Procesamiento de imágenes: mejora del algoritmo para el reconocimiento de 'Coca-Cola Can'


1659

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 haciendo hincapié 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.

Comparación de plantillas

Algunas limitaciones en el proyecto:

  • El fondo puede ser muy ruidoso.
  • La lata podría 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 de color).
  • La lata podría estar parcialmente oculta en los lados o en el medio y posiblemente parcialmente oculta detrás de una botella.
  • No podría haber ninguna lata en la imagen, en cuyo caso no tenía que encontrar nada y escribir un mensaje que lo dijera.

Así que podrías terminar con cosas difíciles como esta (que en este caso mi algoritmo falló por completo):

Fracaso total

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:

Lenguaje : Hecho en C ++ usando la biblioteca OpenCV .

Preprocesamiento : para el preprocesamiento de la imagen, es decir, transformar la imagen en una forma más cruda para darle al algoritmo, utilicé 2 métodos:

  1. Cambiar el dominio de color de RGB a HSV y el filtrado basado en el tono "rojo", la saturación por encima de cierto umbral para evitar colores naranjas y el filtrado de bajo valor para evitar 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 tiene que trabajar. Imagen binarizada
  2. Filtrado de ruido utilizando el filtrado medio (tomando el valor de píxel medio de todos los vecinos y reemplazando el píxel por este valor) para reducir el ruido.
  3. Uso del filtro de detección de bordes Canny para obtener los contornos de todos los elementos después de 2 pasos precedentes. Detección de contorno

Algoritmo : el algoritmo en sí que elegí para esta tarea fue tomado de este impresionante libro sobre extracción de características y se llamó Transformación Hough Generalizada (bastante diferente de la Transformación Hough regular). 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 gravitacional, por lo que tendrás muchos votos en el mismo píxel correspondiente al centro, y verá un pico en el mapa de calor de la siguiente manera:

GHT

Una vez que tenga eso, una simple heurística basada en el umbral puede darle la ubicación del píxel central, desde el 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, carecía severamente en algunas áreas:

  • ¡Es extremadamente lento ! No estoy haciendo suficiente hincapié en esto. 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 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, lo que terminó con un mapa de calor muy ruidoso.
  • Se logró una variación en la traslación y la rotación, pero no en la orientación, lo que significa que no se reconoció una lata que no estaba directamente orientada al objetivo de la cámara.

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

Espero que algunas personas también aprendan algo de eso, después de todo, creo que no solo las personas que hacen preguntas deberían aprender. :)


45
Se podría decir que esta pregunta es más apropiada en dsp.stackexchange.com, o stats.stackexchange.com, y ciertamente debería considerar volver a preguntar en esos sitios también.
ely

49
Lo primero que debe hacer aquí es analizar por qué están ocurriendo los diferentes casos de falla. Por ejemplo, aísle ejemplos de lugares donde las botellas ganan, donde las imágenes son borrosas, etc., y realice un análisis estadístico para conocer la diferencia entre sus representaciones de Hough y las que desea que detecte. Algunos grandes lugares para aprender acerca de los enfoques alternativos están aquí y aquí
Ely

77
@stacker hace un buen punto. Para obtener velocidad, desea obtener funciones económicas para calcular, como histogramas de gradientes orientados. Un primer enfoque realmente ingenuo sería etiquetar manualmente un montón de rectángulos de lata en algunas imágenes de entrenamiento, y usar estos más ejemplos negativos al azar para entrenar un SVM o un clasificador de árbol de decisión. La capacitación tomará más tiempo, pero la ejecución en imágenes nuevas será mucho más rápida. Estoy planeando escribir este método cuando tenga más tiempo libre para incluir las referencias correctas.
ely

99
¿Qué tal un enfoque similar a reCAPTCHA ? ;)
George Duckett

39
¿Por qué se movió esto de dsp.stackexchange.com ? Parece que ese sitio encajaría aún mejor que stackoverflow o_O
BlueRaja - Danny Pflughoeft

Respuestas:


672

Un enfoque alternativo sería extraer características (puntos clave) utilizando la transformación de características invariantes de escala (SIFT) o características robustas aceleradas (SURF).

Está implementado en OpenCV 2.3.1.

Puede encontrar un buen ejemplo de código utilizando las funciones de Características2D + Homografía para encontrar un objeto conocido

Ambos algoritmos son invariables para la escala y la rotación. Dado que funcionan con funciones, también puede manejar la oclusión (siempre que haya suficientes puntos clave visibles).

Ingrese la descripción de la imagen aquí

Fuente de la imagen: ejemplo tutorial

El procesamiento tarda unos cientos de ms para SIFT, SURF es un poco más rápido, pero no es adecuado para aplicaciones en tiempo real. ORB usa FAST, que es más débil con respecto a la invariancia de rotación.

Los papeles originales


66
Estoy de acuerdo con @stacker: SIFT es una excelente opción. Es muy robusto contra las operaciones de escala y rotación. Es algo robusto frente a la deformación en perspectiva (esto puede mejorarse según lo sugerido por el apilador: una base de datos de plantilla con diferentes vistas en perspectiva del objeto deseado). El talón de Aquiles en mi experiencia sería fuertes variaciones de iluminación y un cálculo muy costoso. No conozco ninguna implementación de Java. Soy consciente de una implementación de OpenCV y he usado una implementación de GPU c ++ / Windows ( SiftGPU ) adecuada para el rendimiento en tiempo real.

31
Una nota de advertencia: por mucho que ame SIFT / SURF y lo que me han hecho, están gravados por patentes. Esto podría ser un problema, dependiendo de una serie de condiciones, incluida la ubicación geográfica AFAIK.
Agos

12
Por lo tanto, pruebe con ORB o FREAK de OpenCV que no tienen problemas de patentes. ORB es mucho más rápido que SIFT. ORB es un poco pobre con las variaciones de escala y luz en mi experiencia, pero pruébelo usted mismo.
Rui Marques

66
¿Cómo puede aceptar esto como respuesta? Ninguno de los descriptores de características puede diferenciar las botellas de las latas. Todos ellos solo ven descriptores de patrones locales invariables. Estoy de acuerdo en que SIFT, SURF, ORB, FREAK, etc. pueden ayudarlo a hacer coincidir las características, pero ... ¿Qué pasa con sus otras partes de la pregunta, como oclusiones, Botella contra lata, etc. Espero que esta no sea una solución completa, de hecho, si lo haría? He resuelto su problema, probablemente el primer resultado sería solo esta respuesta.
G453

