Como posso medir a semelhança entre duas imagens? [fechado]

gostaria de comparar uma imagem de uma aplicação (pode ser uma página Web) com uma imagem previamente tirada para determinar se a aplicação está a mostrar-se correctamente. Eu não quero uma comparação exata, porque o aspecto poderia ser ligeiramente diferente (no caso de um aplicativo Web, dependendo do navegador, algum elemento poderia estar em um local ligeiramente diferente). Ele deve dar uma medida de quão semelhantes são as screenshots.

Existe uma biblioteca / ferramenta que já faz isso? Como o implementaria?

Author: Luke Quinane, 2008-08-25

17 answers

Isto depende inteiramente do quão inteligente queres que o algoritmo seja.

Por exemplo, aqui estão algumas questões:
  • imagens recortadas vs. uma imagem não recortada
  • imagens com um texto adicionado vs. outro sem
  • imagens espelhadas

O algoritmo mais fácil e simples que eu vi para isto é apenas fazer os seguintes passos para cada imagem:

  1. escala para algo pequeno, como 64x64 ou 32x32, desconsiderar as proporções, usar uma combinação algoritmo de escala em vez do pixel mais próximo
  2. escala os intervalos de cores para que o mais escuro seja preto e o mais claro seja branco
  3. rodar e inverter a imagem de modo a que a cor mais clara seja a superior esquerda, e depois a superior-direita seja a mais escura, a inferior-esquerda seja a mais escura (tanto quanto possível, claro)

Edit a combinação de algoritmo de escala é aquele que, ao reduzir 10 pixels para um, irá fazê-lo usando uma função que retira a cor de todos aqueles 10 pixels e combina - os num só. Pode ser feito com algoritmos como média, valor médio, ou mais complexos como linhas bicúbicas.

Calcule então a distância média pixel-por-pixel entre as duas imagens.

Para procurar uma possível correspondência numa base de dados, guarde as cores dos pixels como colunas individuais na base de dados, indexe um monte delas (mas não todas, a menos que use uma imagem muito pequena), e faça uma pesquisa que use um intervalo para cada valor de pixels, ou seja. cada imagem onde o pixel no pequeno a imagem está entre -5 e + 5 da imagem que você quer olhar para cima.

Isto é fácil de implementar, e bastante rápido de correr, mas é claro que não vai lidar com as diferenças mais avançadas. Para isso você precisa de algoritmos muito mais avançados.

 61
Author: Lasse Vågsæther Karlsen, 2008-10-15 14:58:00

A forma 'clássica' de medir isto é quebrar a imagem em algum Número canónico de secções (digamos uma grelha 10x10) e depois calcular um histograma de valores RGB dentro de cada célula e comparar os histogramas correspondentes. Este tipo de algoritmo é preferido por causa de sua simplicidade e invariância a escala e (pequeno!) traducao.

 28
Author: Louis Brandy, 2008-08-25 19:18:41

Utilizar um histograma de cores normalizado. (Leia a seção sobre aplicações aqui ), elas são comumente usadas em sistemas de recuperação/correspondência de imagens e são uma forma padrão de combinar imagens que é muito confiável, relativamente rápido e muito fácil de implementar.

Essencialmente, um histograma a cores irá captar a distribuição de cores da imagem. Isto pode então ser comparado com outra imagem para ver se as distribuições de cores coincidem. Este tipo de correspondência é bastante resiliente. para escalar (uma vez que o histograma é normalizado), e rotação/deslocamento/movimento, etc.

Evite comparações pixel-a-pixel como se a imagem fosse rodada/deslocada ligeiramente, pode levar a uma grande diferença a ser relatada.

Os histogramas seriam simples para se gerar a si próprio (assumindo que consegue aceder aos valores dos pixels), mas se não lhe apetecer, a biblioteca OpenCV é um grande recurso para fazer este tipo de coisas. Aqui está uma apresentação em powerpoint que mostra-lhe como criar um histograma com o OpenCV.

 22
Author: Lehane, 2008-08-27 16:53:00

