Exemplos do ImageMagick -- Comparação de Imagens
- Exemplos do ImageMagick -- Prefácio e Índice
- Métodos de Comparação de Imagens -- o que é diferente?
- Programa Compare
- Imagens de Diferença
- Comparação por Cintilação
-
Estatísticas de Comparação -- quão diferentes? Correspondência e Localização de Sub-Imagens Encontrar imagens menores dentro de maiores. Encontrar Imagens Duplicadas -- encontrar duas imagens que são iguais Ordenar Imagens por Tipo -- classificações de imagem para comparação
- Cor Linear
- Preto e Branco Puros
- Imagens Coloridas
- Coloração de Tons Médios
- Texto vs Desenho de Linhas
-
Tratamento de Tipos Específicos de Imagem Métricas de Imagem -- impressão digital de imagens para comparação Web Cameras -- O que mudou em câmeras fixas A capacidade de comparar duas ou mais imagens, ou de encontrar imagens duplicadas em uma coleção grande, é uma questão bastante delicada. Nestes exemplos, examinamos a comparação de imagens para determinar quão semelhantes elas são e onde diferem. Isso pode envolver classificar ou agrupar imagens em vários tipos para um tratamento melhor. Descobrir alguma métrica para simplificar e agrupar imagens semelhantes. E agrupar imagens semelhantes com base nessas métricas. No entanto, tais comparações e estudos, embora difíceis, podem ser recompensadores, pela capacidade de encontrar duplicatas e cópias de imagens, e até de remover 'spam' ou outros textos ou avisos das imagens.
Métodos de Comparação de Imagens
Programa Compare
O programa "magick compare" é fornecido para dar uma forma simples de comparar duas imagens semelhantes e determinar o quanto elas são 'diferentes'. Por exemplo, aqui temos dois quadros de um 'saco' animado, que então passamos ao "magick compare" para destacar as áreas que mudaram.
magick compare bag_frame1.gif bag_frame2.gif compare.gif
Como se pode ver, obtém-se uma imagem em branco e vermelho, que contém uma 'sombra' da segunda imagem. Ela mostra claramente três áreas que mudaram entre as duas imagens. Em vez de salvar a imagem 'compare', pode-se, é claro, visualizá-la diretamente, o que é mais conveniente, gerando a saída no formato especial "[x:](files.html#x)", ou usando o programa "[display](basics.html#display)". Por exemplo..
magick compare bag_frame1.gif bag_frame2.gif x:
magick compare bag_frame1.gif bag_frame2.gif miff:- | display
A partir do IM v6.4, é possível mudar a cor das diferenças de vermelho para alguma outra cor mais interessante... |
magick compare bag_frame1.gif bag_frame2.gif \
-highlight-color SeaGreen compare_color.gif
![[IM Output]](../static/img/compare/compare_color.gif)
A partir do IM v6.4.2-8, também é possível especificar a outra cor. |
magick compare bag_frame1.gif bag_frame2.gif \
-highlight-color SeaGreen -lowlight-color PaleGreen \
compare_colors.gif
![[IM Output]](../static/img/compare/compare_colors.gif)
Se você não quiser aquela 'sombra' da segunda imagem, a partir do IM v6.4.2-8 pode adicionar um "-compose src" às opções para removê-la. |
magick compare bag_frame1.gif bag_frame2.gif \
-compose Src compare_src.gif
![[IM Output]](../static/img/compare/compare_src.gif)
Usando as três configurações extras, é possível gerar uma máscara em tons de cinza dos pixels que mudaram... |
magick compare bag_frame1.gif bag_frame2.gif \
-compose Src -highlight-color White -lowlight-color Black \
compare_mask.gif
![[IM Output]](../static/img/compare/compare_mask.gif)
Observe, porém, que essa máscara é de QUALQUER diferença, mesmo a menor delas. Por exemplo, é possível ver todas as pequenas diferenças que salvar uma imagem no formato JPEG com perdas produz...
magick bag_frame1.gif bag_frame1.jpg
magick compare bag_frame1.gif bag_frame1.jpg compare_lossy_jpeg.gif
Como se pode ver, embora não se perceba nenhuma diferença real entre as versões GIF e JPEG da imagem, o "magick compare" relata muitas diferenças. Usando um pequeno Fator de Fuzz, você pode pedir ao IM que ignore essas diferenças menores entre as duas imagens. |
magick compare -metric AE -fuzz 5% \
bag_frame1.gif bag_frame1.jpg compare_fuzz.gif
![[IM Output]](../static/img/compare/compare_fuzz.gif)
O que mostra que a maior parte das diferenças reais é apenas menor. A configuração especial "[-metric](https://imagemagick.org/command-line-options/#metric)" de 'AE' (abreviação de "Absolute Error", contagem de erro absoluto) relata (na saída de erro padrão) uma contagem do número real de pixels que foram mascarados, para o fator de fuzz atual.
Imagens de Diferença
Para ter uma ideia melhor de exatamente quão diferentes as imagens são, provavelmente é melhor obter uma imagem de composição '[difference](compose.html#difference)' mais exata.... |
magick composite bag_frame1.gif bag_frame1.jpg \
-compose difference difference_jpeg.gif
![[IM Output]](../static/img/compare/difference_jpeg.gif)
Como se pode ver, embora o "magick compare" mostrasse que o JPEG criou muitas diferenças entre as imagens, uma composição '[difference](compose.html#difference)' ficou bastante escura, indicando que todas as diferenças eram relativamente menores. Se a imagem resultante parecer escura demais para se ver as diferenças, você pode Normalizar a imagem (usando o mais correto matematicamente "[-auto-level](https://imagemagick.org/command-line-options/#auto-level)"), de modo a realçar os resultados. |
magick difference_jpeg.gif -auto-level difference_norm.gif
![[IM Output]](../static/img/compare/difference_norm.gif)
Isto ainda mostra que a maior parte das diferenças continua muito pequena, sendo que a maior diferença ocorre ao longo das bordas nítidas da imagem, que o formato de arquivo JPEG não trata muito bem. Por outro lado, obter uma imagem de diferença entre os dois quadros originais da animação mostra diferenças bem acentuadas entre as duas imagens, mesmo sem qualquer realce. |
magick composite bag_frame1.gif bag_frame2.gif \
-compose difference difference_frames.gif
![[IM Output]](../static/img/compare/difference_frames.gif)
Observe que, como o método de composição '[difference](compose.html#difference)' é associativo, a ordem das duas imagens nos exemplos acima não importa; embora, ao contrário do "magick compare", você possa comparar imagens de tamanhos diferentes, com a imagem de destino determinando o tamanho final da imagem de diferença. O método difference é ainda mais útil quando usado com o programa "magick", pois é possível processar a imagem resultante antes de salvar ou exibir os resultados. Por exemplo, você pode aplicar limiar e mesclar cada um dos canais de cor para gerar uma máscara de qualquer pixel que tenha mudado de cor entre as duas imagens. |
magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
-threhold 0 -separate -evaluate-sequence Add \
difference_mask.gif
![[IM Output]](../static/img/compare/difference_mask.gif)
Isto é basicamente o que o programa "magick compare" faz, mas com mais controles quanto à cor e ao estilo de saída. Contudo, como se pode ver, ele tende a encontrar até a menor mudança entre duas imagens. Se as imagens vêm de um formato de arquivo com perdas, como JPEG, ou de uma imagem GIF que exigiu redução de cores e pontilhamento (quantização de cores), então provavelmente tudo na imagem seria correspondido. Assim, isso normalmente não é muito útil. Para melhores resultados, você pode tentar descobrir o quão diferentes são as cores dos pixels. Por exemplo, podemos converter o resultado para tons de cinza, de modo a obter uma imagem de comparação melhor do que uma colorida. |
magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
-colorspace Gray difference_gray.gif
![[IM Output]](../static/img/compare/difference_gray.gif)
Agora, ao contrário do "magick compare", a imagem de diferença mostra uma mistura de ambas as imagens combinadas no resultado final. Por exemplo, observe o estranho 'talismã' que parece surgir na testa do gato. Originalmente, isso era a alça do saco da primeira imagem. Essa fusão pode tornar confuso saber exatamente quais diferenças você está vendo, e você percebe uma mistura tanto das adições quanto das remoções da imagem. Por causa dessa confusão de detalhes, o "magick compare" costuma ser a melhor forma para nós, humanos, visualizarmos, enquanto a imagem 'difference' é o melhor método para processamento posterior da imagem. No entanto, converter uma imagem de diferença para tons de cinza simplesmente calcula a média (na verdade, uma média ponderada) das distâncias RGB. Como resultado, uma diferença de cor de um único bit pode se perder devido aos Efeitos de Arredondamento de Quantum. Se até a menor diferença entre as imagens for importante, um método melhor é somar os canais de cor separados da imagem de diferença, para garantir que você capture TODAS as diferenças, inclusive a mais ínfima. |
magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
-separate -evaluate-sequence add difference_add.gif
![[IM Output]](../static/img/compare/difference_add.gif)
Os valores de diferença produzidos acima são conhecidos como uma métrica de 'distância de manhattan'. Ou seja, a distância entre as duas cores de cada imagem quando você está restrito a movimento ortogonal (ou axial). Cuidado, porém: diferenças grandes podem acabar recortadas (ou 'queimadas'), pois podem exceder o 'Quantum Range' dos dados de pixel, ou os limites de inteiros, a menos que se use uma versão HDRI do IM. Para ir além, você pode obter a distância vetorial de cor, usando alguns quadrados e raízes quadradas para implementar uma distância pitagórica ou euclidiana. |
magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
-evaluate Pow 2 -separate -evaluate-sequence Add -evaluate Pow 0.5 \
difference_vector.gif
![[IM Output]](../static/img/compare/difference_vector.gif)
Isto é, na verdade, semelhante ao que um fator de 'fuzz' mede como parte de seu limiar (quando não há transparência envolvida). Contudo, o 'fuzz' também divide os valores ao quadrado por 3, antes de somar, para garantir que os resultados não excedam os limites da faixa de cores da imagem. Fazer isso significa que você só obteria um pixel puramente 'branco' no resultado para a diferença entre cores primárias e secundárias opostas, como entre um pixel azul e um amarelo. Então vamos fazer também esse ajuste de escala... |
magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
-evaluate Pow 2 -evaluate divide 3 -separate \
-evaluate-sequence Add -evaluate Pow 0.5 \
difference_vector_scaled.gif
![[IM Output]](../static/img/compare/difference_vector_scaled.gif)
Isto é, na verdade, muito semelhante ao que você obteria para uma imagem de diferença "-colorspace Gray" (como acima), mas é uma representação muito mais precisa da diferença de cor. Você poderia deixar de fora a segunda modificação 'Pow 0.5', caso em que obteria uma imagem de diferença ao quadrado. Existem outras métricas de distância de cor, sobre as quais você pode ler na página Color Difference, Wikipedia. A maioria delas envolve gerar diferenças vetoriais (veja a anterior), mas usando um espaço de cor diferente, como LAB ou LUV. Isto, porém, seria mais importante ao comparar diferenças de cor do mundo real (por exemplo, medidas de diferença da visão humana). Veja também Remoção de Fundo, onde imagens de diferença como as acima são usadas para realizar a remoção de fundo. Você também pode gostar de ver esta página externa sobre Detecção de Mudanças como um exemplo prático de seu uso.
Comparação por Cintilação
Uma alternativa ao programa "magick compare" para ver diferenças entre imagens é fazer uma comparação por cintilação entre as imagens semelhantes a uma taxa razoavelmente rápida. |
magick -delay 50 bag_frame1.gif bag_frame2.gif -loop 0 flicker_cmp.gif
![[IM Output]](../static/img/compare/flicker_cmp.gif)
Para facilitar isso, escrevi um script para exibir uma animação de duas imagens dadas, chamado "**[flicker_cmp](../static/img/scripts/flicker_cmp)**", que alterna entre as duas imagens, tal como no exemplo acima. Ele também adiciona um rótulo na parte inferior da imagem exibida, de modo a detalhar qual imagem você está vendo a cada momento.
Comparação de Animações
Também é possível comparar as diferenças em duas animações unificadas (coalesced) usando uma técnica especial de 'tira de filme'. Veja uma técnica de 'append' semelhante em Anexando Lado a Lado. Basicamente, anexamos todos os quadros da animação para formar uma imagem grande e longa. As duas imagens são então comparadas e uma nova animação é criada dividindo a animação novamente em quadros separados. Por exemplo...
magick \( anim1.gif -coalesce -append \) \
\( anim2.gif -coalesce -append \) miff:- | \
magick compare - miff:- |\
magick - -crop 160x120 +repage anim_compare.gif
O resultado é uma animação das imagens 'compare', produzindo uma versão 'atenuada' da segunda animação, sobreposta a um destaque que mostra as partes que são diferentes. Observe que, para que isso funcione, o tamanho do "[-crop](https://imagemagick.org/command-line-options/#crop)" deve corresponder ao tamanho original da animação. Além disso, a animação perderá quaisquer atrasos de tempo variáveis que possa ter tido, usando um atraso de tempo constante baseado no primeiro quadro da animação original. Outra técnica de comparação de imagens útil para animações é usada para localizar todas as áreas em que uma animação muda, de modo a dividir as partes desconexas da animação. Dessa forma, você pode separar uma animação grande em várias animações menores. Veja Dividindo uma Animação.
Estatísticas de Comparação
Quão diferentes são duas imagens?
Em Construção
Estatísticas a partir da imagem de diferença...
O comando a seguir gera informações detalhadas e extrai apenas a
seção que contém as estatísticas de canal da imagem....
magick image1 image2 -compose Difference -composite \
-colorspace gray -verbose info: |\
sed -n '/statistics:/,/^ [^ ]/ p'
Os números entre parênteses (se presentes) são valores normalizados entre
zero e um, de modo que sejam independentes do nível Q do seu IM.
Se você não tiver esses números, deveria pensar em atualizar seu IM.
Para obter o nível de cinza médio (mean) como porcentagem, você pode usar este
comando...
magick image1 image2 -compose Difference -composite \
-colorspace gray -format '%[fx:mean*100]' info:
Para o valor não percentual, você pode usar o ainda mais simples..
magick image1 image2 -compose Difference -composite \
-colorspace gray -format '%[mean]' info:
Estatísticas do programa Compare...
Você pode obter um valor real de diferença média usando o -metric
magick compare -metric MAE image1 image2 null: 2>&1
Adicionar -verbose fornecerá informações mais específicas sobre cada
canal separadamente.
magick compare -verbose -metric MAE rose.jpg reconstruct.jpg null: 2>&1
Image: rose.jpg
Channel distortion: MAE
red: 1884 (0.028748)
green: 1532.34 (0.023382)
blue: 1691.25 (0.0258068)
all: 1702.53 (0.025979)
Há várias métricas diferentes para escolher.
Com o mesmo conjunto de imagens de teste (quase o mesmo)
Número de pixels
AE ...... Absolute Error, contagem do número de pixels diferentes (0=igual)
Este valor pode ter limiar aplicado com uma configuração -fuzz para
contar apenas os pixels cuja diferença seja maior que o limiar.
A partir do IM v6.4.3, a contagem -metric AE é afetada por -fuzz,
então você pode descartar diferenças 'menores' dessa contagem.
magick -metric AE -fuzz 10% image1.png image2.png null:
Quais pixels são diferentes pode ser visto usando a imagem de
saída (ignorada no comando acima).
Esta é a ÚNICA métrica que é afetada por 'fuzz'.
Erro Máximo (de qualquer pixel isolado)
PAE ..... Peak Absolute Error (dentro de um canal, para espaço de cor 3D)
PSNR .... Peak Signal to noise ratio (usado em artigos de compressão de imagem)
A razão entre a diferença quadrática média e a máxima diferença quadrática
média que pode existir entre duas imagens, expressa como um valor em
decibéis.
Quanto maior o PSNR, mais próximas estão as imagens, com
a diferença máxima ocorrendo em 1. Um PSNR de 20 significa que
as diferenças são 1/100 do máximo.
Erro Médio (sobre todos os pixels)
MAE ..... Mean absolute error (distância média de erro de canal)
MSE ..... Mean squared error (distância média de erro ao quadrado)
RMSE .... erro quadrático médio (raiz) -- OU SEJA: sqrt(MSE)
Métricas especializadas
MEPP .... Erro Médio Normalizado E Erro Máximo Normalizado
Estes deveriam se relacionar diretamente ao fator '-fuzz',
para imagens sem transparência.
Com transparência isso fica difícil: a máscara deveria
afetar o número de pixels comparados, e portanto a 'mean',
mas isso atualmente não é feito.
FUZZ diferença do fator fuzz levando a transparência em conta
NCC correlação cruzada normalizada (1 = semelhante)
Obtive os seguintes resultados nas minhas imagens de teste...
_métrica_|__jpeg Q baixo__|__preto vs branco__
PSNR | 29.6504 | 0
PAE | 63479 | 65535
MAE | 137.478 | 65535
MSE | 4.65489e+06 | 4.29484e+09
RMSE | 2157.52 | 65535
A primeira coluna de números é uma comparação de imagens com diferenças
de JPEG de baixa qualidade, em que a imagem de teste foi lida e salva com uma
configuração -quality muito baixa.
A segunda, "black vs white", é uma comparação de uma imagem preta sólida com
uma imagem branca sólida. Se a 'cor média' da imagem for ignorada
pela comparação, então o valor resultante será muito pequeno. Isto
parece ocorrer apenas com a métrica PSNR, pois todas as outras produziram
um valor de diferença máximo.
O e+06 é notação científica, indicando quantas casas deslocar o
ponto decimal. Ex.: 4.65489e+06 --> 4,654,890.0
Assim, é igual a cerca de 4 milhões, e é o quadrado de 2157.52
AVISO: os números dependem dos níveis de Quality (Q) do IM definidos em
tempo de compilação. Quanto maior a qualidade, maiores os números. Apenas o
PSNR não deveria ser afetado por isso. Por essa razão, o IM também fornece um
resultado 'normalizado' não afetado pela configuração de qualidade de compilação,
embora ainda possa ter pequenos efeitos de 'quantum' ou 'arredondamento de inteiro'.
AINDA NÃO descobri se há alguma das opções "-define" existentes
utilizável na função "compare".
NOTA: para cores opacas, as distâncias AE -fuzz e RMSE são equivalentes.
PORÉM, quando cores transparentes estão envolvidas, o teste do fator fuzz do AE
tratará duas cores totalmente transparentes diferentes como sendo a mesma,
enquanto o RMSE as tratará como sendo diferentes!
Por exemplo...
Para o AE, branco totalmente transparente e preto totalmente transparente são iguais.
magick compare -metric AE xc:#0000 xc:#FFF0 null:
0 (0)
Para o RMSE, elas são a mesma cor, pois são totalmente transparentes.
magick compare -metric RMSE xc:#0000 xc:#FFF0 null:
0 (0)
Dissimilarity-threshold (limiar de dissimilaridade)
Se você receber um erro 'too different' (diferente demais), pode desativá-lo usando...
-dissimilarity-threshold 1.0
Mas o que é esse limiar?
Para mais informações, veja minhas notas de texto puro muito antigas... Image Comparing, Tower of Computational Sorcery
Correspondência de Sub-Imagens e Formas
Em Construção
Usando a opção "compare -subimage-search"...
magick compare -subimage-search large_image.png sub-image.png results-%d.png
Isto produz duas imagens
results-0.png
que exibe a localização da correspondência
results-1.png
que é um mapa das possíveis localizações do canto superior esquerdo, mostrando o quão bem
a sub-imagem corresponde naquela localização.
Observe que a segunda imagem é menor, pois contém apenas localizações do canto superior esquerdo.
Assim, seu tamanho é large_image - small_image + 1
A busca, porém, é baseada em uma diferença de vetores de cor, portanto produz
uma comparação de cores muito precisa.
A busca basicamente faz uma comparação da imagem pequena em CADA localização
possível na imagem maior. Assim, é lenta! **muito, muito lenta.**.
A melhor ideia é comparar uma sub-imagem bem PEQUENA para encontrar possíveis
localizações, e então usá-las para fazer uma comparação por diferença em cada possível
localização, para uma correspondência mais precisa.
Dê uma olhada no script
../static/img/scripts/overlap
e na discussão associada
[Overlapped Images](https://magick.imagemagick.org/viewtopic.php?f=1&t=22526&p=95286)
Que examina como localizar sub-imagens de 'alta entropia' de uma imagem para buscar
possíveis correspondências em uma segunda imagem, de modo que o deslocamento de sobreposição entre as
duas imagens possa ser descoberto e as imagens mescladas em uma imagem maior.
Outra discussão usa buscas de sub-imagem para encontrar padrões de ladrilho em
imagens maiores, com o objetivo de gerar imagens ladrilháveis
[Stitching image over a canvas](https://magick.imagemagick.org/viewtopic.php?f=1&t=22860)
Exemplo usando RMSE e a nova função -grayscale para mesclar os
resultados dos canais de diferença de cor separados em uma imagem final
magick large_image.png small_image.png miff:- |
magick compare -metric RMSE -subimage-search - miff:- |
magick - -delete 0 -grayscale MS show:
Limiar de Similaridade
Como muitas vezes as pessoas estão interessadas apenas na primeira correspondência que ocorre.
Assim que essa 'boa' correspondência é encontrada, não há necessidade de continuar
buscando outra correspondência. O -similarity-metric define o que você
consideraria uma boa correspondência.
Um "-similarity-threshold 0.0" abortará na primeira correspondência 'perfeita'
encontrada, enquanto "-similarity-threshold 1.0" (o padrão) nunca corresponderá e
buscará em todos os pontos possíveis. Um valor intermediário definirá apenas um
fator de 'fuzz' de cor sobre o que você consideraria uma correspondência aceitável.
Observe que, se a busca de sub-imagem for abortada, a segunda imagem de 'mapa'
conterá apenas um resultado parcial, mostrando apenas os resultados até o ponto em que a comparação
abortou sua busca).
Alguns Exemplos Básicos de Busca de Sub-Imagem....
Capture uma captura de tela de uma janela de terminal ("screen.png"),
e recorte uma imagem de uma única letra ou palavra ("letter.png").
Apenas relate a primeira correspondência.... por velocidade,
aborte imediatamente após encontrar essa primeira correspondência.
Não se preocupe em gerar os resultados de imagem incompletos.
magick compare -subimage-search -metric AE -similarity-threshold 1.0 \
screen.png letter.png null: 2>&1
NOTA: a velocidade dependerá muito de onde na imagem essa primeira
correspondência é encontrada.
Encontre todas as ocorrências exatamente dessa imagem,
como uma imagem (pontos brancos nas correspondências, preto no restante)
magick compare -subimage-search -metric AE \
screen.png letter.png miff:- 2>/dev/null |
magick - -delete 0 show:
Extraia uma lista das coordenadas de todas as letras correspondentes (pontos brancos)
(como uma lista enumerada de pixels, ignorando tudo o que for preto)
magick compare -subimage-search -metric AE \
screen.png letter.png miff:- 2>/dev/null |
magick - -delete 0 txt:- | grep -v '#000000'
Apenas a lista de coordenadas
magick compare -subimage-search -metric AE \
screen.png letter.png miff:- 2>/dev/null |
magick - -delete 0 txt:- | sed -n '/#FFFFFF/s/:.*//p'
Soluções de busca de sub-imagem NÃO baseadas em ImageMagick...
"visgrep", do pacote "xautomation".
Este é um programa de busca de sub-imagem muito mais simples, que apenas gera uma
lista de coordenadas para as correspondências (ou até múltiplas correspondências de sub-imagem).
Por ser tão mais simples (para correspondência quase exata) e não tentar
gerar 'imagens de resultado' para estudo posterior, também é MUITO MAIS RÁPIDO.
Por exemplo...
visgrep screen.png letter.png
Resultados cronometrados
usando "compare" para obter apenas a primeira correspondência 0.21 segundos
usando "compare" para obter uma 'imagem de resultado' 1.56 segundos
idem, mas extraindo a lista de coordenadas 1.76 segundos
usando "visgrep" para obter todas as coordenadas correspondentes 0.09 segundos
Outros Métodos de busca de sub-imagem....
Morfologia HitAndMiss
Isto é essencialmente uma correspondência binária, em que você define quais pixels devem ser
'fundo' e quais devem ser primeiro plano. Contudo, também permite que você
defina áreas em que não importa se o resultado é primeiro plano ou
fundo.
Basicamente, um método de busca de padrão binário.
Correlate (uma variante de Convolve)
Isto é semelhante ao Hit and Miss, mas usando valores em tons de cinza. Valores positivos
para primeiro plano e valores negativos para fundo, e zero para 'não importa'.
É, porém, limitado a imagens em tons de cinza.
Veja [Correlação e Busca de Formas](convolve.html#correlate_search).
Ambos são basicamente tão lentos quanto a comparação de sub-imagem anterior,
mas menos precisos quanto às cores. Contudo, sua capacidade de especificar
uma forma (áreas 'não importa') para a sub-imagem os torna úteis como
método de busca.
No entanto, você precisa converter (magick) a sub-imagem em um 'núcleo', ou array de
valores de ponto flutuante, em vez de uma imagem propriamente dita.
FFT Convolve (NCC)
As Transformadas Rápidas de Fourier são um operador lento, mas geralmente muitas ordens de
magnitude mais rápido do que os dois métodos anteriores. A razão é que
uma convolução no domínio da frequência é apenas uma multiplicação direta pixel a pixel.
multiplicação.
O método 'Convolve' pode ser convertido em um 'Correlate', simplesmente
rotacionando em 180 graus a sub-imagem que está sendo buscada.
Veja [Correlate](convolve.html#correlate).
Basicamente, convertendo as imagens para o domínio da 'frequência', você pode fazer
uma busca de sub-imagem muito rapidamente, em comparação com as anteriores, especialmente
com sub-imagens maiores que podem ter o mesmo tamanho da imagem original!
Creio que isto foi adicionado como uma métrica de comparação NCC.
<a id="peak_finding"></a>
Localização e extração de picos (para correspondências quase parciais)...
Depois de ter comparado a imagem, você normalmente terá um 'mapa de probabilidade'
de algum tipo, que define o quão 'perfeita' foi a correspondência.
O que você quer fazer agora é encontrar a melhor correspondência, ou talvez múltiplas
correspondências na imagem. Ou seja, você quer localizar os principais 'picos'
no mapa resultante e extrair as localizações reais.
* Usando um Núcleo de Convolução Laplaciano
Para obter resultados, você precisa encontrar os 'picos' na imagem, não
necessariamente os pontos mais brilhantes. Você pode obter isso convolvendo
a imagem de modo a subtrair a média dos pixels vizinhos do
pixel central. Como só queremos resultados positivos, um bias remove os
resultados negativos.
magick mandril3_ncc1.png \
-bias -100% -convolve Laplacian:0 result.png
Aplicando limiar e usando isso como máscara, podemos extrair apenas esses pixels.
magick mandril3_ncc1.png \
\( +clone -bias -100% -convolve Laplacian:0 -threshold 50% \) \
-compose multiply -composite \
txt:- | grep -v black
O problema é que você pode obter um agrupamento de pontos em um pico, em vez de
um pixel definitivo, especialmente para dois pixels de pico cercados por valores muito
baixos.
* Usando um Núcleo de Morfologia Hit and Miss para Picos
magick mandril3_ncc1.png \
-morphology HMT Peaks:1.5 result.png
O problema é que isso pode não produzir resultado se você tiver dois pixels de pico
com exatamente o mesmo valor (sem intervalo entre primeiro plano e fundo)
No entanto, há outros núcleos de 'pico' que ainda localizarão um agrupamento
de pico assim.
* Dilatar e comparar
Dilate (expande os valores máximos) a imagem 3 vezes e então a compare com a
imagem original. Qualquer pico dentro da área do tamanho do núcleo dilatado (quadrado de 7
pixels) permanecerá com o mesmo valor. Defina como zero todos os pixels que apresentem
diferença.
Método de HugoRune (tópico de discussão do IM 14491)
* Correspondência e remoção em laço.
Basicamente, encontre o maior valor de pixel e anote-o. Então mascare todos os pixels em
uma área ao redor desse pico, e repita até que algum limite (número de pontos ou
limiar) seja atingido.
Veja uma implementação em shell script disso no script de Fred Weinhaus
"[maxima](http://www.fmwconcepts.com/imagemagick/maxima/)"
Isto não busca encontrar o centro de um grande 'agrupamento' de pixels de valor quase
igual, embora isso seja muito raro em imagens reais.
* Localização em sub-pixel
Se o pico não for um pixel exato, mas puder concebivelmente estar em uma localização
de sub-pixel (entre pixels), então alguma forma de correspondência de padrão (ajuste de curva
gaussiana) na área do pico pode permitir localizar o pico com uma
coordenada de sub-pixel.
Isto pode ser mais importante no registro de imagens para costura de panoramas,
especialmente quando você não está usando um grande número de pontos para obter uma
média de melhor ajuste da sobreposição de perspectiva.
* Encontrar um padrão de ladrilho em uma imagem
Quando você tiver todos os pontos, uma busca por um padrão repetido (distâncias
vetoriais semelhantes entre múltiplos picos) deveria indicar alguma forma de
estrutura de ladrilho.
Aprimorando a Correspondência de Sub-Imagem...
O maior problema com o Correlate (ou o rápido FFT correlate, que é a
mesma coisa) é que ele não tem absolutamente nenhuma compreensão de cor.
A correlação (ou convolução) é puramente uma técnica matemática usada
sobre um conjunto de valores. Com imagens, isso significa que ela só é aplicada
sobre os canais individuais de uma imagem, e NÃO com distâncias vetoriais de
cor.
Já o compare de fato faz uma comparação real de vetores de cor. Isto encontrará
formas melhor do que o correlate, mas é muito, muito mais lento.
Assim, para fazer bom uso do correlate, você deveria converter (magick) suas imagens
(de antemão, por velocidade, ou depois, sobre os resultados) para tentar destacar
as diferenças de cor da imagem como uma imagem de 'correlação' em tons de cinza.
OBSERVAÇÃO: usar -channel para limitar as operações a um único canal em tons de cinza
melhorará a velocidade. No IMv7, a conversão para tons de cinza reduzirá as imagens a um canal, então
ganhará melhorias de velocidade automaticamente.
Por exemplo, em vez da intensidade, você pode obter uma melhor diferenciação de
primeiro plano / fundo extraindo o Hue (matiz) de uma imagem.
Embora você possa precisar rotacionar os matizes se houver muito vermelho
na sub-imagem que está sendo buscada.
Veja os exemplos de HSL e HSB, separação de canais, para ver esse problema.
https://usage.imagemagick.org/color_basics/#separate
Outro método de conversão para tons de cinza que deveria funcionar muito bem é fazer detecção
de bordas nas duas imagens. Isto destacará os limites e a forma,
que normalmente é muito mais importante do que qualquer gradiente suave ou mudança
de cor na imagem.
Para exemplos de métodos de detecção de bordas, veja
https://usage.imagemagick.org/convolve/#edgedet
Você também pode gostar de ver a detecção de bordas direcional ou do tipo bússola.
Basicamente, qualquer coisa que realce a forma para o seu caso específico é
uma boa ideia. Apenas aplique-a a AMBAS as imagens antes de correlacioná-las.
Correspondência Invariante a Escala e Rotação...
* independência de posição...
* correspondência de sub-imagem rotacionada (independente de ângulo)
* correspondência de sub-imagens redimensionadas (independente de tamanho)
* Independência tanto de tamanho quanto de ângulo
--------------
Outras correspondências de imagem mais específicas..
Correspondência de linhas...
Algoritmo de Hough
Correspondência de círculos...
Variante do Algoritmo de Hough
Correspondência de rostos
Uma combinação dos itens acima.
Encontrar Imagens Duplicadas
Arquivos idênticos
Os arquivos são binariamente idênticos, isto é, são exatamente o mesmo arquivo e provavelmente apenas cópias exatas uns dos outros? Nenhum ImageMagick é necessário. Não descarte isto. Você pode comparar muitos arquivos com muita rapidez dessa forma. O melhor método que encontrei é usando somas de verificação MD5.
md5sum * | sort | awk {'print $2 " " $1'} | uniq -Df 1
E isso listará os md5 das imagens que são idênticas. Usando esta técnica, criei scripts que podem gerar e comparar listas de md5sum de arquivos, retornando os arquivos que são idênticos em md5. Observe, porém, que qualquer alteração em um arquivo de imagem que não seja uma cópia direta será classificada por isto como diferente, mesmo que os dados da imagem em si sejam os mesmos. Basta uma mudança de data ou outra pequena diferença de metadados no arquivo para tornar a imagem diferente.
Assinaturas de Imagem do IM
Você pode fazer o IM gerar uma 'assinatura' para cada imagem...
magick identify -quiet -format "%#" images...
Isto gera uma string de hash muito parecida com o que MD5 e SHA256 fazem. Contudo, ao contrário destes últimos, ela usa os dados reais da imagem para gerar a assinatura, não os metadados da imagem. Assim, se você tiver duas cópias da mesma figura, mas com marcas de tempo de criação/modificação diferentes, deveria obter a mesma assinatura para ambos os arquivos, ao passo que MD5 e SHA256 produzirão duas assinaturas, mesmo que a imagem em si seja a mesma. AVISO: ler e gravar uma imagem JPEG gerará dados de imagem diferentes e, portanto, uma assinatura diferente. Isto se deve simplesmente à compressão com perdas que o formato de imagem JPEG usa.
Comparação Direta
Você pode comparar diretamente duas imagens (usando o programa "magick compare") se elas tiverem o mesmo tamanho, para ver o quão bem elas correspondem. (Veja acima) Isto é muito lento e, na minha experiência, não muito útil quando aplicado a uma imagem em tamanho real, porque é muito lento. Contudo, é provavelmente a melhor forma de ter uma ideia de quão semelhantes são duas imagens.
Classificação de Imagens
Nas minhas tentativas de comparar imagens, descobri que imagens coloridas, do tipo desenho animado e esboços comparam-se de maneiras muito diferentes entre si. Desenhos de linhas e imagens em tons de cinza tendem, em especial, a ter diferenças menores do que as imagens coloridas, em praticamente qualquer método de comparação. Basicamente, como as cores estão todas em uma linha, qualquer métrica de cor tende a colocar tais imagens 3 vezes mais próximas (espaço de cor unidimensional versus espaço de cor tridimensional). Basicamente, isso significa que separar suas imagens em pelo menos esses dois grupos pode ser um primeiro passo muito importante em qualquer tentativa séria de encontrar imagens duplicadas ou muito semelhantes. Outras grandes classificações ou tipos de imagem também podem facilitar a comparação de imagens, apenas reduzindo o número de imagens contra as quais você está comparando. Veja Classificação de imagens abaixo.
Comparação por Miniaturas
Você faz um programa criar (em memória) muitas miniaturas pequenas (digamos, 64x64 pixels) de imagens para comparar em busca de duplicatas, o que você passa a fazer por comparação direta. Costuma ser a primeira coisa que as pessoas (inclusive eu) tentam fazer e, de fato, esta é a técnica que a maioria dos programas de comparação de imagens (como softwares de gerenciamento de fotos) utiliza. Na verdade, isso funciona bem e encontra imagens que correspondem exatamente. Além disso, com um pouco de desfoque e afrouxando o limiar de diferença, pode até encontrar imagens que foram levemente recortadas e redimensionadas. Contudo, tentar armazenar em memória 10.000 dessas miniaturas muitas vezes fará um computador normal começar a fazer thrashing, ficando muito lento. Como alternativa, armazenar todas essas miniaturas (a menos que o programa faça isso para fins de visualização pelo usuário) usa muito espaço em disco. Um método para reduzir o problema do thrashing de disco é manter em memória apenas um número menor de imagens. Ou seja, comparando imagens em grupos, em vez de uma imagem contra todas as outras. Um agrupamento natural é por diretório, comparando cada diretório de imagens com outros diretórios de imagens. Na verdade, isso é bastante bom, pois as imagens tendem a ser agrupadas e esse grupo de imagens muitas vezes corresponderá a um grupo semelhante. Gerar imagens correspondentes por pares de diretórios é, portanto, um bônus. Além disso, o quão aceitavelmente semelhantes são duas imagens depende do tipo delas. Comparar dois desenhos de linhas precisa de um 'limiar' muito pequeno para descartar imagens que diferem, enquanto comparar imagens com grandes áreas de cor muitas vezes precisa de um limiar bem maior para capturar imagens semelhantes que foram recortadas. Imagens do mundo real têm um problema maior: uma textura pode produzir uma diferença aditiva muito séria entre imagens que têm um deslocamento muito pequeno. Por isso, você pode precisar simplificar tais imagens em áreas gerais de cor, seja usando filtros de mediana, desfoque, redução de cores ou segmentação de cores. Após tal processo, uma imagem do mundo real geralmente pode ser comparada de forma semelhante a desenhos animados.
Métricas de Imagem
Criar uma pequena métrica para cada imagem é uma operação de ordem linear (O). Já comparar todas as imagens com todas as outras imagens é uma operação de ordem quadrática (O^2). Uma métrica não tem a intenção de realmente encontrar imagens correspondentes, mas de agrupar imagens semelhantes (que provavelmente correspondem) de tal forma que você possa fazer uma comparação mais intensiva em grupos menores. Assim, qualquer comparação por métrica deveria ser tolerante e aceitar imagens que tenham baixa probabilidade (mas ainda uma probabilidade) de correspondência. Mas não deveria ser tão tolerante a ponto de incluir muitas correspondências falsas. Você também pode querer considerar múltiplas métricas, pois algumas métricas podem casar imagens que outra métrica 'por pouco não' casaria, por caírem em regiões vizinhas diferentes (erro de correspondência por limiar). Na próxima seção (Métricas), há várias métricas geradas pelo IM diferentes com as quais experimentei, ou sobre as quais teorizei, incluindo: cor média, cor predominante, primeiro plano/fundo, cores de borda, matriz de cores, etc. Günter Bachelier também relatou as possibilidades de usar métricas mais exóticas para comparação de imagens, tais como: descritores de Fourier, dimensões fractais, áreas convexas, comprimentos e ângulos de eixos maior/menor, arredondamento, convexidade, curl, solidez, variâncias de forma, direção, números de Euler, descritores de contorno, curvatura, energia de flexão, curvatura absoluta total, áreas, centro geométrico, centro de massa, compacidade, excentricidade, momentos em torno do centro, etc, etc. Meu esforço atual está em gerar e usar uma simples matriz 3x3 de médias de cor para representar a imagem (Veja Métrica de Matriz de Cores abaixo). À medida que estas são geradas (ou solicitadas), a métrica é armazenada em cache (com outras informações do arquivo) em arquivos especiais em cada diretório. Dessa forma, só preciso regerar uma métrica específica quando e se nenhuma métrica em cache estiver disponível, ou se a imagem mudar.
Similaridade ou Distância
As métricas de duas imagens (ou as próprias imagens) podem ser comparadas usando vários métodos diferentes, geralmente produzindo uma única medida de distância ou 'métrica de similaridade' que pode ser usada para agrupar imagens 'semelhantes'.
- Limiar Direto, ou Diferença Máxima (Distância de Chebyshev)
Apenas compare as imagens pela maior diferença em qualquer métrica isolada.
O limiar produzirá um hipercubo de imagens semelhantes no espaço de métricas multidimensional. É claro que a diferença de imagem se baseia em apenas uma métrica e não em todas as métricas. - Diferença Média (Distância Média, Distância de Manhattan Média)
Some todas as diferenças e, opcionalmente, divida pelo número de métricas.
Isto também é conhecido como a Distância de Manhattan entre duas métricas, pois é equivalente à distância que você precisa percorrer para se deslocar em uma malha urbana. Todas as métricas contribuem igualmente, fazendo com que as coisas pareçam 'mais próximas' do que se espera. No espaço, um limiar desta métrica produzirá uma forma semelhante a um losango. - Diferença Euclidiana (Pitagórica)
Ou a distância vetorial direta entre as métricas no espaço de métricas.
O valor tende a ser maior quando mais métricas estão envolvidas. Contudo, uma métrica que produz uma grande diferença tende a contribuir mais do que as outras métricas. Um limiar produz um volume esférico no espaço de métricas. - Erro Matemático/Ajuste de Dados ou (Momento de Inércia???)
Some todos os quadrados de todas as diferenças e então extraia a raiz quadrada
Isto é mais tipicamente usado para calcular o quão bem uma curva matemática se ajusta a um conjunto específico de dados, mas também pode ser usado para comparar métricas de imagem.
Isto parece fornecer a melhor medida de distância não vetorial. - Ângulo de Vetor
Encontre o ângulo entre as duas retas a partir do centro do espaço vetorial criado pela métrica das imagens. Isto deveria remover qualquer efeito de contraste ou realces de imagem que possam ter sido aplicados às duas imagens.
Ainda a ser testado - Distância de Vetor
Para imagens que são desenhos de linhas ou imagens em tons de cinza, em que todos os vetores de cor individuais de uma métrica estão na mesma direção, as distâncias relativas das métricas em relação à cor média da imagem são provavelmente mais importantes. Normalizar as distâncias em relação à maior distância pode reduzir o efeito do contraste.
Ou seja, este é um método de comparação de imagem de desenho de linhas.
Ainda a ser testado - Análise de Agrupamento (Cluster)
Todas as métricas são plotadas e agrupadas em clusters semelhantes dentro do espaço multidimensional. Um bom pacote de clustering pode até ser capaz de descobrir e descartar métricas que não produzem nenhum agrupamento.
Ainda a ser testado
No momento, estou constatando que a técnica de "Erro Matemático" parece funcionar bem tanto para métricas em tons de cinza quanto coloridas, usando uma simples "Métrica de Matriz de Cores" 3x3 de médias (veja abaixo).
Verificação Humana
Depois que o computador termina suas tentativas de encontrar imagens correspondentes, cabe então ao usuário verificar de fato se as imagens correspondem. Apresentar as correspondências ao usuário também pode ser uma tarefa difícil, pois ele provavelmente vai querer a capacidade de...
- Ver as imagens lado a lado
- Alternar bem rapidamente entre duas imagens, em seu tamanho original e, opcionalmente, em um tamanho 'escalado' comum.
- Alternar entre, ou sobrepor, imagens escaladas e deslocadas de forma diferente, para tentar fazê-las coincidir.
- Ver outras imagens no mesmo diretório (origem) ou talvez no mesmo cluster (outras correspondências próximas) da imagem correspondente, de modo a lidar com um grupo inteiro em vez de cada imagem individualmente.
- Renomear, Mover, Substituir, Excluir, Copiar as imagens entre os dois (ou mais) diretórios, para organizar as imagens e rejeitar as demais.
- e assim por diante...
. Atualmente, agrupo as correspondências em conjuntos e uso uma combinação de programas para tratá-las sob o controle do usuário. Esses programas incluem o "magick display" e o "magick montage" do IM, bem como os visualizadores de imagem "XV" e "GQview". Contudo, estou aberto a outras sugestões de programas que possam abrir dois ou mais diretórios simultaneamente e exibir coleções ou grupos de imagens de múltiplos diretórios. O controle remoto por outros programas ou scripts pode ser vital, pois permite que os grupos de imagens sejam configurados e apresentados da melhor forma para o usuário examinar e tratar. Nenhum programa ainda atendeu às minhas necessidades. Por exemplo, o "gqview" tem coleções e uma visão de diretório único, mas não permite visões de múltiplos diretórios, nem controle remoto / por linha de comando da apresentação. Contudo, as coleções não mostram de qual diretório é cada imagem, nem alternam a visão de diretório único para algum outro diretório. Ele também não tem controle remoto por programa. Por outro lado, o bem antigo "xv" permite visões de múltiplos diretórios (usando múltiplas janelas 'visual schnauzer') e uma lista de coleção em sua janela de controle, mas apenas uma imagem pode ser visualizada por vez, e apenas um diretório pode ser aberto e posicionado a partir de sua linha de comando. É claro que ele também não tem controle remoto. Estes são os melhores programas de verificação humana que encontrei, os quais uso com um script para configurar e iniciar para cada grupo de imagens, pares correspondentes ou todas as imagens correspondentes de um grupo. Mas nenhum é muito satisfatório. Uma mesa de luz e o software associado parecem-me o melhor método para organizar imagens, mas para isso você precisa de telas sensíveis ao toque maiores, e aí reside uma grande despesa.
Comparação de Imagens de Tipos Diferentes
Uma das coisas mais difíceis que eu gostaria de fazer é encontrar imagens que foram criadas a partir de outra imagem. Por exemplo, eu gostaria de casar um desenho de linhas que outra pessoa coloriu, ou pintou, para produzir imagens de desenho animado ou até ultrarrealistas. Um fundo também pode ter sido adicionado. Essas coisas são muito difíceis, e meus experimentos com técnicas de detecção de bordas foram, até agora, inconclusivos. Encontrar a métrica certa nisto é a chave, pois os humanos conseguem fazer a conexão de 'similaridade' muito melhor, mas você ainda precisa encontrar possíveis correspondências para apresentar ao usuário.
Resumo de Encontrar Imagens Duplicadas
Em resumo, meu procedimento atual para encontrar e tratar imagens duplicadas é um pipeline de programas para encontrar e organizar imagens 'semelhantes'.
Gerar/Armazenar em Cache Tipos e Métricas de Imagem
-> Comparar métricas e agrupar imagens.
-> comparar imagens no cluster em busca de correspondências
-> agrupar em conjuntos de imagens correspondentes (por diretório de origem)
-> verificação humana
Como se pode ver, estou buscando uma abordagem altamente escalonada. Envie-me suas ideias!!!
Ordenar Imagens por Tipo
Determinar qual é o tipo de imagem é importante, pois a maioria dos métodos de comparação de imagens só funciona para um tipo específico de imagem. Não adianta comparar uma imagem de texto com o esboço de um artista, por exemplo. Nem é útil usar um método de comparação de imagens coloridas em uma imagem que é quase totalmente branca (esboço). Normalmente, a primeira coisa a fazer ao comparar imagens é determinar qual tipo de imagem, ou 'espaço de cor', a imagem usa. As classificações básicas de imagens podem incluir...
- Desenho de linhas em preto e branco ou imagem de texto (quase toda de uma só cor)
- Imagens compostas por duas cores básicas - de forma igual (imagens de padrão?).
- Desenhos de artistas em tons de cinza (muitos tons)
- Imagens de Cor Linear (as cores formam um gradiente, mas não do preto ao branco)
- Imagem colorida do tipo desenho animado, com grandes áreas de cores sólidas.
- Uma imagem da vida real com áreas de cores sombreadas
- A imagem contém algum texto anotado ou sobreposição de logotipo. (um único pico de cor)
Depois de ter categorias básicas, você também pode tentar ordenar as imagens usando várias métricas de imagem, tais como... * Cor média de toda a imagem * cor predominante na imagem * Cor de primeiro plano/fundo da imagem.
O que é pior, JPEG, ou imagens redimensionadas, frequentemente também têm cores distorcidas, tornando tais classificações muito mais difíceis, pois as cores não serão exatamente como deveriam ser. Cinzas não serão cinzas puros, e as linhas podem não ser nítidas e claras. Uma discussão contínua e de longo prazo sobre ordenar imagens por tipo está no Fórum de Usuários do IM... How to check image color or black and white.
Imagens em Tons de Cinza
A forma mais simples de verificar se uma imagem é em tons de cinza é observar os níveis de saturação de cor da imagem. Isso é feito facilmente convertendo a imagem para um espaço de cor 'Hue' (matiz) e obtendo os valores médio e máximo do canal de cor (tipicamente o verde). Por exemplo..
magick rose: granite: -colorspace HCL \
-format '%M avg=%[fx:mean.g] peak=%[fx:maxima.g]\n' info:
Os números são normalizados para uma faixa de 0 a 1. Como se pode ver, a "rose" é muito colorida (média de 30%), com um pico forte (próximo de 1). A imagem "granite", porém, tem uma saturação muito baixa (cerca de 2%) e um valor de pico baixo. Embora não seja tons de cinza puros, é muito próxima disso. Uma média baixa e um pico alto indicam pequenas manchas de cor forte. Aplicar limiar ao mesmo canal pode gerar uma máscara das áreas coloridas da imagem. PROBLEMA: o exposto acima não encontra imagens que são lineares em cor. Ou seja, imagens que contêm apenas cores que formam um gradiente linear de cor, como fotos amareladas (sépia) ou plantas técnicas (blueprints). Estas são essencialmente imagens em tons de cinza coloridas. Veja o próximo tipo de imagem.
A Imagem é de Cor Linear
Outra técnica é fazer um 'melhor ajuste' direto de uma reta tridimensional a todas as cores (ou a uma Matriz de Cores simplificada de métricas) da imagem. O erro do ajuste (geralmente a média dos quadrados dos erros) dá uma indicação muito boa de quão bem a imagem se ajusta a essa reta. O ajuste de uma reta à imagem tridimensional geralmente envolve alguma matemática vetorial. O resultado não só dirá se a imagem usa um conjunto de cores quase 'linear', mas funciona para QUALQUER escala de cores, não apenas de claro a escuro, mas também linhas em cinza sujo sobre papel amarelo. O resultado também pode ser usado para converter (magick) a imagem em uma imagem 'em tons de cinza' mais simples (ou apenas converter um conjunto de métricas de cor em métricas em tons de cinza) para comparações mais simples e melhor localização de correspondências. Meu programa de teste experimental não usa nem a imagem inteira para fazer essa determinação, mas funciona usando uma simples Métrica de Matriz de Cores de 9 cores (27 valores) abaixo para representar a imagem. Contudo, esteja avisado de que esse teste geralmente não diferencia bem os desenhos de linhas não sombreados. Tais imagens são quase inteiramente de uma única cor de fundo (tipicamente branco) e, como tal, podem não apresentar nenhuma forma de gradiente linear de cores. Elas deveriam ser separadas primeiro usando um teste diferente (veja a seguir; na verdade é bem mais fácil). Escreva-me se tiver interesse, e me conte o que você tentou.
Imagens de Preto e Branco Puros
Para ver se uma imagem é quase puramente preto e branco, com pouca cor ou mesmo cinza (devido ao anti-serrilhamento), podemos fazer um uso inusitado da opção "[-solarize](https://imagemagick.org/command-line-options/#solarize)" (Veja o exemplo do IM em Solarize). Aplicar essa operação em qualquer imagem faz com que quaisquer cores claras se tornem cores escuras (sendo negadas). Assim, quaisquer cores quase brancas se tornarão cores quase pretas. A partir de tal imagem, uma simples análise estatística determinará se a imagem é puramente (ou quase puramente) preto e branco.
magick wmark_dragon.jpg -solarize 50% -colorspace Gray wmark_bw_test.png
magick identify -verbose -alpha off wmark_bw_test.png | \
sed -n '/Histogram/q; /Colormap/q; /statistics:/,$ p' > wmark_stats.txt
| | ![[IM Text]](../static/img/compare/wmark_stats.txt.gif)
Se você olhar as estatísticas acima, verá que a 'mean' (média) da cor está muito próxima do preto puro ('0'), enquanto o 'standard deviation' (desvio padrão) também é muito pequeno, mas maior que a 'mean'. Assim, esta imagem deve ser majoritariamente preto e branco puros, com muito poucas cores ou cinzas de tom médio. Para imagens gerais em tons de cinza e coloridas, a 'mean' será bem maior e, geralmente, o 'standard deviation' menor que a média. Quando isso acontece, significa que a imagem solarizada tem muito pouco de preto quase puro. Ou seja, muito poucas cores pretas ou brancas puras estão presentes. Vamos repetir este teste usando a imagem granite embutida.
magick granite: granite.jpg
magick granite.jpg -solarize 50% -colorspace Gray granite_bw_test.png
magick identify -verbose -alpha off granite_bw_test.png | \
sed -n '/Histogram/q; /Colormap/q; /statistics:/,$ p' > granite_stats.txt
| | ![[IM Text]](../static/img/compare/granite_stats.txt.gif)
Note como a 'mean' agora é bem maior, em direção ao meio da faixa de cores, com um 'standard deviation' que é bem menor que o tamanho da 'mean'. A partir do IM v6.4.8-3, você também verá dois outros valores estatísticos que podem ajudar a determinar o tipo de imagem. Tanto a 'Kurtosis' (curtose) quanto a 'Skewness' (assimetria) são relativamente grandes (e positivas) na primeira imagem de Preto e Branco, o que também reflete o fato de que muito poucos cinzas estão envolvidos em comparação com uma imagem em tons de cinza. Contudo, 'mean' versus 'standard deviation' ainda é provavelmente o melhor indicador para fins de comparação. Note que esta comparação não diferencia entre 'preto sobre branco' ou 'branco sobre preto', mas, uma vez que você sabe que não é realmente uma imagem em tons de cinza, uma simples verificação da média normal das imagens dirá qual é de fato a cor de fundo.
Imagens com Cores Localizadas
Estas imagens falham no teste de tons de cinza acima, mas ainda são preto e branco com uma pequena área ou mancha de cor. Pequenas manchas de cor poderiam facilmente ser encobertas pela média geral de uma imagem grande, podendo ser tipificadas erroneamente como tons de cinza. Não estamos interessados em imagens com apenas, digamos, um único pixel de cor, o que provavelmente é um erro de bit, ou um salpicado desses pixels pela imagem. Mas sim em uma imagem com, digamos, uma seta colorida ou um pequeno objeto colorido. Em outras palavras, uma mancha concentrada de cor. Em uma discussão no Fórum do IM, False positive for greyscale images using the "saturation test", pensou-se em quebrar as imagens em seções menores e, então, procurar uma alta saturação em qualquer uma dessas áreas. Isso levou ao método a seguir.
- converter (magick) a imagem para um espaço de cor com um canal de Saturação ou Croma
- Redimensionar a imagem para menor, em uma proporção de 1:50 (2%) (ex.: um 'tamanho de mancha' para cor)
- Aplicar limiar para obter o valor máximo de saturação/croma
Manchas individuais ou muito pequenas serão removidas, mas uma mancha de cor maior terá pelo menos um pixel colorido na imagem redimensionada.
Imagens Coloridas em Tons Médios
Imagens em tom sépia, ou com cinzas de tom médio coloridos em alguma cor de destaque (por exemplo, a imagem à direita), podem ser muito mais difíceis de distinguir. Gerar tais imagens é fácil, como mostrado em Coloração de Tons Médios, embora não sejam muito comuns. As cores ainda formam um gradiente (linha) de cores no espaço de cor, mas esse gradiente segue um caminho curvo, tipicamente uma parábola de algum tipo, em um plano. Mas distinguir tais imagens pode ser muito difícil. Uma técnica é obter um desvio padrão de quaisquer matizes que não tenham uma saturação extremamente pequena. Todos os matizes em uma imagem colorida de tom médio deveriam ser muito semelhantes, mesmo que não haja muitos deles. Esta técnica foi apresentada no post específico em How to check image color or back and white. Apenas um lembrete de que o Hue (matiz) é um valor cíclico e dá a volta na cor 'vermelho'. Para testar corretamente, você pode ter de fazê-lo duas vezes, com os matizes deslocados em 180 graus. Além disso, o Hue não tem um significado real para qualquer cor com saturação muito baixa (cinza), portanto qualquer cor assim deveria ser ignorada ao testar o desvio padrão dos matizes.
Texto vs Desenho de Linhas
Se você tiver uma imagem que é quase puramente de uma única cor (tipicamente branco), então pode tentar ver se o conteúdo da imagem pode ser classificado como texto ou como um desenho de linhas. O texto terá muitos pequenos objetos desconectados, geralmente agrupados em linhas horizontais. Por outro lado, os desenhos de linhas deveriam ter quase tudo conectado como um todo, envolvendo muitos ângulos diferentes. Note que imagens coloridas do tipo desenho animado também poderiam ser transformadas em um desenho de linhas para uma comparação de imagens mais simples, de modo que um método de comparação de desenhos de linhas seria algo útil de se ter. Alguém? Para saber mais sobre o texto, várias técnicas foram discutidas nos fóruns do IM, Check if image contains text.
Vida Real vs Tipo Desenho Animado
Basicamente, os desenhos animados têm blocos de cor muito específicos, com regiões de bordas nítidas, muitas vezes tornadas mais nítidas pelo uso de uma linha preta separadora. Eles também costumam ter efeitos mínimos de gradiente ou sombreamento. As imagens da vida real, porém, têm muitos efeitos de bordas suaves, gradientes de cor e texturas, e usam muitas cores diferentes. É claro que isso nem sempre é verdade. Uma imagem da vida real poderia ter uma qualidade muito semelhante a um desenho animado, especialmente se for usado um contraste muito alto, e alguns desenhos animados modernos são tão realistas que pode ser difícil classificá-los como desenhos animados. Geralmente, a principal diferença entre uma imagem da vida real e um desenho animado são as texturas e os gradientes. Assim, para determinar de que tipo é a imagem, é preciso comparar a imagem com a mesma imagem sem a textura de escala fina. Uma grande diferença significa que a imagem é mais 'realista' e parecida com o 'mundo real', e não 'caricata' ou 'plana'. Lembre-se também de que um desenho de linhas, um esboço de artista e um texto também podem ser muito parecidos com desenhos animados no estilo, mas têm uma textura e um detalhe tão finos que o teste acima poderia considerar a imagem como sendo do mundo real. Por isso, os desenhos de linhas e esboços deveriam ser separados de antemão.
Jim Van Zandt oferece esta solução...
- escreva a cor de cada pixel
- ordene por cor
- escreva a contagem de pixels de cada cor
- ordene pela contagem de pixels
- Percorra a lista até ter contabilizado metade dos pixels da imagem.
- Se #pixels >>> #cores, então é do tipo desenho animado.
A seção inicial pode ser classificada como histograma. Veja os exemplos de "[histogram:](files.html#histogram)".
Se você criou algum tipo de esquema de classificação de imagens... mesmo que apenas aproximado, por favor nos conte seus resultados, para que outros (inclusive eu) possam se beneficiar.
Tratamento de Tipos Específicos de Imagem
Aqui estão notas e informações sobre técnicas de determinação de imagem mais específicas.
Digitalização ou Impressão com Defeito
No mundo real, as coisas nunca funcionam tão perfeitamente quanto se gostaria. Scanners têm sensores quebrados e os cilindros das impressoras têm arranhões. Ambos os problemas geralmente resultam em digitalizações e impressões contendo longas linhas verticais. Determinar se uma imagem tem essas linhas verticais é, porém, bastante fácil. A ideia é calcular a média dos pixels de todas as linhas de uma imagem em conjunto. Qualquer 'falha' aparecerá como um pico acentuado na linha final de pixels, cujo número você pode contar usando um 'histograma com limiar' da linha de pixels.
FUTURO -- exemplo de imagem necessário para teste
magick bad_printout.png -crop 0x1+0+0 -evaluate-sequence mean \
-threshold 50% -format %c histogram:info:-
método mais rápido, mas precisa da altura da imagem (assumida como 1024)
magick bad_printout.png -scale 1024x1 \
-threshold 50% -format %c histogram:info:-
Quando você tiver determinado e removido essas 'linhas ruins' de um fax, impressão ou digitalização, poderá então continuar com seus outros testes sem precisar se preocupar com esse tipo de falha do mundo real.
Fax em Branco
Primeiro, você precisará usar "[-shave](https://imagemagick.org/command-line-options/#shave)" para remover quaisquer cabeçalhos e rodapés que um fax possa ter adicionado a uma página. Você pode então fazer um 'histograma com limiar' (veja o anterior) para ver quantos pixels pretos individuais existem.
FUTURO -- exemplo de imagem necessário para teste
magick blank_fax.png -threshold 50% -format %c histogram:info:-
Ou você pode fazer um Recorte com Ruído para ver se a imagem realmente contém alguma área sólida ou objeto digno de sua atenção.
FUTURO -- exemplo de imagem necessário para teste
Imagens com Spam
Uma imagem com spam geralmente mostrará um pico de cor pura predominante no histograma de cores da imagem. Uma verificação da cor na imagem geralmente a mostrará em um dos cantos da imagem. Contudo, isso não funcionará com imagens do tipo desenho animado.
Imagens de Spam de E-mail
Estas são imagens projetadas para passar pelos vários filtros de spam. Basicamente, o texto do anúncio fica oculto em uma imagem usando várias cores e 'sujeira' extra e outro ruído adicionado para dificultar a detecção. E, embora sejam difíceis de distinguir de, digamos, o logotipo de um cabeçalho de e-mail de uma empresa, elas geralmente também são muito maiores do que o típico logotipo de e-mail. Uma técnica de descoberta é usar um filtro de mediana grande sobre a imagem. O texto de spam de e-mail geralmente desaparecerá, enquanto um logotipo ou imagem ainda permanecerá muito colorido.
Métricas de Imagem, encontrando rapidamente imagens para comparar
Uma métrica representa um tipo de 'impressão digital' para representar uma imagem, em uma quantidade muito pequena de memória. Imagens semelhantes deveriam resultar em uma métrica semelhante. Note, porém, que uma métrica não é projetada para realmente encontrar imagens correspondentes, mas para tentar descartar imagens que definitivamente não são uma correspondência. Ou seja, uma boa métrica permite desconsiderar a maioria das imagens em comparações posteriores, reduzindo assim o tempo necessário para buscar em todas as imagens.
Cor Média de uma imagem
Você pode usar -scale para obter uma cor média de uma imagem; contudo, também sugiro
que você remova as bordas externas da imagem para reduzir o efeito de
qualquer 'penugem' que possa ter sido adicionada ao redor da imagem.
magick image.png -gravity center -crop 70x70%+0+0 \
-scale 1x1\! -depth 8 txt:-
Alternativamente, para obter a cor do 'centroide ponderado', com base em agrupamento de cores,
em vez de uma média, você pode usar -colors
magick rose: -colors 1 -crop 1x1+0+0 -depth 8 -format '%[pixel:s]' info:-
rgb(146,89,80)
Isto geralmente casará imagens que foram redimensionadas, levemente recortadas, rotacionadas ou deslocadas. Mas também casará muitas imagens que não são de fato relacionadas. O maior problema é que essa métrica geralmente desconsiderará imagens que tiveram o brilho aumentado, diminuído ou o matiz geral alterado. Além disso, embora seja uma ótima métrica para imagens coloridas e do mundo real, ela é completamente inútil para imagens em tons de cinza. Todas essas imagens geralmente são agrupadas juntas sem qualquer clustering adicional dentro do tipo. Isso, por sua vez, mostra por que alguma classificação inicial de tipos de imagem pode ser vital para uma boa ordenação e correspondência de imagens.
Cor Predominante de uma imagem
A cor predominante de uma imagem é um pouco diferente: em vez da média, que mescla as cores de fundo com as de primeiro plano, você quer encontrar a cor de primeiro plano mais comum e, talvez, uma porcentagem de quanto da imagem consiste nessa cor predominante. Assim, você não pode simplesmente tirar um histograma de uma imagem, pois a imagem pode usar muitos tons individuais de cor em vez de uma cor específica. Isso pode ser feito usando a função de quantização de baixo nível -segment e, em seguida, tirando um histograma. Isto tem uma vantagem sobre o uso direto de -colors, pois não tenta mesclar agrupamentos de cores distantes (em termos de cor), embora os resultados possam ser mais difíceis de determinar.
exemplo FUTURO
Após o que um histograma lhe dará a quantidade de cada uma das cores predominantes. Contudo, geralmente a cor predominante de um desenho animado ou de linhas é a cor de fundo da imagem. Portanto, só é realmente útil para imagens da vida real. Por outro lado, você pode conseguir usá-la para descobrir se uma imagem tem um verdadeiro fundo, comparando isto com a cor média das bordas da imagem. Observe que a cor predominante de uma figura tende a ser mais fortemente influenciada pela cor de fundo da imagem do que pelo objeto de interesse. Ou seja, geralmente no centro ou próximo ao centro da imagem.
Cores das Bordas
Recortando repetidamente cada uma das quatro bordas (no máximo 2 a 3 pixels) de uma imagem e calculando a cor média das bordas, você pode determinar se uma imagem está emoldurada e com que profundidade. Se há um fundo definido para a imagem. Ou se há algum tipo de separação de cor céu/terra ou primeiro plano/plano distante na imagem como um todo. Comparando as cores médias das laterais com a cor média central da imagem, você pode descobrir se a imagem é uniforme, sem um tema ou sujeito central, como a foto de uma paisagem vazia.
Histograma - Correspondência Geral de Cores
Para uma métrica referente aos tipos de cores encontradas em uma imagem, usa-se um histograma de um tipo ou de outro. Isso é feito criando um array de 'compartimentos de cor' (bins) e incrementando a contagem de cada 'bin' à medida que as cores são encontradas. Ora, não dá para imaginar você armazenando um histograma grande para cada imagem! Então você armazenará apenas as cores mais predominantes do histograma, ou usará um número bem menor de bins (com mais pixels em cada bin). Um histograma comum de 'compartimentos de cor' não funciona muito bem. A razão é que cada cor sempre cairá em um único bin. Ou seja, cada pixel é adicionado a cada bin em uma base de tudo ou nada, sem qualquer consideração de quão perto essa cor está da borda de um bin. Isso, por sua vez, não gera uma boa métrica. Uma solução é criar um histograma com bins sobrepostos. Ou seja, cada cor (exceto talvez preto ou branco) cairá em dois bins de cor. Então, mais tarde, quando você comparar as imagens, uma cor próxima corresponderá a pelo menos um desses bins. Outra alternativa é criar o histograma fazendo cada cor contribuir para cada 'bin' de acordo com o quão próxima está do centro do bin. Ou seja, uma cor na borda de um bin de fato se distribuirá entre dois bins. Isso gerará uma espécie de histograma difuso, ou interpolado, mas que representaria uma imagem com mais precisão, especialmente quando apenas um número muito pequeno de 'bins' de cor é usado. Além disso, os histogramas são tradicionalmente ou apenas o componente em tons de cinza de uma imagem, ou três componentes RGB separados. Mas essa não é uma representação muito boa. Você poderia tentar, em vez disso, histogramas de Matiz, Saturação e Luminância para representar melhor a imagem. Alternativamente, por que se limitar a um histograma unidimensional? Que tal mapear as cores para um conjunto de cores reais por todo o espaço de cor! Ou seja, em vez de compartimentar apenas o valor 'vermelho', por que não contá-lo em um compartimento de cor tridimensional (em qualquer espaço de cor que funcione melhor). Isso geraria um histograma que realmente representaria as cores encontradas dentro de uma imagem. Tal métrica de histograma 3D poderia ser um simples array de, digamos, 8x8x8 ou 2048 bins. Ou seja, uma métrica de 2 Kbytes. Uma busca de cor então localizaria o número correto de bins próximos e obteria uma contagem interpolada dos bins vizinhos. O que representaria o número de cores 'próximas' daquela cor dentro da imagem!
Separação de Cores de Primeiro Plano/Fundo
Usando -colors, você pode tentar separar a imagem em partes de primeiro plano e de fundo, reduzindo a imagem a apenas duas cores. Usar primeiro um filtro -median removerá o efeito de detalhes menores, e das bordas de linhas e ruído que possam estar na imagem. É claro que isso não é muito bom para imagens majoritariamente brancas do tipo esboço.
magick rose: -median 5 +dither -colors 2 \
-depth 8 -format %c histogram:info:-
Isto mostra uma cor vermelha e uma cinza como as cores predominantes na imagem. Um recorte/corte para o centro da imagem deveria então determinar o que é primeiro plano e o que é fundo.
magick rose: -median 5 +dither -colors 2 \
-trim +repage -gravity center -crop 50% \
-depth 8 -format %c histogram:info:-
O que mostra que a cor vermelha da 'rose' é a cor predominante de primeiro plano. Note que uma imagem de paisagem pode se separar de forma diferente, resultando em uma cor inferior de terra e uma cor superior de céu. Assim, uma olhada aproximada em como as cores foram separadas pode ser muito útil para a determinação do tipo de imagem. Além disso, uma figura com algum 'spam' de texto muitas vezes mostrará uma mancha de cor em um canto que é bem mais proeminente que o resto da imagem. Se encontrada, refaça com 3 cores e então apague essa área com a 'cor de fundo' mais comum encontrada antes de fazer seu teste final. Esta técnica é provavelmente uma boa forma de separar imagens em classes como 'tom de pele', 'vegetação', 'paisagem', etc.
Matriz de Cores Média
Um esquema de cores em matriz três por três ("-scale 3x3\!") é um esquema de classificação de cores razoável. Ele separará e agrupará imagens semelhantes muito bem. Por exemplo, esboços (todos quase brancos), tons de cinza, paisagens, marinhas, salas, rostos, etc, serão todos separados em grupos básicos e semelhantes (em teoria). Esta também é uma métrica razoável para indexar imagens para gerar Mosaicos de Fotos. A saída do formato de imagem NetPBM é particularmente adequada para gerar tal métrica, pois pode gerar apenas os valores dos pixels como números em texto. Lembre-se de que isto produziria um resultado de 27 dimensões (3x3 cores de 3 valores), portanto um algoritmo de clustering multidimensional pode ser necessário. Você conhece um bom programa/algoritmo de clustering 3d? Por exemplo, aqui estão as 3 x 3 cores RGB (em profundidade 8) para o logotipo do IM.
magick logo: -scale 3x3\! -compress none -depth 8 ppm:- |\
sed '/^#/d' | tail -n +4
251 241 240 245 234 231 229 233 236 254 254 254
192 196 204 231 231 231 255 255 255 211 221 231
188 196 210
O exposto acima pode ser aprimorado usando valores de 16 bits e, possivelmente, recortando 10% das bordas para remover logotipo e lixo de moldura que possam ter sido adicionados...
magick logo: -gravity center -crop 80% -scale 3x3\! \
-compress none -depth 16 ppm:- | sed '/^#/d' | tail -n +4
63999 59442 58776 62326 58785 58178 51740 54203 54965 65277 65262 65166
45674 47023 49782 56375 55648 55601 65535 65535 65535 52406 55842 58941
44635 48423 52881
É claro que, como a métrica de cor média anterior, esta também terá problemas para casar imagens que foram modificadas em cor, como mudanças de matiz ou de brilho. (Veja a próxima seção) Além disso, esta métrica pode separar desenhos de linhas dentro de seu agrupamento, embora apenas de uma forma muito geral. Tais desenhos ainda serão agrupados mais pela cor do 'papel' de fundo do que pelo conteúdo, e geralmente precisam de um 'limiar' de similaridade menor do que as imagens coloridas.
Matriz de Diferença de Cores
O maior problema de usar as cores diretamente como métrica é que você vincula a imagem a uma cor geral específica. Isso significa que qualquer imagem que tenha tido o brilho aumentado ou reduzido, ou cujo matiz tenha sido alterado, não será agrupada junto. Uma solução para isso é, de alguma forma, subtrair a cor predominante ou média da imagem da métrica, e usar uma matriz de cores torna isso possível. Aqui, por exemplo, subtraio a cor média central de todas as cores ao redor na matriz.
magick logo: -gravity center -crop 80% -scale 3x3\! -fx '.5+u-p{1,1}' \
-compress none -depth 16 ppm:- | sed '/^#/d' | tail -n +4
51093 45187 41761 49419 44529 41163 38834 39947 37950 52371 51007 48152
32767 32767 32767 43469 41393 38587 52629 51279 48521 39500 41587 41926
31729 34168 35867
Note que adiciono .5 à diferença, pois não é possível salvar um valor de cor negativo em uma imagem. Além disso, o uso do lento operador "[-fx](https://imagemagick.org/command-line-options/#fx)" é aceitável, pois apenas 9 pixels são processados. Note que o pixel central ("32767 32767 32767" no início da segunda linha acima) não mudará muito (qualquer mudança se deve apenas a leves erros de arredondamento) e poderia ser removido do resultado, reduzindo a métrica a 24 dimensões (valores). Alternativamente, você pode subtrair a cor média da imagem de todos os 9 valores de cor.
magick logo: -scale 3x3\! \( +clone -scale 1x1 \) -fx '.5+u-v.p{0,0}' \
-compress none ppm:- | sed '/^#/d' | tail -n +4
38604 35917 34642 37011 33949 32441 32839 33841 33649 39447 39259 38369
23358 24377 25436 33538 33174 32426 39612 39434 38605 28225 30576 32319
22271 24381 27021
Isto também poderia ser feito pelo comparador de métricas, e não pelo gerador de métricas. A métrica ainda separa e agrupa imagens coloridas muito bem, colocando imagens semelhantes bem próximas, independentemente de quaisquer mudanças gerais de cor ou brilho. Ela ainda é sensível a mudanças de contraste, no entanto. Essa modificação de métrica poderia, de fato, ser feita durante o processo de comparação, de modo que uma Métrica de Matriz de Cores bruta ainda possa ser usada como uma métrica de imagem padrão a ser coletada, armazenada em cache e comparada. Isto é o que eu mesmo faço agora para comparações de imagens em larga escala. Ao contrário de uma média direta de cor, você pode usar esta métrica para diferenciar entre diferentes imagens de desenho de linhas. Contudo, como os desenhos de linhas usam uma escala de cor linear (todas as cores caem em uma linha no espaço de métricas), as diferenças entre as imagens são de cerca de 1/3 daquelas das imagens coloridas. Assim, um limiar bem diferente é necessário ao comparar desenhos de linhas. Ainda é melhor separar desenhos de linhas e imagens em tons de cinza das imagens coloridas. Em outras palavras, esta é uma das melhores métricas que já encontrei para imagens coloridas. Apenas certifique-se de determinar primeiro quais imagens são desenhos de linhas e compará-las separadamente usando um limiar bem menor. Felizmente para nós, a própria métrica pode ser usada para fazer a separação das imagens em tons de cinza ou imagem de cor linear. Sugestões são bem-vindas.
Diferença de Vizinhos
O exposto acima gera uma matriz 3x3, com o pixel central subtraído e todos os valores deslocados para um cinza perfeito. Contudo, um método melhor é, em vez de tentar salvar a cor de cada célula individual, gerar as diferenças entre cada célula e seus vizinhos (8 vizinhos). Ou seja, em vez de salvar a cor do canto superior esquerdo, salvar a diferença entre esse canto e o superior-central, o central e o esquerdo-central. É claro que, mesmo com um pequeno array 3x3, você acabará com uma assinatura contendo 12 diferenças, embora não precise codificar a diferença completa, apenas um nível de diferença geral, como igual, ou valores de diferença positiva/negativa grande/pequena. Isto tem uma probabilidade muito maior de encontrar imagens que correspondem, mesmo entre imagens que contêm cores muito diferentes, pois a cor real não desempenha nenhum papel na assinatura. A biblioteca de comparação de imagens 'libpuzzle' faz exatamente isso, embora use uma matriz 9x9, com apenas os pixels centrais de cada célula sendo calculados em média. Ela também se limita a versões em tons de cinza da imagem. A técnica é completamente definida em um artigo postscript, Image Signature for Any Kind of Image. O artigo também aborda métodos de armazenar essa assinatura em um banco de dados e como realmente realizar uma consulta para encontrar imagens com assinaturas semelhantes (não necessariamente iguais). É o primeiro artigo que descobri que de fato detalha como fazer isso. :-)
Hash Perceptual
Reduza a imagem para 8x8 e calcule uma intensidade média. Cada bit do hash de 64 bits é então 1 se o pixel estiver acima da média, ou 0 se estiver abaixo dela. Para comparar a similaridade entre duas imagens, você simplesmente compara os hashes bit a bit, retornando uma distância de Hamming. Quanto menor a distância de Hamming, mais semelhantes são as imagens. Qualquer valor acima de 21 / 64 é considerado não semelhante. O pHash parece usar codificação YCbCr. Há quem fale em trabalhar diretamente com a DCT do JPEG, e o mais promissor trabalha com a magnitude / fase e a mapeia para um sistema de coordenadas log-polar.
Correspondência de imagens com mais precisão
Notas e técnicas diversas que eu não experimentei ou que não funcionaram muito bem para comparar imagens maiores em busca de uma correspondência de imagem mais exata.
Cor de Segmentação
Como se pode ver, muitas das métricas acima usam um filtro de desfoque/mediana seguido de técnicas de redução de cores como tentativas básicas de simplificar imagens para permitir que sejam melhor classificadas. Contudo, o Operador de Quantização de Cor não é realmente projetado para esse propósito. Seu trabalho é reduzir as cores de modo a destacar os detalhes importantes da imagem. Para a comparação de imagens, porém, não queremos realmente destacar esses detalhes, mas sim destacar áreas de interesse comparativo. Este é o trabalho de uma técnica de cor relacionada conhecida como segmentação... OBSERVAÇÃO: da Leptonica: a segmentação de imagem é a divisão da imagem em regiões que têm propriedades diferentes. Este operador bloqueia áreas de cores semelhantes, removendo o detalhe dessas áreas. Então, quando você compara as duas imagens, está comparando áreas em vez de detalhes de baixo nível nas imagens. O IM implementa um algoritmo de segmentação, "[-segment](https://imagemagick.org/command-line-options/#segment)"; para detalhes de sua implementação, veja SegmentImage(). Exemplo:
magick logo: -median 10 -segment 1x1 \
+dither -scale 100x100\! segment_image.gif
Um problema é que o -segment é MUITO lento e só parece funcionar para imagens maiores. Imagens pequenas (como uma rose: ou um logo: escalado para 100x100) parecem resultar apenas em uma única cor sendo produzida. Isto pode ser um bug. É claro que você ainda pode escalar a imagem após segmentá-la, como fizemos acima. Dessa forma, você pode armazenar em memória um número maior de imagens para comparar entre si. Além disso, a segmentação resultante não parece funcionar muito bem, quando comparada ao algoritmo de segmentação de imagem que a Leptonica fornece. Veja Leptonica: Color Segmentation. Contudo, uma alternativa à segmentação do IM é fazer um uso indevido da função de quantização de cor para encontrar áreas de cor semelhante. Exemplo:
magick logo: -scale 100x100\! -median 3 \
-quantize YIQ +dither -colors 3 segment_image.gif
A desvantagem é que o -color limita o número de áreas de cor que podem estar presentes em uma imagem, enquanto o segment tenta preservar áreas semelhantes, independentemente de quantas áreas realmente estejam presentes na imagem (ou pelo menos é o que deveria fazer).
Comparação de Bordas sem Cor
A cor da imagem é notoriamente pouco confiável, particularmente para imagens do tipo desenho animado. Diferentes usuários poderiam facilmente recolorir tais imagens, adicionar fundos de cores diferentes, ou até pegar um esboço e colori-lo. Uma forma de casar tais imagens é fazer alguma redução básica de cor, como no método acima, mas então, em vez de comparar imagens com base na cor resultante, você realiza uma detecção de bordas e processamento adicional, de modo que apenas os contornos das mudanças de cor mais importantes sejam usados para as métricas e a comparação das imagens. Por exemplo...
magick logo: -scale 100x100\! -median 3 \
-quantize YIQ +dither -colors 3 -edge 1 \
-colorspace gray -blur 0x1 outline_image.gif
Uma alternativa pode ser usar o -lat (Local Area Threshold, limiar de área local) para detecção de bordas, o que pode lhe dar um controle melhor...
magick logo: -scale 100x100\! -median 3 \
-quantize YIQ +dither -colors 3 \
-lat 3x3-5% -negate \
-colorspace gray -blur 0x1 outline_image.gif
É claro que, para comparar, você usaria um método de comparação de desenho de linhas.
??? como você compararia desenhos de linhas de uma forma viável ???
Multiplique as imagens e veja se a imagem resultante aumentou ou reduziu a intensidade das linhas. Linhas que não correspondem se tornarão pretas.
Web Cameras
O que mudou em câmeras fixas
Em Construção
Walter Perry
![[IM Output]](../static/img/images/bag_frame1.gif)
![[IM Output]](../static/img/images/bag_frame2.gif)
![[IM Output]](../static/img/compare/compare.gif)
![[IM Output]](../static/img/compare/bag_frame1.jpg)
![[IM Output]](../static/img/compare/compare_lossy_jpeg.gif)
![[IM Text]](../static/img/compare/compare_fuzz.txt.gif)
![[IM Text]](../static/img/compare/greyscale_test.txt.gif)