11
@ G453 tienes toda la razón! Probablemente se sintió fascinado por la actuación de SHIFT y se olvidó de que la extracción de características y la coincidencia no era el problema ...
sepdek

383

Para acelerar las cosas, aprovecharía 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 característica, invariante de escala en el dominio de frecuencia, particularmente en el canal rojo de RGB. Es decir, el patrón alternativo de rojo a blanco a rojo encontrado por una línea de exploración horizontal (entrenada en un logotipo alineado horizontalmente) tendrá un "ritmo" distintivo a medida que pasa a través del eje central del logotipo. Ese ritmo se "acelerará" o "disminuirá" en diferentes escalas y orientaciones, pero seguirá siendo proporcionalmente equivalente. Puede identificar / definir unas pocas docenas de líneas de exploración, tanto horizontal como verticalmente a través del logotipo y varias más en diagonal, en un patrón de estallido estelar. Llame a estas "líneas de escaneo de firmas".

Línea de escaneo de firma

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 encontrada, vea si le sigue uno de los ritmos de frecuencia identificados en la sesión de entrenamiento. Una vez que se encuentra una coincidencia, sabrá instantáneamente la orientación y ubicación de la línea de escaneo en el logotipo (si realiza un seguimiento de esas cosas durante el entrenamiento), por lo que identificar los límites del logotipo desde allí es trivial.

Me sorprendería si este no fuera un algoritmo linealmente eficiente, o casi. Obviamente no aborda la discriminación de la lata de botella, pero al menos tendrá sus logotipos.

(Actualización: para el reconocimiento de la botella, buscaría Coca-Cola (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 tenga el la misma forma básica, tamaño y distancia del logotipo y, por lo general, será todo blanco o rojo. Busque una forma elíptica de color sólido donde debería estar una gorra , en relación con el logotipo. No es infalible, por supuesto, pero su objetivo aquí debería ser encontrar los sencillos los rápidos .)

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


24
Esa es una gran sugerencia, me gusta especialmente el hecho de que este algoritmo debería ser bastante rápido, incluso si probablemente tenga muchos falsos negativos. ¡Uno de mis objetivos ocultos es usar esta detección en tiempo real para la robótica, por lo que podría ser un buen compromiso!
Charles Menguy

42
Sí, a menudo se olvida (en un campo caracterizado por la precisión) que los algoritmos de aproximación son esenciales para la mayoría de las tareas de modelado del mundo real en tiempo real. (Basé mi tesis en este concepto). Guarde sus algoritmos que requieren mucho tiempo para regiones limitadas (para podar falsos positivos). Y recuerde: en robótica generalmente no está limitado a una sola imagen. Suponiendo que se trata de un robot móvil, un alg rápido puede buscar docenas de imágenes desde diferentes ángulos en menos tiempo que el gasto sofisticado en una, lo que reduce significativamente los falsos negativos.
kmote

29
Me gusta la idea de usar lo que equivale a un escáner de código de barras para la detección extremadamente rápida de logotipos de Coca-Cola. +1!
Li-aung Yip

8
El problema de buscar firmas en este caso es que si giramos la lata hacia el otro lado, es decir, ocultando la firma, el algoritmo no podrá detectar la lata.
karlphillip

34
@karlphillip: Si oculta la firma, es decir, el logotipo, cualquier método basado en la búsqueda del logotipo fallará.
Li-aung Yip

162

Problema divertido: cuando miré la imagen de tu botella, pensé que también era una lata. Pero, como humano, lo que hice para notar la diferencia es que luego noté que también era una botella ...

Entonces, para distinguir las latas y las botellas, ¿qué tal simplemente escanear las botellas primero? Si encuentra uno, oculte la etiqueta antes de buscar latas.

No es demasiado difícil de implementar si ya estás haciendo latas. El verdadero inconveniente es que duplica su tiempo de procesamiento. (Pero pensando en las aplicaciones del mundo real, terminará queriendo hacer botellas de todos modos ;-)


55
Sí, también he pensado en eso, pero no tuve mucho tiempo para hacerlo. ¿Cómo reconocerías una botella, ya que su parte principal se verá como una lata a escala? Estaba pensando en buscar el tapón rojo también y ver si está alineado con el centro embotellado, pero eso no parece muy robusto.
Charles Menguy

42
Si hay una tapa roja (o anillo) paralela a la "Coca cola", es muy probable que sea una botella.
Lukasz Madon

@linker ¿Cómo entrenaste tu algoritmo para latas? ¿Tenías ejemplos de latas? ¿Qué tal entrenar con ejemplos de botellas?
siamii

1
La fortaleza de este algoritmo es que solo necesita una plantilla para entrenar, y luego aplica todas las transformaciones para que coincida con otras latas potenciales. Estaba usando una versión binarizada y basada en el contorno de esta plantilla para entrenar, por lo que la única diferencia entre la lata y la botella sería el tapón, pero me temo que traería más falsos positivos ya que el centro de gravedad estaría en algún lugar del borde o fuera de la botella. Vale la pena intentarlo, supongo. Pero eso duplicará mi tiempo de procesamiento y voy a llorar;)
Charles Menguy

77
Esencialmente, esta es una dirección razonable. Lo diría un poco diferente: primero encuentre todos los candidatos y luego, para cada candidato, determine si se trata de una botella, una lata u otra cosa.
MSalters

131

¿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, excepto por 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 es del mismo ancho en todo, pero un cambio menor, ¿verdad?)

Lo primero que me vino a la mente fue comprobar la tapa roja de la botella. Pero sigue siendo un problema, si no hay 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. Revise los siguientes enlaces.

Mire particularmente esto para ver con qué precisión detectan el vidrio:

Ver el resultado de su implementación:

Ingrese la descripción de la imagen aquí

Dicen que es la implementación del documento "Un marco de contorno activo geodésico para encontrar vidrio" por K. McHenry y J. Ponce, CVPR 2006 .

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

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

Ingrese la descripción de la imagen aquí

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 diferentes problemas como en las otras soluciones.

  1. Funciona solo si su botella está vacía. En ese caso, deberá 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.


+1 Pensé en esto y estaba en mi camino para implementar este enfoque. Sin embargo, @linker debería compartir su conjunto de imágenes para que podamos intentar hacer conjeturas más educadas.
karlphillip

sí ... también estoy pensando que sería bueno si hubiera más imágenes.
Abid Rahman K

