[c++] Procesamiento de imágenes: mejora de algoritmos para el reconocimiento de 'Coca-Cola Can'



11 Answers

Para acelerar las cosas, me gustaría aprovechar el hecho de que no se le pide que encuentre una imagen / objeto arbitrario, sino específicamente uno con el logotipo de Coca-Cola. Esto es significativo porque este logotipo es muy distintivo, y debe tener una firma invariante de escala característica en el dominio de frecuencia, particularmente en el canal rojo de RGB. Es decir, el patrón alterno de rojo a blanco a rojo que se encuentra en una línea de escaneo horizontal (entrenado en un logotipo alineado horizontalmente) tendrá un "ritmo" distintivo a medida que pasa por el eje central del logotipo. Ese ritmo se "acelerará" o "disminuirá" a diferentes escalas y orientaciones, pero seguirá siendo proporcionalmente equivalente. Podrías identificar / definir unas pocas docenas de líneas de exploración, tanto horizontal como verticalmente a través del logotipo y varias más diagonalmente, en un patrón estelar. Llámalos las "líneas de escaneo de firmas".

La búsqueda de esta firma en la imagen de destino es una simple cuestión de escanear la imagen en franjas horizontales. Busque una frecuencia alta en el canal rojo (que indica pasar de una región roja a una blanca), y una vez que la encuentre, vea si está seguida de uno de los ritmos de frecuencia identificados en la sesión de entrenamiento. Una vez que encuentre una coincidencia, sabrá instantáneamente la orientación y la ubicación de la línea de escaneo en el logotipo (si realiza un seguimiento de esas cosas durante el entrenamiento), por lo que es trivial identificar los límites del logotipo desde allí.

Me sorprendería que este no fuera un algoritmo de eficacia lineal, o casi. Obviamente, no aborda su discriminación de botella, pero al menos tendrá su logotipo.

(Actualización: para el reconocimiento de la botella, buscaría coque (el líquido marrón) adyacente al logotipo, es decir, dentro de la botella. O, en el caso de una botella vacía, buscaría una tapa que siempre tendrá el La forma, el tamaño y la distancia básicos del logotipo son típicamente blancos o rojos. Busque una forma elíptica de color sólido donde debe haber una tapa, en relación con el logotipo. No es infalible, por supuesto, pero su objetivo aquí debería ser encuentre los fáciles rápidamente ).

(Han pasado algunos años desde mis días de procesamiento de imágenes, así que guardé esta sugerencia de alto nivel y conceptual. Creo que podría aproximarse ligeramente a cómo funcionaría un ojo humano, ¡o al menos cómo funciona mi cerebro!)

Question

Uno de los proyectos más interesantes en los que he trabajado en los últimos años fue un proyecto sobre procesamiento de imágenes . El objetivo era desarrollar un sistema para poder reconocer las 'latas' de Coca-Cola (tenga en cuenta que estoy insistiendo en la palabra 'latas', verá por qué en un minuto). Puede ver una muestra a continuación, con la lata reconocida en el rectángulo verde con escala y rotación.

Algunas limitaciones en el proyecto:

  • El fondo puede ser muy ruidoso.
  • La lata puede tener cualquier escala o rotación o incluso orientación (dentro de límites razonables).
  • La imagen podría tener cierto grado de borrosidad (los contornos podrían no ser completamente rectos).
  • ¡Podría haber botellas de Coca-Cola en la imagen, y el algoritmo solo debería detectar la lata !
  • El brillo de la imagen puede variar mucho (por lo que no puede confiar "demasiado" en la detección del color).
  • La lata puede estar parcialmente oculta a los lados o en el medio y posiblemente parcialmente escondida detrás de una botella.
  • No podría haber nada en absoluto en la imagen, en cuyo caso no tenía que encontrar nada y escribir un mensaje diciéndolo.

Entonces podrías terminar con cosas complicadas como esta (que en este caso mi algoritmo falló totalmente):

Hice este proyecto hace un tiempo, y me divertí mucho haciéndolo, y tuve una implementación decente. Aquí hay algunos detalles sobre mi implementación:

Idioma : hecho en C ++ usando la biblioteca OpenCV .

