2010-01-27 12 views
35

Qui ci sono alcuni argomenti che sono molto utili su come trovare immagini simili.OpenCV/SURF Come generare un hash di immagine/impronta digitale/firma fuori dai descrittori?

Quello che voglio fare è ottenere un'impronta digitale di una foto e trovare la stessa immagine su diverse foto scattate da una fotocamera digitale. L'algoritmo SURF sembra essere il modo migliore per essere indipendente su ridimensionamento, angolo e altre distorsioni.

Sto usando OpenCV con l'algoritmo SURF per estrarre le funzionalità sull'immagine campione. Ora mi chiedo come convertire tutti i dati di questa feature (posizione, laplacian, dimensione, orientamento, hessian) in un'impronta digitale o hash.

Questa impronta digitale verrà memorizzata in un database e una query di ricerca deve essere in grado di confrontare quell'impronta digitale con un'impronta digitale di una foto con quasi le stesse caratteristiche.

Aggiornamento:

Sembra che non v'è alcun modo per convertire tutti i vettori descrittore in un semplice hash. Quindi quale sarebbe il modo migliore per archiviare i descrittori di immagini nel database per l'interrogazione veloce?

Gli alberi del vocabolario sarebbero un'opzione?

Sarei molto grato per qualsiasi aiuto.

+0

Il codice esegue quello che viene chiamato matching "più vicino prossimo" - prendendo il descrittore (un vettore di dimensione N) e confrontandolo con un insieme di altri vettori di dimensione N (questo può essere calcolando la distanza euclidea tra loro o qualsiasi altra misura di distanza) e selezionando quello che è più vicino. L'ingenuo nel nome significa che il vettore viene confrontato con TUTTI gli altri vettori. Esistono altri algoritmi che utilizzano il prossimo più prossimo approssimativo, che sono meno precisi ma più efficienti. – elijah

+1

Per rendere le cose brevi - non è possibile fare una funzione hash dalle immagini (che è troppo mal posta e presuntuosa). È possibile consultare la documentazione per la classificazione dei vicini più vicini o le misure di somiglianza delle immagini. – elijah

+0

Ok, quale sarebbe il modo migliore per memorizzare qualsiasi query dei descrittori di immagini di? – dan

risposta

9

I dati di feature che si menzionano (posizione, laplacian, dimensione, orientamento, hessian) non sono sufficienti per il proprio scopo (queste sono in realtà le parti meno rilevanti del descrittore se si desidera eseguire la corrispondenza). I dati che si desidera guardare sono i "descrittori" (il 4 ° argomento):

void cvExtractSURF(const CvArr* image, const CvArr* mask, CvSeq** keypoints, CvSeq** descriptors, CvMemStorage* storage, CvSURFParams params)