Teniendo en cuenta si solo tenemos las etiquetas para botellas / latas y ninguno de los otros factores distintivos de la tapa o la transparencia de la botella o la lata superior / inferior: el ancho de la botella es diferente al ancho de la lata.
Ken

¿Qué pasa si se coloca una lata frente al logotipo de la botella?
AlgoRythm

51

Realmente me gustan las respuestas de Darren Cook y Stacker a este problema. Estaba a punto de poner mis pensamientos en un comentario al respecto, pero creo que mi enfoque tiene demasiada respuesta para no salir de aquí.

En resumen, ha identificado un algoritmo para determinar que un logotipo de Coca-Cola está presente en una ubicación particular en el espacio. Ahora está tratando de determinar, por orientaciones arbitrarias y factores de escala arbitrarios, una heurística adecuada para distinguir las latas de Coca-Cola de otros objetos, incluidos: botellas , vallas publicitarias , anuncios y parafernalia de Coca-Cola, todos asociados con este logotipo icónico. No mencionó muchos de estos casos adicionales en su enunciado del problema, pero creo que son vitales para el éxito de su algoritmo.

El secreto aquí es determinar qué características visuales contiene una lata o, a través del espacio negativo, qué características están presentes para otros productos de Coca-Cola que no están presentes para las latas. Con ese fin, la respuesta principal actual esboza un enfoque básico para seleccionar "lata" si y solo si "botella" no se identifica, ya sea por la presencia de una tapa de botella, líquido u otra heurística visual similar.

El problema es que esto se rompe. Una botella podría, por ejemplo, estar vacía y carecer de la presencia de una tapa, lo que lleva a un falso positivo. O bien, podría ser una botella parcial con características adicionales destrozadas, lo que lleva nuevamente a una detección falsa. No hace falta decir que esto no es elegante, ni es efectivo para nuestros propósitos.

Con este fin, los criterios de selección más correctos para las latas parecen ser los siguientes:

  • ¿Es correcta la forma de la silueta del objeto, como esbozaste en tu pregunta ? Si es así, +1.
  • Si asumimos la presencia de luz natural o artificial, ¿detectamos un contorno cromado en la botella que indique si está hecho de aluminio? Si es así, +1.
  • ¿Determinamos que las propiedades especulares del objeto son correctas, en relación con nuestras fuentes de luz ( enlace de video ilustrativo sobre detección de fuente de luz )? Si es así, +1.
  • ¿Podemos determinar cualquier otra propiedad sobre el objeto que lo identifique como una lata, incluyendo, entre otros, el sesgo de la imagen topológica del logotipo, la orientación del objeto, la yuxtaposición del objeto (por ejemplo, en una superficie plana) como una mesa o en el contexto de otras latas), y la presencia de una pestaña de extracción? Si es así, para cada uno, +1.

Su clasificación podría verse así:

  • Para cada partido candidato, si se detectó la presencia de un logotipo de Coca Cola, dibuje un borde gris.
  • Para cada partido por encima de +2, dibuja un borde rojo.

Esto resalta visualmente al usuario lo que se detectó, enfatizando los positivos débiles que, correctamente, pueden detectarse como latas destrozadas.

La detección de cada propiedad conlleva una complejidad de tiempo y espacio muy diferente, y para cada enfoque, un paso rápido a través de http://dsp.stackexchange.com es más que razonable para determinar el algoritmo más correcto y más eficiente para sus propósitos. Mi intención aquí es, pura y simplemente, enfatizar que detectar si algo es una lata al invalidar una pequeña porción del espacio de detección de candidatos no es la solución más sólida o efectiva para este problema, e idealmente, debe tomar las medidas apropiadas en consecuencia.

Y oye, ¡felicidades por la publicación de Hacker News! En general, esta es una pregunta bastante excelente, digna de la publicidad que recibió. :)


2
Ese es un enfoque interesante que al menos vale la pena intentarlo, realmente me gusta tu razonamiento sobre el problema
Charles Menguy

Esto es algo de lo que estaba pensando: no descarte tipos particulares de falsos positivos. Regla en más características de lo que hace una lata de coca cola. Pero me pregunto: ¿qué haces con una lata aplastada? Quiero decir, si pisas una lata de coca cola, sigue siendo una lata de coca cola. Pero ya no tendrá la misma forma. ¿O ese problema es AI-Complete?
Ian

41

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 la misma.

Mirando lo más destacado

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 metal 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 notaría la diferencia entre los dos tipos de etiquetas. Si las condiciones de iluminación son malas, seguramente habrá cierta incertidumbre al distinguir los dos de todos modos. En ese caso, debería poder detectar la presencia de la botella transparente / translúcida.


Me gusta la idea, pero parece que necesitarías unas condiciones de iluminación realmente buenas. En la imagen de ejemplo donde hay lata y botella, por ejemplo, esto parece un poco difícil de hacer.
Charles Menguy

En su ejemplo, observe cómo la especularidad para la etiqueta de plástico es mucho más difusa que los puntos muy brillantes en la lata. Así es como se puede saber.
tskuzzy

Ya veo, ¿qué tipo de representación de espacio de color usarías en este caso para capturar la especularidad en tu algoritmo? Esto parece bastante difícil de conseguir en RGB o HSV
Charles Menguy

3
¿Qué pasa si la fuente de luz estaba detrás de la lata? Creo que no verías lo más destacado.
Rui Marques

37

Por favor, eche un vistazo al rastreador Predator de Zdenek Kalal . Requiere algo de entrenamiento, ¡pero puede aprender activamente cómo el objeto rastreado se ve en diferentes orientaciones y escalas y lo hace en tiempo real!

El código fuente está disponible en su sitio. Está en MATLAB , pero quizás haya una implementación de Java ya realizada por un miembro de la comunidad. He vuelto a implementar con éxito la parte de seguimiento de TLD en C #. Si no recuerdo mal, TLD está usando Ferns como el detector de punto clave. En su lugar, uso SURF o SIFT (ya sugerido por @stacker) para volver a adquirir el objeto si el rastreador lo perdió. Los comentarios del rastreador facilitan la creación con tiempo de una lista dinámica de plantillas de exploración / navegación que con el tiempo permiten recuperar el objeto con una precisión muy alta.

Si está interesado en mi implementación de C # del rastreador, no dude en preguntar.


Gracias por el enlace que parece interesante. Con respecto a la capacitación, ¿cuál es el tamaño del conjunto de capacitación que sería razonable para lograr resultados razonables? Si tiene una implementación incluso en C #, ¡eso también sería muy útil!
Charles Menguy