Preprocesamiento : para el procesamiento previo de la imagen, es decir, la transformación de la imagen en una forma más cruda para dar al algoritmo, utilicé 2 métodos:

  1. Cambiar el dominio de color de RGB a HSV y filtrar según el tono "rojo", la saturación por encima de un cierto umbral para evitar colores similares a los de la naranja y el filtrado de bajo valor para evitar los tonos oscuros. El resultado final fue una imagen binaria en blanco y negro, donde todos los píxeles blancos representarían los píxeles que coinciden con este umbral. Obviamente, todavía hay mucha basura en la imagen, pero esto reduce la cantidad de dimensiones con las que debe trabajar.
  2. Filtrado de ruido utilizando filtrado mediano (tomando el valor medio de píxeles de todos los vecinos y reemplazando el píxel por este valor) para reducir el ruido.
  3. Usando Canny Edge Detection Filter para obtener los contornos de todos los elementos después de 2 pasos precedentes.

Algoritmo : El algoritmo que elegí para esta tarea fue tomado de this impresionante libro sobre extracción de características y llamado Generalized Hough Transform (bastante diferente de la Transformada Hough normal). Básicamente dice algunas cosas:

  • Puede describir un objeto en el espacio sin conocer su ecuación analítica (que es el caso aquí).
  • Es resistente a las deformaciones de la imagen, como la escala y la rotación, ya que básicamente probará su imagen para cada combinación de factor de escala y factor de rotación.
  • Utiliza un modelo base (una plantilla) que el algoritmo "aprenderá".
  • Cada píxel restante en la imagen de contorno votará por otro píxel que supuestamente será el centro (en términos de gravedad) de su objeto, en función de lo que aprendió del modelo.

Al final, terminas con un mapa de calor de los votos, por ejemplo, aquí todos los píxeles del contorno de la lata votarán por su centro gravitatorio, por lo que tendrás muchos votos en el mismo píxel correspondiente al centro, y verá un pico en el mapa de calor como se muestra a continuación:

Una vez que tenga eso, una simple heurística basada en umbrales puede darle la ubicación del píxel central, desde la cual puede derivar la escala y la rotación y luego trazar su pequeño rectángulo a su alrededor (la escala final y el factor de rotación obviamente serán relativos a su plantilla original). En teoría, al menos ...

Resultados : ahora, aunque este enfoque funcionó en los casos básicos, en algunas áreas faltaba mucho:

  • ¡Es extremadamente lento ! No estoy enfatizando esto lo suficiente. Se necesitó casi un día completo para procesar las 30 imágenes de prueba, obviamente porque tenía un factor de escala muy alto para la rotación y la traducción, ya que algunas de las latas eran muy pequeñas.
  • Se perdió por completo cuando las botellas estaban en la imagen, y por alguna razón casi siempre se encontró la botella en lugar de la lata (tal vez porque las botellas eran más grandes, por lo tanto tenían más píxeles, por lo tanto, más votos)
  • Las imágenes borrosas tampoco fueron buenas, ya que los votos terminaron en píxeles en ubicaciones aleatorias alrededor del centro, terminando con un mapa de calor muy ruidoso.
  • Se logró una variación en la traducción y la rotación, pero no en la orientación, lo que significa que no se reconoció una lata que no se enfrentaba directamente al objetivo de la cámara.

¿Puede ayudarme a mejorar mi algoritmo específico , utilizando exclusivamente las características de OpenCV , para resolver los cuatro problemas específicos mencionados?

Espero que algunas personas también aprendan algo al respecto, después de todo, creo que no solo las personas que hacen preguntas deben aprender. :)




If you are interested in it being realtime, then what you need is to add in a pre-processing filter to determine what gets scanned with the heavy-duty stuff. A good fast, very real time, pre-processing filter that will allow you to scan things that are more likely to be a coca-cola can than not before moving onto more iffy things is something like this: search the image for the biggest patches of color that are a certain tolerance away from the sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) of your coca-cola can. Start with a very strict color tolerance, and work your way down to more lenient color tolerances. Then, when your robot runs out of an allotted time to process the current frame, it uses the currently found bottles for your purposes. Please note that you will have to tweak the RGB colors in the sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) to get them just right.

Also, this is gona seem really dumb, but did you make sure to turn on -oFast compiler optimizations when you compiled your C code?




¿No es difícil incluso para los humanos distinguir entre una botella y una lata en la segunda imagen (siempre que la región transparente de la botella esté oculta)?

