.net - recomendado - Compara imágenes para encontrar diferencias
tamaño imagen destacada wordpress (6)
No conozco los detalles, pero sí sé que en situaciones industriales donde es esencial un alto rendimiento, a veces esto se hace usando redes neuronales. Convierten millones de bits (píxeles de cámara) en 1 (bueno o malo). Quizás esto te ayude en tu búsqueda.
Tarea: tengo una cámara montada al final de nuestra línea de ensamblaje, que captura imágenes de artículos producidos. Digamos, por ejemplo, que producimos boletos (con texto e imágenes). Entonces, cada boleto producido es fotografiado y guardado en el disco como imagen. Ahora me gustaría comprobar estas imágenes guardadas en busca de anomalías (es decir, compararlas con una imagen (una plantilla), lo cual está bien). Entonces, si hay un problema con un ticket en nuestra línea de ensamblaje (falta una imagen, una mancha, ...), mi aplicación debería encontrarlo (porque su imagen difiere demasiado de mi plantilla).
Pregunta: ¿Cuál es la forma más fácil de comparar imágenes y encontrar diferencias entre ellas? ¿Debo escribir mis propios métodos o puedo usar los existentes? Sería genial si solo establezco un valor de tolerancia (es decir, las imágenes pueden diferir en un 1%), pongo ambas imágenes en una función y obtengo un valor de retorno de verdadero o falso :)
Herramientas: C # o VB.NET, Emgu.CV (.NET wrapper para OpenCV) o algo similar
No soy el experto en el campo, pero parece que necesitas algo como esto
http://en.wikipedia.org/wiki/Template_matching
Y parece que OpenCV tiene soporte para la coincidencia de plantillas
http://nashruddin.com/template-matching-in-opencv-with-example.html
Seguramente hay aplicaciones y bibliotecas que ya hacen lo que estás intentando hacer, pero no sé de ninguna manera. Obviamente, uno podría comparar las dos imágenes y compararlas, pero eso espera que las cosas sean idénticas y no deja margen para diferencias de luz o cosas por el estilo.
Suponiendo que haya controlado los objetos en las imágenes orientadas de manera idéntica y colocadas de forma idéntica, una cosa que podría hacer es marchar a través de los píxeles de cada imagen, y obtener los valores HSV de cada uno así:
Color color1 = Image1.GetPixel(i,j);
Color color2 = Image2.GetPIxel(i,j);
float hue1 = color1.GetHue();
float sat1 = color1.GetSaturation();
float bright1 = color1.GetBrightness();
float hue2 = color2.GetHue();
float sat2 = color2.GetSaturation();
float bright2 = color2.GetBrightness();
y hacer algunas comparaciones con esos valores. Eso me permitiría compararlos, creo, con más fiabilidad que con los valores RGB, sobre todo porque quiere incluir algunas tolerancias en su comparación.
Editar:
Solo por diversión, escribí una pequeña aplicación de muestra que utilizó mi idea anterior. Esencialmente ascendió el número de píxeles cuyos valores H, S y V diferían en cierta cantidad (elegí 0.1 como mi valor) y luego abandonó los bucles de comparación si los contadores H, S o V superan 38400 o 2% de los píxeles (0.02 * 1600 * 1200). En el peor de los casos, tomó aproximadamente 2 segundos comparar dos imágenes idénticas. Cuando comparé las imágenes donde una de ellas había sido alterada lo suficiente como para exceder ese valor del 2%, generalmente tomaba una fracción de segundo.
Obviamente, esto probablemente sería demasiado lento si se produjeran muchas imágenes por segundo, pero de todos modos pensé que era interesante.
No sé mucho sobre OpenCV, pero un poco sobre el procesamiento de imágenes.
El camino a seguir depende de la frecuencia en que se toman las imágenes nuevas. Un enfoque simplista sería calcular una imagen diferente de su plantilla ''buena'' y la imagen de su producto real.
Si las imágenes son 100% idénticas, la imagen resultante debe estar vacía. Si hay píxeles residuales, puede contarlos y tomarlos como una medida de desviación de la norma.
Sin embargo, deberá coincidir con la orientación (y probablemente la escala) de una de las imágenes para alinear los bordes, de lo contrario, este enfoque no funcionará.
Si tiene limitaciones de timn, es posible que desee reducir la información en sus imágenes antes de procesarlas (utilizando, por ejemplo, una detección de bordes y / o convertirlos a escala de grises o incluso mapa de bits monocromático si las características de su producto son lo suficientemente importantes)
Recomiendo mirar la biblioteca AForge Imaging ya que tiene muchas funciones realmente útiles para este tipo de trabajo.
Hay varios métodos que podrías usar:
- Sustracción simple (imagen de plantilla - actual) y ver cuántos píxeles son diferentes. Probablemente desee establecer el umbral de los resultados, es decir, solo incluir píxeles que sean diferentes por 10 o más (por ejemplo).
- Si los boletos se pueden mover en el campo de vista, entonces el artículo 1) no funcionará a menos que primero pueda ubicar el boleto. Si, por ejemplo, el boleto es blanco sobre un fondo negro, podría hacer un umbral en la imagen y eso le daría una buena idea de dónde estaba el boleto.
- Otra técnica que he usado anteriormente es "Búsqueda de modelos" o "Coincidencia de patrones", pero solo conozco una biblioteca comercial de la Biblioteca de imágenes Matrox (o MIL) que contiene estas funciones, ya que no son triviales.
También debe asegurarse de saber qué partes del ticket son más importantes. Por ejemplo, supongo que un logotipo o marca de agua faltante es un gran problema. Pero algunas áreas pueden tener texto variable, como un número de serie, por lo que es de esperar que sean diferentes. Básicamente, es posible que deba tratar algunas áreas de la imagen de manera diferente a los demás.
Este tipo aquí escribió un código Java simple para el mismo problema. No será difícil convertirlo en C #, supongo. Está funcionando bien, también se puede encontrar una versión más nueva y más fuerte.