Eu tenho duas imagens diferentes:
e
na largura de 100 px ou 400 px
Como você pode ver, os dois são claramente os "mesmos" do ponto de vista humano. Agora eu quero detectar programaticamente que eles são os mesmos. Eu tenho usado magia de imagem através da gema de rubi chamada rmagick
assim:
img1 = Magick::Image.from_blob(File.read("image_1.jpeg")).first
img2 = Magick::Image.from_blob(File.read("image_2.jpeg")).first
if img1.difference(img2).first < 4000.0 # I have found this to be a good threshold, but does not work for cropped images
puts "they are the same!!!"
end
Embora isso funcione bem para imagens com a mesma proporção / corte, não é ideal quando elas têm cortes ligeiramente diferentes e foram redimensionadas para a mesma largura.
Existe uma maneira de fazer isso com imagens com cortes diferentes? Estou interessado em uma solução em que posso dizer algo como: Uma imagem está contida na outra e cobre algo em torno de, por exemplo, 90% dela.
PS. Posso obter as imagens em alta resolução, se isso ajudar (por exemplo, o dobro)
fonte
compare
ferramenta de linha de comando do ImageMagick possui uma-subimage-search
opção.Respostas:
Você pode dar uma olhada na correspondência de recursos. A idéia é encontrar recursos em duas imagens e combiná-los. Esse método é comumente usado para encontrar um modelo (por exemplo, um logotipo) em outra imagem. Um recurso, em essência, pode ser descrito como coisas que os humanos considerariam interessantes em uma imagem, como cantos ou espaços abertos. Existem muitos tipos de técnicas de detecção de recursos por aí, no entanto, minha recomendação é usar uma transformação de recurso invariável em escala (SIFT) como um algoritmo de detecção de recursos. O SIFT é invariável à conversão, redimensionamento, rotação da imagem, parcialmente invariável às mudanças de iluminação e robusto à distorção geométrica local. Isso parece corresponder à sua especificação, onde as imagens podem ter proporções ligeiramente diferentes.
Dadas as duas imagens fornecidas, aqui está uma tentativa de combinar os recursos usando o combinador de recursos da FLANN . Para determinar se as duas imagens são iguais, podemos basear algum limiar predeterminado que rastreia o número de correspondências que passam no teste de proporção descrito em Recursos de imagem distintiva de pontos-chave invariantes em escala por David G. Lowe . Uma explicação simples do teste é que o teste de proporção verifica se as correspondências são ambíguas e devem ser removidas; você pode tratá-lo como uma técnica de remoção externa. Podemos contar o número de correspondências que passam neste teste para determinar se as duas imagens são iguais. Aqui estão os resultados da correspondência de recursos:
Os pontos representam todas as correspondências detectadas, enquanto as linhas verdes representam as "boas correspondências" que passam no teste de proporção. Se você não usar o teste de proporção, todos os pontos serão sorteados. Dessa forma, você pode usar esse filtro como limite para manter apenas os melhores recursos correspondentes.
Eu o implementei em Python, não estou muito familiarizado com o Rails. Espero que isso ajude, boa sorte!
Código
fonte
Como o ImageMagick é muito antigo, avançado e uma ferramenta com muitos recursos, seria difícil criar uma interface que cubra a maioria dos recursos. Por melhor que seja, o rmagick não chega nem perto de cobrir todos os recursos.
Eu imagino que, para muitos casos de uso, será seguro o suficiente e muito mais fácil simplesmente executar um método de linha de comando e ler a partir dele. Em rubi, será assim;
Vou cobrir coisas importantes e depois falar sobre anotações adicionais.
O comando usa magick compare para verificar se a segunda imagem (
small
) é uma sub-imagem da primeira (large
). Esta função não verifica se pequeno é estritamente menor que grande (altura e largura). O número que coloquei para a semelhança é 0,2 (erro de 20%) e o valor para as imagens que você forneceu é de cerca de 0,15. Você pode ajustar isso! Acho que as imagens que são um subconjunto estrito recebem menos de 0,01.stderr
estdout
não é "necessário", mas você deveria.fonte
Obtenha o histograma das duas imagens e compare-as. Isso funcionaria muito bem para o corte e o zoom, a menos que haja uma alteração muito drástica por causa disso.
Isso é melhor do que a abordagem atual em que você está subtraindo diretamente as imagens. Mas essa abordagem ainda tem poucas.
fonte
Normalmente, a correspondência de modelos tem um bom resultado nessas situações. A correspondência de modelo é uma técnica para encontrar áreas de uma imagem que correspondem (são semelhantes) a uma imagem de modelo (segunda imagem). Esse algoritmo fornece uma pontuação para a melhor posição destacada na imagem de origem (a segunda).
No opencv, usando o método TM_CCOEFF_NORMED , fornece a pontuação entre 0 e 1. Se a pontuação for 1, significa que a imagem do modelo é exatamente uma parte (Rect) da imagem de origem, mas se houver uma pequena alteração no raio ou na perspectiva entre nas duas imagens, a pontuação seria menor que 1.
Agora, considerando um limite para a pontuação de similaridade, você pode descobrir se são iguais ou não. Esse limite pode ser obtido por tentativa e erro em algumas imagens de amostra. Eu tentei suas imagens e obtive a pontuação 0.823863 . Aqui está o código (opencv C ++) e a área comum entre as duas imagens, obtida pela correspondência:
fonte
Considere o método find_similar_region . Use a menor das duas imagens como imagem de destino. Tente vários valores para os atributos de fuzz na imagem e na imagem de destino.
fonte