Ho bisogno di un algoritmo di hashing dell'immagine (preferibilmente semplice e veloce). Il valore di hash viene utilizzato in una tabella di ricerca, non per la crittografia.Algoritmo di hashing dell'immagine semplice e veloce
Alcune delle immagini sono "computer graphic" - cioè ripieni a colori pieni, testi rasterizzati e così via, mentre ci sono anche immagini "fotografiche" - contenenti uno spettro di colori ricco, per lo più regolare, con un'ampiezza di rumore ragionevole.
Mi piacerebbe anche che l'algoritmo di hash potesse essere applicato a specifiche parti dell'immagine. Voglio dire, l'immagine può essere divisa in celle di griglia e la funzione di hash di ogni cella dovrebbe dipendere solo dal contenuto di questa cella. In modo che si possa individuare rapidamente se due immagini hanno aree comuni (nel caso siano allineate in modo appropriato).
Nota: Ho solo bisogno di sapere se due immagini (o loro parti) sono identici . Cioè, non ho bisogno di abbinare immagini simili, non c'è bisogno di riconoscimento delle funzioni, correlazione e altre tecniche DSP.
Mi chiedo quale sia l'algoritmo di hashing preferito.
Per le immagini "fotografiche", solo XOR-in tutti i pixel all'interno di una cella della griglia è ok più o meno. La probabilità dello stesso valore di hash per immagini diverse è piuttosto bassa, soprattutto perché la presenza del rumore (quasi bianco) rompe tutte le simmetrie potenziali. Inoltre, lo spettro di tale funzione di hash sembra buono (qualsiasi valore è possibile con quasi la stessa probabilità).
Ma un algoritmo così ingenuo non può essere utilizzato con la grafica "artificiale". Pixel identici, pattern ripetuti, invarianza di offset geometrica sono molto comuni per tali immagini. XOR-tutti i pixel daranno 0 per ogni immagine con un numero pari di pixel identici.
L'utilizzo di qualcosa come CRT-32 sembra un po 'promettente, ma mi piacerebbe immaginare qualcosa di più veloce. Ho pensato di formula iterativa, ogni nuovo pixel muta il valore hash corrente, in questo modo:
hashValue = (hashValue * /*something*/ | newPixelValue) % /* huge prime */
Facendo numero primo modulo dovrebbe probabilmente dare una buona dispersione, in modo che io sto sporgendosi verso questa opzione. Ma mi piacerebbe sapere se ci sono varianti migliori.
Grazie in anticipo.
perché non usi un semplice algoritmo di hashing come md5? –
@Karoly Horvath: buona domanda. In effetti, questo è ciò di cui ho bisogno più o meno. Comunque MD5 è (presumibilmente) affamato di CPU, è progettato per essere una funzione hash unidirezionale. OTOH Ho bisogno di qualcosa di molto più semplice, dal momento che non ho considerazioni sulla sicurezza. Ho pensato a CRC-32. Ma mi piacerebbe capire qualcosa di ancora più semplice – valdo
Se lo fai su molte immagini, il collo di bottiglia sarà la tua velocità del disco .. –