Mientras investigaba TLD, encontré otro usuario que buscaba una implementación de C #. ¿Hay alguna razón para no poner su trabajo en Github? stackoverflow.com/questions/29436719/…
spillner

2
NB Años, más tarde, el enlace ahora está muerto
J Evans

33

Si no está limitado a una cámara que no estaba en una de sus limitaciones, quizás pueda usar un sensor de alcance como el Xbox Kinect . Con esto, puede realizar una segmentación coincidente basada en profundidad y color de la imagen. Esto permite una separación más rápida de los objetos en la imagen. A continuación, puede usar la coincidencia de 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 anterior del objetivo. Estas técnicas a menudo son bastante rápidas, especialmente cuando se usan para un propósito tan específico que debería resolver su problema de velocidad.

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


3
En realidad, no expliqué eso en la publicación, pero para esta tarea me dieron un conjunto de aproximadamente 30 imágenes, y tuve que hacer un algoritmo que las igualara a todas en diversas situaciones como se describe. Por supuesto, algunas imágenes se presentaron para probar el algoritmo al final. Pero me gusta la idea de los sensores Kinect, ¡y me encantaría leer más sobre el tema!
Charles Menguy

¿Cuál sería aproximadamente el tamaño del conjunto de entrenamiento con una red neuronal para tener resultados satisfactorios? Lo bueno de este método también es que solo necesito una plantilla para que coincida con casi todo.
Charles Menguy

2
Si su conjunto de imágenes está predefinido y limitado, solo resultados perfectos en su programa;)
sne11ius

Sí, si entreno en el conjunto de datos con el que voy a ejecutar el algoritmo, seguro que obtendré resultados perfectos :) Pero, por ejemplo, para esta tarea, el programa probó el profesor al final en un conjunto de imágenes extendidas . Me gustaría hacer algo que sea robusto y que no se ajuste demasiado a los datos de entrenamiento.
Charles Menguy

El número de series de entrenamiento varía, sin embargo, debes tener cuidado con algunas cosas: no entrenes demasiado, probablemente quieras un conjunto de prueba que muestre cómo va tu precisión. Además, la cantidad de conjuntos de entrenamiento dependerá de la cantidad de capas que usará.
Fantástico Mr Fox

24

Detectaría rectángulos rojos: RGB -> HSV, filtro rojo -> imagen binaria, cerrar (dilatar y luego erosionar, conocido como imcloseen matlab)

Luego mira a través de los rectángulos de mayor a menor. Los rectángulos que tienen rectángulos más pequeños en una posición / escala conocida se pueden eliminar (suponiendo que las proporciones de la botella sean constantes, el rectángulo más pequeño sería una tapa de botella).

Esto te dejaría con rectángulos rojos, entonces necesitarás detectar de alguna manera los logotipos para saber si son un rectángulo rojo o una lata de coca cola. ¿Como OCR, pero con un logotipo conocido?


2
Al igual que esto se discutió en DSP en el corto tiempo en que se movió, algunas botellas pueden no tener tapones;) o el tapón podría estar parcialmente oculto.
Charles Menguy

22

Esta puede ser una idea muy ingenua (o puede que no funcione en absoluto), pero las dimensiones de todas las latas de coca cola son fijas. Entonces, si la misma imagen contiene una lata y una botella, 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 parezca encogida y no haya una diferencia de tamaño. Puede recuperar información de profundidad utilizando imágenes estéreo y luego recuperar el tamaño original.


3
En realidad no: no hay restricción de tamaño u orientación (u orientación, pero realmente no lo manejé), por lo que puede tener una botella muy lejos en el fondo y una lata en primer plano, y la lata sería mucho más grande que la botella
Charles Menguy

También he comprobado que la relación entre el ancho y la altura es bastante similar para la botella y la lata, por lo que tampoco es una opción.
Charles Menguy

La relación de la etiqueta (siendo una marca registrada) es la misma. Entonces, si la botella (más grande) está un poco más lejos en la imagen, su tamaño será exactamente el mismo que el de la lata.
littleadv

3
Para explicar un poco más. Supongamos que can está en z = 0 y la botella en z = -100. Como la botella está muy por detrás, se verá más pequeña. Pero si sé que la botella está en z = -100 y puede en z = 0, entonces puedo calcular el tamaño esperado de la lata / botella si ambos se traducen a z = 0. Entonces ahora están a la misma profundidad y, por lo tanto, puedo tomar decisiones basadas en el tamaño.
Sharad

2
Esto es solo un comentario, no una respuesta, pero está mucho más cerca de ser una respuesta que el comentario como respuesta anterior con 120 votos.
Fattie

22

Hmm, en realidad creo que estoy en algo (esta es la pregunta más interesante de la historia, así que sería una pena no seguir tratando de encontrar la respuesta "perfecta", a pesar de que se haya encontrado una respuesta aceptable). .

Una vez que encuentre el logotipo, sus problemas estarán a medias. Entonces solo tiene que descubrir las diferencias entre lo que hay alrededor del logotipo. Además, queremos hacer la menor cantidad adicional posible. Creo que esta es realmente esta parte fácil ...

¿Qué hay alrededor del logo? Para una lata, podemos ver el metal, que a pesar de los efectos de la iluminación, no cambia en absoluto en su color básico. Mientras sepamos el ángulo de la etiqueta, podemos saber qué hay directamente encima de ella, por lo que estamos viendo la diferencia entre estos:

Aquí, lo que está arriba y debajo del logotipo es completamente oscuro, de color consistente. Relativamente fácil a ese respecto.

Aquí, lo que está arriba y abajo es claro, pero sigue siendo de color constante. Es totalmente plateado, y el metal totalmente plateado en realidad parece bastante raro, así como los colores plateados en general. Además, está en un deslizamiento delgado y lo suficientemente cerca del rojo que ya se ha identificado para que pueda trazar su forma en toda su longitud para calcular un porcentaje de lo que puede considerarse el anillo de metal de la lata. Realmente, solo necesita una pequeña fracción de eso en cualquier lugar a lo largo de la lata para decir que es parte de ella, pero aún necesita encontrar un equilibrio que garantice que no sea solo una botella vacía con algo de metal detrás.