Questi sono 128 o 64 (a seconda del params) vettori che contengono le "impronte digitali" della funzione specifica (ogni l'immagine conterrà una quantità variabile di tali vettori). Se si ottiene l'ultima versione di Opencv hanno un campione di nome find_obj.cpp che mostra come viene utilizzato per la corrispondenza

aggiornamento:

si potrebbe trovare this discussione utile

+0

Ciao Liza, grazie per la tua risposta. Ho esaminato l'esempio ma non trovo alcun modo per trasformare i vettori dei descrittori memorizzati in CvSeq in un valore hash che rende possibile l'archiviazione in un database e il confronto con altri hash. Hai qualche suggerimento su questo? – dan

+0

CvSeq memorizza semplicemente gli array float (guarda il codice sorgente di cvExtractSURF per vedere come lo memorizzano). quegli array (128 o 64 di lunghezza) sono ciò che ti interessa in – elijah

+0

a proposito, se quello che vuoi è ottenere qualche hash magico che mapperebbe tutte le immagini dei cani per esempio con lo stesso codice hash, temo che sia più complicato rispetto all'estrazione delle funzioni SURF. Dai un'occhiata al link che ho inserito nell'aggiornamento – elijah

3

Un banale modo per calcolare un hash sarebbe il seguente. Ottieni tutti i descrittori dall'immagine (diciamo, N di loro). Ogni descrittore è un vettore di 128 numeri (è possibile convertirli in numeri interi tra 0 e 255). Quindi hai un set di interi N * 128. Basta scriverli uno dopo l'altro in una stringa e usarli come valore hash. Se si desidera che i valori hash siano piccoli, credo che esistano modi per calcolare le funzioni hash delle stringhe, quindi convertire i descrittori in stringa e quindi utilizzare il valore hash di tale stringa.

Potrebbe funzionare se si desidera trovare duplicati esatti. Ma sembra (dal momento che parli di scala, rotazione, ecc.), Vuoi solo trovare immagini "simili". In tal caso, usare un hash non è probabilmente un buon modo per andare. Probabilmente utilizzi un rilevatore di punti di interesse per trovare punti in cui calcolare i descrittori SURF. Immagina di restituire lo stesso insieme di punti, ma in ordine diverso. All'improvviso il tuo valore di hash sarà molto diverso, anche se le immagini e i descrittori sono gli stessi.

Quindi, se dovessi trovare immagini simili in modo affidabile, userei un approccio diverso.Ad esempio, potrei quantizzare vettoriale i descrittori SURF, creare istogrammi di valori quantizzati da vettori e utilizzare l'intersezione dell'istogramma per la corrispondenza. Devi assolutamente usare le funzioni hash (forse per l'efficienza) o vuoi semplicemente usare qualsiasi cosa per trovare immagini simili?

+0

Hi Sheldon, grazie per la risposta. Prima di guardare SURF, stavo lavorando con la lib di pHash. Quella lib genera un valore hash per i dati multimediali (immagini, video e audio). Di quanto potresti usare la distanza di Hamming per interrogare il tuo database di hash di immagini simili abbastanza facilmente. Ho pensato che ci deve essere un modo per fare lo stesso con i descrittori SURF in qualche modo. Ora sto pensando di archiviare tutti gli oggetti array di descrittori di immagini serializzati nel database. Quando voglio trovare un'immagine simile nel database devo selezionare riga per riga e trovare i descrittori simili a mano. (...) – dan

+2

(continua) Il grande svantaggio sarebbe una pessima prestazione per un grande database di immagini. Mi chiedo come TinEye.com possa trovare immagini simili così velocemente. Deve esserci qualche trucco per interrogare il loro database molto velocemente. – dan

+1

Penso che sarebbe di grande aiuto se tu dicessi esattamente cosa stai cercando di ottenere. Data un'immagine, cosa stai cercando di trovare? Immagini identiche, immagini simili, immagini simili fino al ridimensionamento rotazione/traslazione? Data un'immagine X, vuoi trovare solo le immagini che sono simili a X, o vuoi anche le immagini che contengono X come sotto-parte? Ad esempio, la query è un'immagine del volto. Vuoi trovare altre immagini del viso, o anche fotografie di tutto il corpo che contengono la faccia ma anche molte altre cose? Perché hai smesso di usare pHash e hai deciso di lavorare con i descrittori SURF? – user245973

2

Min-Hash o min-Hashing è una tecnica che potrebbe essere di aiuto. Codifica l'intera immagine in una rappresentazione con dimensione regolabile che viene quindi memorizzata in tabelle hash. Diverse varianti come Geometrica Minima-Hashing, Partition min-Hash e Bundle min-Hashing esistono. L'impronta di memoria risultante non è una delle più piccole, ma queste tecniche funzionano per una varietà di scenari come il recupero quasi duplicato e anche il recupero di oggetti di piccole dimensioni - uno scenario in cui le altre firme brevi spesso non si comportano molto bene.

Ci sono diversi articoli su questo argomento. letteratura Entry sarebbe: duplicato vicino Rilevamento immagine: min-Hash e ponderazione TF-IDF Ondrej Chum, James Philbin, Andrew Zisserman, BMVC 2008PDF