Tengo dos imágenes diferentes:
y
Como puede ver, los dos son claramente "iguales" desde el punto de vista humano. Ahora quiero detectar programáticamente que son lo mismo. He estado usando magia de imágenes a través de la gema de rubí llamada rmagick
así:
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
Si bien esto funciona bien para imágenes que tienen la misma relación / recorte, no es ideal cuando tienen un recorte ligeramente diferente y se ha redimensionado al mismo ancho.
¿Hay alguna manera de hacerlo para imágenes con diferentes recortes? Estoy interesado en una solución en la que pueda decir algo como: una imagen está contenida dentro de la otra y cubre en algún lugar, por ejemplo, el 90% de la misma.
PD. Puedo obtener las imágenes en mayor resolución si eso ayuda (por ejemplo, el doble)
fuente
compare
herramienta de línea de comandos de ImageMagick tiene un-subimage-search
interruptor.Respuestas:
Es posible que desee echar un vistazo a la coincidencia de características. La idea es encontrar características en dos imágenes y combinarlas. Este método se usa comúnmente para encontrar una plantilla (por ejemplo, un logotipo) en otra imagen. Una característica, en esencia, puede describirse como cosas que los humanos encontrarían interesantes en una imagen, como esquinas o espacios abiertos. Existen muchos tipos de técnicas de detección de características, sin embargo, mi recomendación es utilizar una transformación de características invariantes de escala (SIFT) como algoritmo de detección de características. SIFT es invariante para la traducción de imágenes, escalado, rotación, parcialmente invariable para los cambios de iluminación y robusto para la distorsión geométrica local. Esto parece coincidir con su especificación donde las imágenes pueden tener proporciones ligeramente diferentes.
Dadas sus dos imágenes proporcionadas, aquí hay un intento de hacer coincidir las características utilizando el comparador de características de FLANN . Para determinar si las dos imágenes son iguales, podemos basarlo en un umbral predeterminado que rastrea el número de coincidencias que pasan la prueba de relación descrita en Características de imagen distintivas de puntos clave invariables a escala por David G. Lowe . Una explicación simple de la prueba es que la prueba de proporción verifica si las coincidencias son ambiguas y deben eliminarse, puede tratarse como una técnica de eliminación atípica. Podemos contar el número de coincidencias que pasan esta prueba para determinar si las dos imágenes son iguales. Aquí están los resultados de coincidencia de características:
Los puntos representan todas las coincidencias detectadas, mientras que las líneas verdes representan las "coincidencias buenas" que pasan la prueba de relación. Si no utiliza la prueba de razón, se dibujarán todos los puntos. De esta manera, puede usar este filtro como umbral para mantener solo las mejores características coincidentes.
Lo implementé en Python, no estoy muy familiarizado con Rails. Espero que esto ayude, buena suerte!
Código
fuente
Debido a que ImageMagick es una herramienta muy antigua, avanzada y con muchas funciones, sería difícil construir una interfaz que cubra la mayoría de las funciones. Por grandioso que sea, rmagick no (y tampoco los muchos intentos que ha hecho Python) se acerca a cubrir todas las características.
Me imagino que para muchos casos de uso, será lo suficientemente seguro y mucho más fácil simplemente ejecutar un método de línea de comando y leerlo. En rubí se verá así;
Cubriré cosas importantes y luego hablaré sobre notas adicionales.
El comando usa magick compare para verificar si la segunda imagen (
small
) es una subimagen de la primera (large
). Esta función no comprueba que pequeño es estrictamente más pequeño que grande (altura y anchura). El número que puse para la similitud es 0.2 (error del 20%), y el valor de las imágenes que proporcionó es de aproximadamente 0.15. Es posible que desee afinar esto! Encuentro que las imágenes que son un subconjunto estricto obtienen menos de 0.01.stderr
ystdout
no es "necesario" pero se supone que debes hacerlo.fuente
Obtenga el histograma de ambas imágenes y compárelas. Esto funcionaría muy bien para recortar y Zoom a menos que haya un cambio demasiado drástico debido a esto.
Esto es mejor que el enfoque actual en el que está restando directamente las imágenes. Pero este enfoque todavía tiene pocos.
fuente
Por lo general, la coincidencia de plantillas tiene un buen resultado en estas situaciones. La coincidencia de plantillas es una técnica para encontrar áreas de una imagen que coinciden (son similares) a una imagen de plantilla (segunda imagen). Este algoritmo proporciona una puntuación para la mejor posición macthed en la imagen de origen (la segunda).
En opencv usando TM_CCOEFF_NORMED método , da el puntaje entre 0 y 1. Si el puntaje es 1, eso significa que la imagen de la plantilla es exactamente una parte (Rect) de la imagen de origen, pero si tiene un pequeño cambio en la iluminación o la perspectiva entre Las dos imágenes, la puntuación sería inferior a 1.
Ahora, al considerar un umbral para el puntaje de similitud, puede averiguar si son iguales o no. Ese umbral se puede obtener mediante alguna prueba y error en algunas imágenes de muestra. Probé sus imágenes y obtuve el puntaje 0.823863 . Aquí está el código (opencv C ++) y el área común entre las dos imágenes, obtenidas por la coincidencia:
fuente
Considere el método find_similar_region . Use la menor de las dos imágenes como imagen de destino. Pruebe varios valores para los atributos de fuzz en la imagen y la imagen de destino.
fuente