Y finalmente, el complicado. Pero no es tan complicado, una vez que solo veamos lo que podemos ver directamente arriba (y debajo) del envoltorio rojo. Es transparente, lo que significa que mostrará lo que haya detrás. Eso es bueno, porque es probable que las cosas que están detrás no sean tan consistentes en color como el metal circular plateado de la lata. Podría haber muchas cosas diferentes detrás de él, lo que nos diría que es una botella vacía (o llena de líquido transparente), o un color consistente, lo que podría significar que está llena de líquido o que la botella está simplemente frente a un color solido. Estamos trabajando con lo que está más cerca de la parte superior e inferior, y las posibilidades de que los colores correctos estén en el lugar correcto son relativamente escasas. Sabemos que es una botella, porque no tiene ese elemento visual clave de la lata,

(esa última fue la mejor que pude encontrar de una botella de coca cola grande y vacía; curiosamente, la tapa Y el anillo son amarillos, lo que indica que probablemente no se debe confiar en el enrojecimiento de la tapa)

En la rara circunstancia de que haya un tono similar de plata detrás de la botella, incluso después de la extracción del plástico, o si la botella se llena de alguna manera con el mismo tono de líquido plateado, podemos recurrir a lo que podemos estimar aproximadamente como el forma de la plata, que como mencioné, es circular y sigue la forma de la lata. Pero aunque me falta cierto conocimiento en el procesamiento de imágenes, eso suena lento. Mejor aún, ¿por qué no deducir esto comprobando por una vez los lados del logotipo para asegurarse de que no haya nada del mismo color plateado? Ah, pero ¿y si hay el mismo tono de plata detrás de una lata? Entonces, de hecho, debemos prestar más atención a las formas, mirando de nuevo la parte superior e inferior de la lata.

Dependiendo de cuán impecable sea todo esto, puede ser muy lento, pero supongo que mi concepto básico es verificar primero las cosas más fáciles y cercanas. Ve por las diferencias de color alrededor de la forma ya emparejada (que de todos modos parece ser la parte más trivial de esto) antes de esforzarte por resolver la forma de los otros elementos. Para enumerarlo, va:

  • Encuentre la atracción principal (fondo del logotipo rojo, y posiblemente el logotipo en sí mismo para orientación, aunque en caso de que la lata esté rechazada, debe concentrarse solo en el rojo)
  • Verifique la forma y orientación, una vez más a través del enrojecimiento muy distintivo
  • Verifique los colores alrededor de la forma (ya que es rápido y sin dolor)
  • Finalmente, si es necesario, verifique la forma de esos colores alrededor de la atracción principal para obtener la redondez correcta.

En el caso de que no pueda hacer esto, probablemente significa que la parte superior e inferior de la lata están cubiertas, y las únicas cosas posibles que un humano podría haber utilizado para distinguir de manera confiable entre la lata y la botella es la oclusión y la reflexión. de la lata, que sería una batalla mucho más difícil de procesar. Sin embargo, para ir aún más lejos, puede seguir el ángulo de la lata / botella para verificar si hay más rasgos similares a las botellas, utilizando las técnicas de escaneo semitransparente mencionadas en las otras respuestas.

Las pesadillas adicionales interesantes podrían incluir una lata convenientemente sentada detrás de la botella a una distancia tal que el metal se muestre por encima y por debajo de la etiqueta, lo que aún fallaría mientras escanee a lo largo de todo el rojo etiqueta, que en realidad es más un problema porque no está detectando una lata donde podría haber, en lugar de considerar que realmente está detectando una botella, incluida la lata por accidente. ¡El vaso está medio vacío, en ese caso!


Como descargo de responsabilidad, no tengo experiencia ni he pensado en el procesamiento de imágenes fuera de esta pregunta, pero es tan interesante que me hizo pensar bastante en ello, y después de leer todas las otras respuestas, considero que esto posiblemente sea La forma más fácil y eficiente de hacerlo. En lo personal, estoy contento de que no realmente que pensar en la programación de este!

EDITAR

mal dibujo de una lata en pintura MS Además, mira este dibujo que hice en MS Paint ... Es absolutamente horrible y bastante incompleto, pero basándote solo en la forma y los colores, puedes adivinar lo que probablemente será. En esencia, estas son las únicas cosas que uno necesita para molestarse en escanear. Cuando miras esa forma distintiva y combinación de colores tan cercanos, ¿qué más podría ser? La parte que no pinté, el fondo blanco, debe considerarse "algo inconsistente". Si tuviera un fondo transparente, podría pasar sobre casi cualquier otra imagen y aún así podría verla.


10
El tono particular del rojo es principalmente subjetivo y está fuertemente influenciado por consideraciones de iluminación y balance de blancos. Te sorprenderá cuánto pueden cambiar esos. Considere, por ejemplo, esta ilusión de tablero de ajedrez .
Pulpo

2
Una actualización del enlace que @Octopus publicó: persci.mit.edu/gallery/checkershadow
Sombrero

Una ilusión de percepción no afecta lo que ve su cámara web, es decir, lo que obtiene su código, solo cómo un ojo humano engaña útilmente (?) Al cerebro.
Barny

17

No conozco OpenCV, pero mirando el problema lógicamente, creo que podría diferenciar entre la botella y la lata cambiando la imagen que está buscando, es decir, Coca Cola. Debe incorporar hasta la parte superior de la lata ya que en el caso de la lata hay un revestimiento plateado en la parte superior de la coca cola y en el caso de la botella no habrá tal revestimiento plateado.

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


1
Pensé lo mismo, pero creo que el revestimiento plateado en la parte superior de la lata cambia dramáticamente dependiendo del ángulo de la lata en la imagen. Puede ser una línea recta o un círculo. ¿Quizás podría usar ambos como referencia?
Alexis Dufrenoy

15

Me gusta el desafío y quería dar una respuesta, lo que resuelve el problema, creo.

  1. Extraer características (puntos clave, descriptores como SIFT, SURF) del logotipo
  2. Haga coincidir los puntos con una imagen modelo del logotipo (usando Matcher como Brute Force)
  3. Estime las coordenadas del cuerpo rígido (problema PnP - SolvePnP)
  4. Estime la posición de la tapa de acuerdo con el cuerpo rígido
  5. Haga una retroproyección y calcule la posición del píxel de la imagen (ROI) de la tapa de la botella (supongo que tiene los parámetros intrínsecos de la cámara)
  6. Verifique con un método si la tapa está ahí o no. Si hay, entonces esta es la botella

La detección del límite es otro problema. Puede ser complicado o simple. Si yo fuera usted, simplemente verificaría el histograma de color en el ROI para una decisión simple.

Por favor, envíe sus comentarios si me equivoco. Gracias.