Dava-te jeito uma abordagem matemática pura de {[[0]}, mas só será útil se tiveres a certeza de que não há compensação ou algo do género. (Embora se você tiver alguns objetos com coloração homogênea ele ainda vai funcionar muito bem.)

De qualquer forma, a ideia é calcular o produto-Ponto normalizado das duas matrizes. C = sum(Pij*Qij)^2/(sum(Pij^2)*sum(Qij^2)).

Esta fórmula é na verdade o" cosseno " do ângulo entre as matrizes (wierd). Quanto maior for a semelhança (digamos Pij=Qij), C será 1, e se forem completamente diferentes, digamos que para cada i,j Qij = 1 (evitando divisão zero), Pij = 255, então para o tamanho nxn, Quanto maior n for, mais perto de zero chegaremos. (Por cálculo aproximado: C=1/n^2).

 13
Author: Shachar, 2012-11-16 11:02:16

Os algoritmos de codificação de vídeo como o MPEG não calculam a diferença entre cada imagem de um vídeo para que possam codificar o delta? Você pode ver como os algoritmos de codificação de vídeo computam essas diferenças de quadros.

Veja Esta aplicação de pesquisa de imagens de código aberto http://www.semanticmetadata.net/lire / . descreve vários algoritmos de semelhança de imagens, três dos quais são da norma MPEG-7: ScalableColor, ColorLayout, EdgeHistogram e Auto Color Correlograma.

 12
Author: Mark B, 2008-09-16 20:29:32

Vais precisar de reconhecimento de padrões para isso. Para determinar pequenas diferenças entre duas imagens, As Redes de Hopfield funcionam bastante bem e são muito fáceis de implementar. Mas não conheço nenhuma implementação disponível.

 8
Author: Konrad Rudolph, 2008-08-25 13:00:13
Uma solução de ruby pode ser encontrada aqui

Do readme:

O Phashion é um invólucro de rubi em torno da biblioteca de pHash, o "hash perceptual", que detecta duplicados e quase duplicados ficheiros multimédia

 5
Author: edk750, 2012-10-10 13:06:17

Como medir a semelhança entre duas imagens depende inteiramente do que você gostaria de medir, por exemplo: contraste, brilho, modalidade, ruído... e então escolha a melhor medida de semelhança adequada que existe para você. Você pode escolher entre MAD (diferença média absoluta), MSD (diferença média ao quadrado) que são bons para medir o brilho...existe também uma CR ([2]}disponível (coeficiente de coreação) que é boa em representar a coreação entre dois imagem. Pode também escolher entre medidas de semelhança baseadas em histogramas como SDH (desvio padrão do histograma da diferença de imagem) ou medidas de semelhança multimodality como MI (informação mútua) ou NMI (informação mútua normalizada).

Como estas medidas de semelhança custam muito tempo, é aconselhável reduzir as imagens antes de aplicar estas medidas sobre elas.

 4
Author: Gregor Simončič, 2016-01-31 10:41:24

Eu me pergunto (E eu estou realmente jogando a idéia para fora para ser derrubado) se algo poderia ser derivado subtraindo uma imagem da outra, e então comprimindo a imagem resultante como um jpeg de gif, e tomando o tamanho do arquivo como uma medida de similaridade.

Se tivesse duas imagens idênticas, teria uma caixa branca, que comprimiria muito bem. Quanto mais as imagens diferiam, mais complexo seria representar e, portanto, menos compressível.

Provavelmente não é um teste ideal, e provavelmente muito mais lento do que o necessário, mas pode funcionar como uma implementação rápida e suja.

 3
Author: Matt Sheppard, 2008-08-25 13:10:28

Você pode olhar para o código para a ferramenta de código aberto findimagedupes , embora pareça ter sido escrito em perl, por isso não posso dizer como será fácil processar...

Ao ler a página findimagedupes de que gostei, vejo que existe uma implementação em C++ do mesmo algoritmo. Presumivelmente isto será mais fácil de entender.

E parece que também pode utilizar gqview .

 3
Author: dmckee, 2017-05-06 00:52:55
Bem, não quero responder directamente à tua pergunta, mas já vi isto acontecer. A Microsoft lançou recentemente uma ferramenta chamada PhotoSynth que faz algo muito semelhante para determinar áreas sobrepostas em um grande número de imagens (que podem ser de diferentes proporções). Pergunto-me se eles têm alguma biblioteca disponível ou excertos de código no seu blog.
 2
Author: Vaibhav, 2008-08-25 12:57:21

Para expandir a nota de Vaibhav, hugin é um 'autostitcher' de código aberto que deve ter alguma visão sobre o problema.

 2
Author: hometoast, 2008-08-25 13:16:33

Há software para recuperação de imagem baseada em conteúdo, que faz (parcialmente) o que você precisa. Todas as referências e explicações estão ligadas a partir do site do projeto e há também um pequeno livro de texto (Kindle): LIRE

 2
Author: Mathias, 2013-04-19 14:51:44

Bem, um método de nível realmente básico a usar pode passar por cada cor de pixel e compará - lo com a cor de pixel correspondente na segunda imagem-mas isso é provavelmente uma solução muito muito lenta.

 0
Author: Ross, 2008-08-25 13:19:39

Se isto for algo que você vai fazer ocasionalmente e não precisa de automatizar, você pode fazê-lo num editor de imagens que suporta camadas, como o Photoshop ou o Paint Shop Pro (provavelmente o GIMP ou Paint.Net too, but i'm not sure about those). Abra ambas as imagens da tela, e coloque uma Como UMA camada em cima da outra. Mude o modo de mistura de camadas para a diferença, e tudo o que é o mesmo entre os dois vai se tornar preto. Você pode mover a camada superior ao redor para minimizar qualquer diferenças de alinhamento.

 0
Author: Mark Ransom, 2008-10-15 15:15:47

Pode usar a rede Siamesa para ver se as duas imagens são semelhantes ou diferentes a seguir a este tutorial . Este tutorial agrupa as imagens semelhantes, enquanto que você pode usar a distância L2 para medir a semelhança de duas imagens.

 0
Author: cpwah, 2017-02-27 08:53:25

Além de Comparar tem comparação pixel-por-pixel para imagens, por exemplo,

enter image description here

 0
Author: emallove, 2017-04-26 19:57:11