Son casi iguales a excepción de una región muy pequeña (es decir, el ancho en la parte superior de la lata es un poco pequeño, mientras que la envoltura de la botella tiene el mismo ancho, pero es un cambio menor ¿no?).

Lo primero que se me vino a la mente fue buscar la tapa roja de la botella. Pero sigue siendo un problema, si no hay una tapa para la botella, o si está parcialmente oculta (como se mencionó anteriormente).

Lo segundo que pensé fue sobre la transparencia de la botella. OpenCV tiene algunos trabajos para encontrar objetos transparentes en una imagen. Verifique los enlaces a continuación.

En particular, mire esto para ver con qué precisión detectan el vidrio:

Ver su resultado de implementación:

Dicen que es la implementación del documento "A Geodesic Active Contour Framework for Finding Glass" by K. McHenry and J. Ponce, CVPR 2006. . (Descargar el documento) .

Puede ser útil en su caso un poco, pero el problema surge nuevamente si se llena la botella.

Así que creo que aquí, puedes buscar el cuerpo transparente de las botellas primero o para una región roja conectada lateralmente a dos objetos transparentes que obviamente es la botella. (Cuando se trabaja idealmente, una imagen de la siguiente manera).

Ahora puede eliminar la región amarilla, es decir, la etiqueta de la botella y ejecutar su algoritmo para encontrar la lata.

De todos modos, esta solución también tiene problemas diferentes, como en las otras soluciones.

  1. Funciona solo si su botella está vacía. En ese caso, tendrá que buscar la región roja entre los dos colores negros (si el líquido de Coca Cola es negro).
  2. Otro problema si la parte transparente está cubierta.

Pero de todos modos, si no hay ninguno de los problemas anteriores en las imágenes, esto parece ser una mejor manera.




Hay muchos descriptores de color que se usan para reconocer objetos, el siguiente documento compara muchos de ellos. Son especialmente potentes cuando se combinan con SIFT o SURF. SURF o SIFT por sí solos no son muy útiles en una imagen de lata de coca-cola porque no reconocen muchos puntos de interés, se necesita la información del color para ayudar. Utilizo BIC (Clasi fi cación de píxeles fronterizos / interiores) con SURF en un proyecto y funcionó muy bien para reconocer objetos.

Descriptores de color para la recuperación de imágenes web: un estudio comparativo




Si no está limitado a una cámara que no estaba en una de sus limitaciones, quizás pueda pasar a usar un sensor de rango como Xbox Kinect . Con esto puede realizar una segmentación de profundidad de la imagen basada en la profundidad y el color. Esto permite una separación más rápida de objetos en la imagen. Luego puede usar igualación ICP o técnicas similares para igualar la forma de la lata en lugar de solo su contorno o color, y dado que es cilíndrica, esta puede ser una opción válida para cualquier orientación si tiene un escaneo 3D previo del objetivo. Estas técnicas a menudo son bastante rápidas, especialmente cuando se usan para un propósito específico que debería resolver su problema de velocidad.

También podría sugerir, no necesariamente por exactitud o velocidad, pero para divertirse, podría usar una red neuronal entrenada en su imagen segmentada de tono para identificar la forma de la lata. Estos son muy rápidos y a menudo pueden tener hasta 80/90% de precisión. El entrenamiento sería un proceso un poco largo, ya que tendría que identificar manualmente la lata en cada imagen.




Necesita un programa que aprenda y mejore la precisión de la clasificación de forma orgánica a partir de la experiencia.

Sugeriré el aprendizaje profundo, con el aprendizaje profundo esto se convierte en un problema trivial.

Puede volver a entrenar el modelo v3 de inicio en Tensorflow:

Cómo reciclar la capa final de Inception para nuevas categorías .

En este caso, entrenarás una red neuronal convolucional para clasificar un objeto como una lata de coca-cola o no.




No estoy al tanto de OpenCV, pero mirando lógicamente el problema, creo que se puede diferenciar entre botella y lata cambiando la imagen que está buscando, es decir, Coca Cola. Debes incorporar hasta la parte superior de la lata, ya que en el caso de la lata hay un forro plateado en la parte superior de la coca cola y en el caso de la botella no habrá un revestimiento plateado.

