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

94

Gostaria de comparar uma captura de tela de um aplicativo (pode ser uma página da Web) com uma captura de tela feita anteriormente para determinar se o aplicativo está sendo exibido corretamente. Não quero uma comparação de correspondência exata, porque o aspecto pode ser ligeiramente diferente (no caso de um aplicativo da Web, dependendo do navegador, algum elemento pode estar em um local ligeiramente diferente). Deve dar uma medida de quão semelhantes são as capturas de tela.

Existe alguma biblioteca / ferramenta que já faz isso? Como você o implementaria?

Antoine Aubry
fonte
1
Existem algumas boas respostas para essa outra pergunta semelhante: stackoverflow.com/questions/75891/…
blak
1
É hora de atualizar as respostas à luz dos avanços recentes no aprendizado de máquina e, mais especificamente, no "aprendizado profundo".
jldupont
Meu laboratório também precisava resolver esse problema e usou o fluxo de trabalho descrito aqui: douglasduhaime.com/posts/…
duhaime

Respostas:

73

Isso depende inteiramente de quão inteligente você deseja que o algoritmo seja.

Por exemplo, aqui estão alguns problemas:

  • imagens cortadas x uma imagem não cortada
  • imagens com um texto adicionado vs. outro sem
  • imagens espelhadas

O algoritmo mais fácil e simples que vi para isso é apenas executar as seguintes etapas para cada imagem:

  1. dimensione para algo pequeno, como 64x64 ou 32x32, desconsidere a proporção, use um algoritmo de escala de combinação em vez do pixel mais próximo
  2. dimensione os intervalos de cores de modo que o mais escuro seja o preto e o mais claro o branco
  3. gire e vire a imagem de modo que a cor mais clara fique no canto superior esquerdo e, em seguida, o canto superior direito é o próximo mais escuro, o canto inferior esquerdo é o próximo mais escuro (o mais longe possível, é claro)

Editar Um algoritmo de escalonamento de combinação é aquele que, ao dimensionar 10 pixels para um, o fará usando uma função que pega a cor de todos esses 10 pixels e os combina em um. Pode ser feito com algoritmos como média, valor médio ou mais complexos como splines bicúbicos.

Em seguida, calcule a distância média pixel a pixel entre as duas imagens.

Para pesquisar uma possível correspondência em um banco de dados, armazene as cores de pixel como colunas individuais no banco de dados, indexe um monte deles (mas não todos, a menos que você use uma imagem muito pequena) e faça uma consulta que use um intervalo para cada valor de pixel, ou seja, todas as imagens em que o pixel na imagem pequena está entre -5 e +5 da imagem que você deseja visualizar.

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

Lasse V. Karlsen
fonte
14
O que é um "algoritmo de escalonamento combinado"?
Gregg Lind,
32

