Pergunta

Estou procurando criar um sistema de identificação para catalogar imagens.Não posso usar md5() pois isso mudará se eu alterar as tags EXIF ​​da imagem.

Atualmente estou usando a soma de verificação SHA1 calculada pelo imagemagick.Funciona perfeitamente, mas é muito, muito lento em imagens maiores (cerca de 15 segundos em um xeon quad-core para um JPG de 21 megapixels).

Existem outros métodos "visuais" para identificar exclusivamente uma imagem que seriam mais rápidos?

Foi útil?

Solução

Você pode tentar executar o MD5 nos dados bitmap reais em vez do arquivo JPEG.Testei na minha máquina (também um Xeon quad core) e o seguinte roda em cerca de 900ms em uma imagem de 23 megapixels.

uint32_t width  = MagickGetImageWidth(imageWand);
uint32_t height = MagickGetImageHeight(imageWand);

uint8_t *imageData = malloc(width * height * 3);

MagickExportImagePixels(imageWand,
   0, 0, width, height, "RGB", CharPixel, imageData);

unsigned char *imageDigest = MD5(imageData, width * height * 3, NULL);

free(imageData);

Outras dicas

o que você quer dizer com "soma de verificação visual"?os algoritmos que você menciona (md5/sha/crc) funcionam com base em bytes, mas não levam em consideração as informações visuais da imagem.Se você converter uma de suas imagens para JPEG, os dois arquivos mostrarão a mesma imagem, mas terão somas de verificação md5/sha/crc totalmente diferentes.

se sua única preocupação são as edições exif, você pode fazer uma cópia temporária da imagem, retirar todos os metadados dela com a biblioteca exiv2 e executar o algoritmo de soma de verificação.Suponho que isso seja muito mais rápido do que reduzir manualmente as imagens.Você também pode acelerar o cálculo usando apenas os primeiros n kilobytes do arquivo de origem para a soma de verificação.

Se todos os seus arquivos de imagem vierem diretamente de uma câmera, será ainda melhor:você pode extrair a miniatura exif pré-gerada com exiv2 (geralmente apenas alguns kilobytes) e calcular sua soma de verificação.

Sobre a abordagem de redução de escala:Esteja ciente também do fato de que o ImageMagick pode alterar seus algoritmos de escala no futuro, o que invalidaria suas somas de verificação (a estrutura de bytes das versões reduzidas mudaria então).

Conforme observado por Todd Yandell, o MD5 provavelmente é rápido o suficiente.Caso contrário, você pode obter algo ainda mais rápido usando uma versão de 32 ou 64 bits. CDC para sua soma de verificação.A grande diferença é que qualquer pessoa pode criar uma nova imagem com o mesmo CRC;é muito fácil falsificar.É muito difícil alguém falsificar uma soma de verificação MD5.Uma pequena diferença é que o CRC tem muito menos bits, mas, a menos que você tenha um número muito grande de imagens, uma colisão ainda é improvável.

exiftool afirma ser capaz de extrair a imagem binária de um arquivo JPEG, para que você possa calcular sua soma de verificação sem descompactar, mas não consigo descobrir na página de manual como fazer isso.

Fiz alguns experimentos em um laptop com CPU Intel Core 2 Duo L7100, e um JPEG de 8MP leva cerca de 1 segundo para compactar no formato PPM e mais 1 segundo para fazer a soma de verificação.Os tempos de checksum não foram dramaticamente diferentes usando md5sum, sum, e sha1sum.Portanto, sua melhor aposta seria encontrar uma maneira de extrair os dados binários sem descompactá-los.

Observo também que sua soma de verificação será quase tão boa, mesmo que use muito menos pixels.Compare estes dois:

djpeg -scale 1/8 big.jpg | /usr/bin/sha1sum   # 0.70s
djpeg            big.jpg | /usr/bin/sha1sum   # 2.15s

Você deve considerar que alguém pode cortar a imagem ou modificar a paleta, a profundidade da cor ou qualquer coisa, então uma soma de verificação plana será diferente, mesmo que visualmente a imagem original e a imagem modificada ainda sejam muito parecidas.Talvez exista um algoritmo eficaz para imagens recortadas ou recoloridas, como o Imagens do Google usa para pesquisar imagens semelhantes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top