Pero, obviamente, este algoritmo fallará en los casos en que la parte superior de la lata esté oculta, pero en ese caso, incluso el ser humano no podrá diferenciar entre los dos (si solo es visible la porción de coca cola de la lata / botella)




Esta puede ser una idea muy ingenua (o puede que no funcione en absoluto), pero las dimensiones de todas las latas de coque son fijas. Entonces, si la misma imagen contiene tanto una lata como una botella, entonces puede distinguirlas por consideraciones de tamaño (las botellas serán más grandes). Ahora, debido a la falta de profundidad (es decir, mapeo 3D a mapeo 2D) es posible que una botella pueda aparecer reducida y no haya una diferencia de tamaño. Puede recuperar algo de información de profundidad utilizando stereo-imaging y luego recuperar el tamaño original.




Mirando la forma

Eche un vistazo a la forma de la porción roja de la lata / botella. Observe cómo la lata se estrecha ligeramente en la parte superior, mientras que la etiqueta de la botella es recta. Puede distinguir entre estos dos comparando el ancho de la porción roja a lo largo de él.

Mirando los aspectos más destacados

Una forma de distinguir entre botellas y latas es el material. Una botella está hecha de plástico, mientras que una lata está hecha de aluminio. En situaciones suficientemente iluminadas, observar la especularidad sería una forma de distinguir una etiqueta de botella de una etiqueta de lata.

Por lo que puedo decir, así es como un humano diría la diferencia entre los dos tipos de etiquetas. Si las condiciones de iluminación son deficientes, es probable que exista cierta incertidumbre al distinguir las dos de todas formas. En ese caso, debería ser capaz de detectar la presencia de la botella transparente / translúcida.




Como alternativa a todas estas agradables soluciones, puede entrenar su propio clasificador y hacer que su aplicación sea robusta ante los errores. Como ejemplo, puede usar Haar Training , que proporciona una buena cantidad de imágenes positivas y negativas de su objetivo.

Puede ser útil extraer solo latas y se puede combinar con la detección de objetos transparentes.




Llevo unos años tarde respondiendo esta pregunta. Con el estado del arte llevado al límite por las CNN en los últimos 5 años, ¡no usaría OpenCV para hacer esta tarea ahora! ( Sé que específicamente querías las características de OpenCv en la pregunta ) Siento que los algoritmos de detección de objetos, como RCNN más rápidos, YOLO, SSD, etc. podrían resolver este problema con un margen significativo en comparación con las características de OpenCV. Si tuviera que abordar este problema ahora (¡después de 6 años!) Definitivamente usaría Faster-RCNN .




The first things I would look for are color - like RED , when doing Red eye detection in an image - there is a certain color range to detect , some characteristics about it considering the surrounding area and such as distance apart from the other eye if it is indeed visible in the image.

1: First characteristic is color and Red is very dominant. After detecting the Coca Cola Red there are several items of interest 1A: How big is this red area (is it of sufficient quantity to make a determination of a true can or not - 10 pixels is probably not enough), 1B: Does it contain the color of the Label - "Coca-Cola" or wave. 1B1: Is there enough to consider a high probability that it is a label.

Item 1 is kind of a short cut - pre-process if that doe snot exist in the image - move on.

So if that is the case I can then utilize that segment of my image and start looking more zoom out of the area in question a little bit - basically look at the surrounding region / edges...

2: Given the above image area ID'd in 1 - verify the surrounding points [edges] of the item in question. A: Is there what appears to be a can top or bottom - silver? B: A bottle might appear transparent , but so might a glass table - so is there a glass table/shelf or a transparent area - if so there are multiple possible out comes. A Bottle MIGHT have a red cap, it might not, but it should have either the shape of the bottle top / thread screws, or a cap. C: Even if this fails A and B it still can be a can - partial.. This is more complex when it is partial because a partial bottle / partial can might look the same , so some more processing of measurement of the Red region edge to edge.. small bottle might be similar in size ..

3: Después del análisis anterior, es cuando miro las letras y el logotipo de la onda, porque puedo orientar mi búsqueda de algunas de las letras en las palabras, ya que es posible que no tenga todo el texto debido a que no tiene todas las letras puede, la onda se alinearía en ciertos puntos con el texto (distancia sabia) para poder buscar esa probabilidad y saber qué letras deberían existir en ese punto de la onda en la distancia x.




Related