A maneira 'clássica' de medir isso é dividir a imagem em um número canônico de seções (digamos, uma grade de 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 sua invariância para escalonamento e (pequena!) Tradução.

Louis Brandy
fonte
6
Isso não é semelhante a fazer um único histograma para a imagem inteira, mas com as desvantagens adicionais de não ser resiliente para espelhar e girar?
dodgy_coder
2 histogramas de 2 metades da imagem terão melhor precisão de correspondência do que 1 histograma de um todo. Embora tenha desvantagens que você mencionou, depende do problema que você está resolvendo.
psycho brm
25

Use um histograma de cores normalizado. (Leia a seção sobre aplicativos aqui ), eles são comumente usados ​​em sistemas de recuperação / correspondência de imagens e são uma forma padrão de correspondência de imagens que é muito confiável, relativamente rápida e muito fácil de implementar.

Basicamente, um histograma de cores capturará a distribuição de cores da imagem. Isso pode então ser comparado com outra imagem para ver se as distribuições de cores correspondem.

Este tipo de correspondência é bastante resistente ao dimensionamento (uma vez que o histograma é normalizado) e rotação / deslocamento / movimento etc.

Evite comparações pixel a pixel, pois se a imagem for girada / deslocada levemente, isso pode levar ao relatório de uma grande diferença.

Seria fácil gerar histogramas (presumindo que você possa obter acesso aos valores de pixel), mas se você não quiser, a biblioteca OpenCV é um ótimo recurso para fazer esse tipo de coisa. Aqui está uma apresentação em PowerPoint que mostra como criar um histograma usando o OpenCV.

Lehane
fonte
14

Algoritmos de codificação de vídeo como o MPEG não calculam a diferença entre cada quadro de um vídeo para que eles possam codificar apenas o delta? Você pode examinar como os algoritmos de codificação de vídeo calculam essas diferenças de quadro.

Veja este aplicativo de pesquisa de imagens de código aberto http://www.semanticmetadata.net/lire/ . Ele descreve vários algoritmos de similaridade de imagem, três dos quais são do padrão MPEG-7: ScalableColor, ColorLayout, EdgeHistogram e Auto Color Correlogram.

Mark B
fonte
1
Isso não responderia à pergunta aqui. A questão não é sobre a comparação pixel por pixel.
Kousha
@Kousha True, mas ainda uma direção interessante para pensar.
significado importa
13

Você poderia usar uma abordagem matemática pura de O(n^2), mas será útil apenas se você tiver certeza de que não há deslocamento ou algo parecido. (Embora se você tiver alguns objetos com cores homogêneas, ainda funcionará muito bem.)

De qualquer forma, a ideia é calcular o produto escalar 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 (estranho). Quanto maior a similaridade (digamos Pij=Qij), C será 1, e se eles forem completamente diferentes, digamos para cada i,j Qij = 1(evitando a divisão zero) Pij = 255, então para tamanho nxn, quanto maior nserá, mais próximo de zero nós obter. (Por cálculo aproximado:) C=1/n^2.

Shachar
fonte
8

Você precisará de reconhecimento de padrões para isso. Para determinar pequenas diferenças entre duas imagens, as redes Hopfield funcionam muito bem e são fáceis de implementar. Não conheço nenhuma implementação disponível, no entanto.

Konrad Rudolph
fonte
7

Uma solução de rubi pode ser encontrada aqui

Do leia-me:

Phashion é um wrapper Ruby em torno da biblioteca pHash, "perceptual hash", que detecta arquivos multimídia duplicados e quase duplicados

edk750
fonte
5

Como medir a similaridade entre duas imagens depende inteiramente do que você gostaria de medir, por exemplo: contraste, brilho, modalidade, ruído ... e então escolher a melhor medida de similaridade adequada para você. Você pode escolher entre MAD (diferença média absoluta), MSD (diferença quadrada média), que são bons para medir o brilho ... há também CR (coeficiente de correlação) disponível, que é bom para representar a correlação entre duas imagens. Você também pode escolher entre medidas de similaridade baseadas em histograma como SDH (desvio padrão do histograma de imagem de diferença) ou medidas de similaridade multimodal como MI (informação mútua) ou NMI (informação mútua normalizada).

Como essas medidas de similaridade custam muito tempo, é aconselhável reduzir as imagens antes de aplicar essas medidas nelas.

Gregor Simončič
fonte
4

Eu me pergunto (e estou apenas lançando a ideia para ser derrubado) se algo poderia ser derivado subtraindo uma imagem da outra e, em seguida, compactando a imagem resultante como um jpeg de gif e tomando o tamanho do arquivo como uma medida de semelhança.

Se você tivesse duas imagens idênticas, obteria uma caixa branca, que compactaria muito bem. Quanto mais as imagens diferiam, mais complexo seria a representação e, portanto, menos compactá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.

Matt Sheppard
fonte
Pense em girar 90 graus; as imagens ainda são semelhantes.
assuntos de significado
3

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

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

E parece que você também pode usar o gqview .

dmckee --- gatinho ex-moderador
fonte
2

Bem, não para responder sua pergunta diretamente, mas eu vi isso 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 ter proporções diferentes).

Eu me pergunto se eles têm alguma biblioteca ou trecho de código disponível em seu blog.

Vaibhav
fonte
1
Esta tecnologia. foi descontinuado.
Joseph Rosson,
2

para expandir a nota de Vaibhav, o hugin é um 'autostitcher' de código aberto que deve ter algumas dicas sobre o problema.

hometoast
fonte
2

Existe um 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 vinculadas ao site do projeto e também há um pequeno livro de texto (Kindle): LIRE

Mathias
fonte
1

Você pode usar a rede siamesa para ver se as duas imagens são semelhantes ou diferentes seguindo este tutorial . Este tutorial agrupa as imagens semelhantes, enquanto você pode usar a L2distância para medir a semelhança de duas imagens.

cpwah
fonte
0

Se isso é algo que você fará ocasionalmente e não precisa ser automatizado, você pode fazer isso em um editor de imagens que suporte camadas, como Photoshop ou Paint Shop Pro (provavelmente GIMP ou Paint.Net também, mas eu ' não tenho certeza sobre aqueles). Abra as duas capturas de tela e coloque uma como uma camada sobre a outra. Mude o modo de mesclagem da camada para Diferença, e tudo o que for igual entre os dois ficará preto. Você pode mover a camada superior para minimizar quaisquer diferenças de alinhamento.

Mark Ransom
fonte
Outra ferramenta que torna este tipo de comparação muito simples é o kaleidoscopeapp.com
Michael Osofsky
0

Beyond Compare tem comparação pixel a pixel para imagens, por exemplo,

insira a descrição da imagem aqui

emallove
fonte
@xilpex, o OP pergunta: Existe alguma biblioteca / ferramenta que já faz isso ? Minha resposta inclui um link para essa biblioteca / ferramenta.
emallove
-1

Bem, um método realmente básico para usar poderia passar por cada cor de pixel e compará-la com a cor de pixel correspondente na segunda imagem - mas essa provavelmente é uma solução muito lenta.

Ross
fonte