13

Llevo unos años tarde en responder 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 quería específicamente las funciones de OpenCv en la pregunta ) Creo que los algoritmos de detección de objetos como Faster-RCNN, YOLO, SSD, etc. resolverían este problema con un margen significativo en comparación con las funciones de OpenCV. Si tuviera que resolver este problema ahora (¡después de 6 años!) Definitivamente usaría Faster-RCNN .


55
OP dijo que había 30 imágenes de alta resolución, que probablemente no sea el mejor escenario para entrenar ConvNets. No solo son muy pocos (incluso aumentados), la parte de alta resolución destruiría ConvNets.
Kostas Mouratidis

11

Me gusta su pregunta, independientemente de si está fuera de tema o no: P

Un interesante aparte; Acabo de completar una asignatura en mi carrera en la que cubrimos robótica y visión por computadora. Nuestro proyecto para el semestre fue increíblemente similar al que usted describe.

Tuvimos que desarrollar un robot que utilizara un Xbox Kinect para detectar botellas y latas de coca en cualquier orientación en una variedad de condiciones de iluminación y ambientales. Nuestra solución implicó el uso de un filtro de paso de banda en el canal Hue en combinación con la transformación de círculo de hough. Pudimos restringir un poco el entorno (pudimos elegir dónde y cómo colocar el robot y el sensor Kinect), de lo contrario, íbamos a utilizar las transformaciones SIFT o SURF.

Puedes leer sobre nuestro enfoque en mi blog en el tema :)


2
Proyecto interesante pero solo se aplica a su configuración muy específica.
Rui Marques

10

Hay un montón de descriptores de color que se utilizan 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, necesita la información de color para ayudar. Utilizo BIC (Border / Interior Pixel Classi fi cation) 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


10

Aprendizaje profundo

Reúna al menos unos cientos de imágenes que contengan latas de cola, anote el cuadro delimitador a su alrededor como clases positivas, incluya botellas de cola y otros productos de cola, rotúlelos como clases negativas, así como objetos aleatorios.

A menos que recopile un conjunto de datos muy grande, realice el truco de utilizar las funciones de aprendizaje profundo para un conjunto de datos pequeño. Idealmente usando una combinación de Máquinas de vectores de soporte (SVM) con redes neuronales profundas.

Una vez que alimente las imágenes a un modelo de aprendizaje profundo previamente entrenado (por ejemplo, GoogleNet), en lugar de usar la capa de decisión (final) de la red neuronal para hacer clasificaciones, use los datos de las capas anteriores como características para entrenar a su clasificador.

OpenCV y Google Net: http://docs.opencv.org/trunk/d5/de7/tutorial_dnn_googlenet.html

OpenCV y SVM: http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html


9

Necesita un programa que aprenda y mejore la precisión de clasificación orgánicamente 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 de inicio v3 en Tensorflow:

Cómo volver a entrenar la capa final del inicio para nuevas categorías .

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


2
Hot dog o no hot dog?
YellowPillow

6

Como alternativa a todas estas buenas soluciones, puede entrenar su propio clasificador y hacer que su aplicación sea robusta a 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 puede combinarse con la detección de objetos transparentes.


3

Hay un paquete de visión por computadora llamado HALCON de MVTec cuyas demostraciones pueden darle buenas ideas de algoritmos. Hay muchos ejemplos similares a su problema que podría ejecutar en modo de demostración y luego mirar a los operadores en el código y ver cómo implementarlos desde los operadores OpenCV existentes.

He usado este paquete para crear rápidamente prototipos de algoritmos complejos para problemas como este y luego encontrar cómo implementarlos utilizando las funciones existentes de OpenCV. En particular, para su caso, podría intentar implementar en OpenCV la funcionalidad incorporada en el operador find_scaled_shape_model . Algunos operadores señalan el artículo científico sobre la implementación de algoritmos que puede ayudar a descubrir cómo hacer algo similar en OpenCV. Espero que esto ayude...


0

Si está interesado en que sea en tiempo real, entonces lo que necesita es agregar un filtro de preprocesamiento para determinar qué se escanea con el material pesado. Un buen filtro de preprocesamiento rápido y en tiempo real que le permitirá escanear cosas que tienen más probabilidades de ser una lata de coca que antes de pasar a cosas más dudosas es algo como esto: busque en la imagen los parches más grandes de color que son una cierta tolerancia lejos sqrt(pow(red,2) + pow(blue,2) + pow(green,2))de su lata de coca-cola. Comience con una tolerancia de color muy estricta y avance hasta obtener tolerancias de color más indulgentes. Luego, cuando su robot se queda sin un tiempo asignado para procesar el marco actual, utiliza las botellas encontradas actualmente para sus propósitos. Tenga en cuenta que tendrá que ajustar los colores RGB en el sqrt(pow(red,2) + pow(blue,2) + pow(green,2))para obtenerlos a la perfección.

Además, esto parece muy tonto, pero ¿se aseguró de activar -oFastlas optimizaciones del compilador cuando compiló su código C?


0

Tal vez muchos años tarde, pero sin embargo, una teoría para probar.

La relación entre el rectángulo delimitador de la región del logotipo rojo y la dimensión general de la botella / lata es diferente. En el caso de Can, debe ser 1: 1, mientras que será diferente en el de botella (con o sin tapón). Esto debería facilitar la distinción entre los dos.

Actualización: la curvatura horizontal de la región del logotipo será diferente entre la lata y la botella debido a su respectiva diferencia de tamaño. Esto podría ser específicamente útil si su robot necesita recoger la lata / botella, y usted decide el agarre en consecuencia.


-1

Lo primero que buscaría es el color, como ROJO, cuando detecto los ojos rojos en una imagen; hay un cierto rango de color para detectar, algunas características al respecto considerando el área circundante y, por ejemplo, la distancia del otro ojo si es de hecho visible en la imagen.

1: La primera característica es el color y el rojo es muy dominante. Después de detectar Coca Cola Red, hay varios elementos de interés 1A: ¿Qué tan grande es esta área roja? (¿Es suficiente para hacer una determinación de una lata verdadera o no? 10 píxeles probablemente no sean suficientes), 1B: ¿Contiene El color de la etiqueta - "Coca-Cola" u ola. 1B1: ¿Hay suficiente para considerar una alta probabilidad de que sea una etiqueta?

El ítem 1 es una especie de atajo - preprocesar si eso no existe en la imagen - seguir adelante.

Entonces, si ese es el caso, entonces puedo utilizar ese segmento de mi imagen y comenzar a mirar un poco más el área en cuestión, básicamente mira la región / bordes circundantes ...

2: Dada la ID de área de imagen anterior identificada en 1, verifique los puntos circundantes [bordes] del elemento en cuestión. R: ¿Existe lo que parece ser una lata superior o inferior: plata? B: Una botella puede parecer transparente, pero también puede ser una mesa de vidrio, por lo que hay una mesa / estante de vidrio o un área transparente, de ser así, hay varias salidas posibles. Una botella PUEDE tener una tapa roja, puede que no, pero debe tener la forma de la tapa de la botella / tornillos de rosca, o una tapa. C: Incluso si esto falla A y B, todavía puede ser una lata parcial. Esto es más complejo cuando es parcial porque una botella parcial / una lata parcial puede verse igual, por lo que un poco más de procesamiento de la medición del borde de la región roja al borde ... la botella pequeña puede ser similar en tamaño ...

3: Después del análisis anterior, es cuando miraría 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 todos los puede, la onda se alinearía en ciertos puntos del texto (en lo que respecta a la distancia) para poder buscar esa probabilidad y saber qué letras deberían existir en ese punto de la onda a la distancia x.


-9

Este es un viejo proyecto en el que trabajé. Las imágenes MAP son muy fáciles de usar con javascript. Te ofrezco el objeto, lo lees y sabes cómo usarlo. No necesitamos JQuery y otros sistemas para usar imágenes MAP.

    //Copyright Cherif yahiaoui, by ELEBAN.FR

//variables de flottement.
var myInstOne = null;
var globalize = null;

var eleban_preload_images = function (name, imgs, url){
try{
    var oThis = this;
    this.images = new Array();
    this.imageshover = new Array();
    this.imagesNames = new Array(imgs.split(";"));


        for(var i=0; i < this.imagesNames[0].length; i++){
            this.images[i] = new Image();
            this.imageshover[i] = new Image();
        }

    this.url = url;

    this.GetAbsoluteurl = function () {

    var img = new Image(); img.src = url;
    url = img.src; img = null; 
        this.url = url; 

    };

    this.Preload = function () {

        for(var i=0; i < this.imagesNames[0].length; i++){
            this.images[i].src = this.url+("btn-"+this.imagesNames[0][i]+".png");
            this.imageshover[i].src = this.url+("btn-"+this.imagesNames[0][i]+"-hover.png");
        }

    };
    this.GetAbsoluteurl();
    this.Preload();
}
finally {return;}
}

var g_preloaderhover = new eleban_preload_images("loaderhover","menu;malette;reservation;cabine;facebook;map;amis","./images/");


//variable arret flottement
var g_stopflo = false;

var myObjfloater = function(name, idname, itop, differ ) {
var oThis = this; // création d'une référence vers l'objet courant
this.name = name;
this.id =idname;
this.xstep= 0.3;
this.itime = 30;
this.obj = null;
this.y = itop;
this.yadd = 0;
this.up = true;
this.pause = false;
this.differ = differ;
this.coordsimage = null;
this.objimg = null;
this.initimages = false;
this.compteur = 0;
this.over = false;
this.timeoutstop = null;
try{
this.initimage = function(){
var img = this.obj.getElementsByTagName('img')[0];
this.coordsimage = new Array(img.width, img.height);
this.objimg = img;
this.initimages = true;
};


this.myMethod = function() {
if(!g_stopflo){
    if(this.differ != 0){ 
this.differ=this.differ-0.1; 
}else{

if(this.obj){
if(this.over == false){
    this.yadd=this.yadd+0.1; this.itime = this.itime + 10;
this.obj.style.visibility = "hidden";
this.y = ((this.up)? this.y - this.yadd : this.y + this.yadd);
this.obj.style.marginTop = this.y +"%" ;
this.obj.style.visibility = "visible";

if (this.yadd > this.xstep){ 
    this.up = (this.up)? false : true;
    this.yadd = -0.1; this.itime=180;
}
}
}else{
    if (document){
        if(document.getElementById) {
         this.obj = document.getElementById(this.id); 
        //this.y = this.obj.offsetTop;
        }else{
        if(document.getElementByTagName) { this.obj = document.getElementByTagName(this.id); this.y = this.obj.offsetTop;}
        }

    }
}
}
this.timeoutstop=setTimeout(function() { oThis.myMethod(); }, this.itime);
}    
};

this.callDelayed = function() {
    // utilisation de la référence vers l'objet
if(!g_stopflo){
    this.timeoutstop=setTimeout(function() { oThis.myMethod(); }, this.itime);
}
};
}
finally {return;}
};

// special creation des zones AREA
function eleban_createallarea(){
try{
var measur = new Array("w", "h");
measur["w"] = new Array(330,570,185,300,115,390,225);
measur["h"] = new Array(460,570,295,450,100,190,115);
var ititle = new Array("Voir les menus  et nos suggestions","Repas &agrave; emporter","R&eacute;servation d&rsquo;une table","Nous contacter","Nous rejoindre sur FaceBook","Calculer votre trajet","liste des amis");
var ihref = new Array("menus.html","emporter.html","reservation.html","contact.html","likebox.html","google.html","amis.html");
var b_map = new Array(0,1,2,3,4,5,6);
b_map[0] = "71,32,240,32,249,43,289,352,280,366,102,385,90,371,51,38";
b_map[1] = "66,52,95,14,129,56,115,91,100,93,112,273,128,284,122,366,176,343,193,296,191,194,147,189,145,166,201,111,199,84,545,105,532,354,509,388,412,478,32,401,77,383,87,375,82,286,95,269,94,221,24,195,11,165,9,120,89,123,89,94,78,92,77,92,77,93,75,93,77,93,76,93,79,92";
b_map[2] = "19,25,169,38,173,112,161,113,105,103,90,125,91,262,121,269,124,281,96,293,62,289,49,281,56,268,83,264,84,121,71,98,16,90";
b_map[3] = "60,0,216,1,226,20,225,403,168,421,42,410,45,10";
b_map[4] = "31,7,72,10,82,18,88,45,88,71,76,81,29,80,17,68,16,18";
b_map[5] = "91,40,141,38,178,27,184,4,211,5,223,24,240,23,386,135,229,121,103,180,6,156,49,94";
b_map[6] = "6,32,69,18,79,6,118,7,141,2,149,10,211,17,202,28,209,30,189,62,195,70,178,74,180,90,164,90,154,107,68,101,34,104,34,98,18,97,28,84,15,84,30,65";

if (document.getElementById){
for (var i=0; i<b_map.length;i++){
var obj = document.getElementById("pc_menu"+i);
    if(obj){
    var ct = '<img class=\"pc_menu\" src=\"'+g_preloaderhover.images[i].src+'\" alt=\"\" width=\"'+measur["w"][i]+'\" height=\"'+measur["h"][i]+'\" usemap=\"#MAP_INDEX'+i+'\" \/>';
    ct+='<map name=\"MAP_INDEX'+i+'\">';
    ct+='<area shape=\"poly\" coords=\"'+b_map[i]+'\" title=\"'+ititle[i]+'\" href=\"'+ihref[i]+'\" \/>';
    ct+='<\/map>';
    obj.innerHTML = ct;
    }
}
}
}
finally {return;}
}

//preload, creation et gestion de tous les evenements


var image_resizer = function(g_layer){


    b_org_elm = new Array("w",  "h");
    b_org_elm["w"] = new Array(330,570,185,300,115,390,225);
    b_org_elm["h"] = new Array(460,570,295,450,100,190,115);

    b_map = new Array(0,1,2,3,4,5,6);
    b_map[0] = new Array(71,32,240,32,249,43,289,352,280,366,102,385,90,371,51,38);
    b_map[1] = new Array(66,52,95,14,129,56,115,91,100,93,112,273,128,284,122,366,176,343,193,296,191,194,147,189,145,166,201,111,199,84,545,105,532,354,509,388,412,478,32,401,77,383,87,375,82,286,95,269,94,221,24,195,11,165,9,120,89,123,89,94,78,92,77,92,77,93,75,93,77,93,76,93,79,92);
    b_map[2] = new Array(19,25,169,38,173,112,161,113,105,103,90,125,91,262,121,269,124,281,96,293,62,289,49,281,56,268,83,264,84,121,71,98,16,90);
    b_map[3] = new Array(60,0,216,1,226,20,225,403,168,421,42,410,45,10);
    b_map[4] = new Array(31,6,70,10,78,18,84,23,88,44,88,70,78,80,75,81,33,82,23,76,18,69,16,22,21,13);
    b_map[5] = new Array(91,40,141,38,178,27,184,4,211,5,223,24,240,23,386,135,229,121,103,180,6,156,49,94);
    b_map[6] = new Array(6,32,69,18,79,6,118,7,141,2,149,10,211,17,202,28,209,30,189,62,195,70,178,74,180,90,164,90,154,107,68,101,34,104,34,98,18,97,28,84,15,84,30,65);


    b_layer = g_layer;

//gere mouseover
    this.mouseover = function(e){
        if (!e) var e = window.event;
        var tg = (window.event) ? e.srcElement : e.target
            if (tg.nodeName){
                if(tg.nodeName == "AREA"){
                var divpar = (tg.parentNode)? tg.parentNode.parentNode : tg.parentElement.parentElement;
                    if (divpar){
                        if(divpar.nodeName == "DIV"){
                            var iiobjimg = divpar.getElementsByTagName('img');
                                if (iiobjimg){
                                    ii = parseInt(divpar.id.substring(divpar.id.length-1,divpar.id.length));
                                    iiobjimg[0].src = g_preloaderhover.imageshover[ii].src;
                                }
                        }
                    }
                }
            }
    };

//gere mouseout
    this.mouseout = function(e){
        if (!e) var e = window.event;
        tg = (window.event) ? e.srcElement : e.target
            if (tg.nodeName){
                if(tg.nodeName == "AREA"){
                divpar = (tg.parentNode)? tg.parentNode.parentNode : tg.parentElement.parentElement;
                    if (divpar){
                        if(divpar.nodeName == "DIV"){
                            var iiobjimg = divpar.getElementsByTagName('img');
                                if (iiobjimg){
                                    ii = parseInt(divpar.id.substring(divpar.id.length-1,divpar.id.length));
                                    iiobjimg[0].src = g_preloaderhover.images[ii].src;
                                }
                        }
                    }
                }
            }
    };

//ajout evenements entree sortie à la page web lors du chargement de la page
    this.init = function () {

        for(var i=0; i<b_org_elm["w"].length;i++){
            w = document.getElementById("pc_menu"+i).offsetWidth;
            h = document.getElementById("pc_menu"+i).offsetHeight;

            xa = w/parseFloat(b_org_elm["w"][i]);
            ya = h/parseFloat(b_org_elm["h"][i]);

            area = document.getElementById("pc_menu"+i).getElementsByTagName('area')[0];

            b_map2 = area.coords.split(",");
            yswitch = true;
                for(m=0; m<b_map2.length;m++){
                b_map2[m] = Math.round(parseFloat(b_map[i][m]) * ((yswitch)? xa: ya));
                yswitch = (yswitch)? false :  true;
                }
            area.coords = b_map2.join(',');
        }
    }; 


    this.resize = function () {
    clearTimeout(myInstOne.timeoutstop);
    g_stopflo=true;

    globalize.init();
    g_stopflo=false;
    myInstOne.obj = null;
    myInstOne.callDelayed();
    };


    nar = document.getElementsByTagName('area').length;

        for(var i=0; i<nar;i++){
            var elem = document.getElementsByTagName('area')[i];
            if (elem.addEventListener){
                    elem.addEventListener("onmouseover",this.mouseover,true);
                elem.addEventListener("onmouseout",this.mouseout,true);
            }else if (elem.attachEvent) {
                    elem.attachEvent("onmouseover", this.mouseover);
                    elem.attachEvent("onmouseout", this.mouseout);
            }else{
                    elem["onmouseover"] = this.mouseover;
                    elem["onmouseout"] = this.mouseout;
            }
        }

            window.onresize = this.resize;
        window.onmouseover = this.mouseover;
        window.onmouseout = this.mouseout;
}


//permet de temporiser et éviter les erreurs de chargement des objets
function temporise_Init(Lastdiv){
if(document.getElementById){
    if(document.getElementById(Lastdiv)){

    eleban_createallarea();

    myInstOne = new myObjfloater('b_menumap11', 'pc_menu1', 1, 0);

    globalize = new image_resizer(document.getElementById('pc_redim'));
    globalize.init();
        globalize.resize();



    }else{
    setTimeout(temporise_Init(Lastdiv), 30);
    }
}
}


window.onload = function () {
temporise_Init("pc_bandeau");
}

3
que hace esto
user8408080
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.