Encontrar cuadrados en la imagen

34

Necesito encontrar los cuadrados en una imagen usando OpenCV (no hay problema en matlab o cualquier otro, generalmente lo que espero son algunas ideas).

Considere la imagen de prueba a continuación:

ingrese la descripción de la imagen aquí

Necesito encontrar esos cuadrados de colores en la imagen de arriba con precisión (no las tiras largas blancas).

Que he hecho :

  • Apliqué el método común (que viene con muestras OpenCV), es decir, encontrar contornos en todos los planos de color, aproximarlo y verificar el número de elementos = 4. Funciona hasta cierto punto que, se detectan pocos cuadrados, especialmente los oscuros.

  • El siguiente paso que hice fue la predicción . es decir, este arreglo es fijo . Entonces, si se obtienen algunos, puedo predecir los restantes. También funcionó hasta cierto punto. Pero la precisión fue muy mala.

Pero siento que la predicción no es un buen método aquí y no siempre proporciona respuestas precisas como las da el primer paso.

Lo que necesito :

1) ¿Hay algún otro método mejor para detectar estos cuadrados con mayor precisión? O múltiples métodos?

Un punto importante es que el tiempo no es un problema aquí . El algoritmo puede ser lento, no importa. Pero la precisión es el criterio principal.

A veces, las imágenes pueden ser mucho más borrosas.

Y uno de los principales problemas que enfrenté es que algunos cuadrados tienen un color casi similar al del fondo (verifique los primeros y segundos cuadrados de la columna 3).

Buscando ideas, gracias de antemano

ACTUALIZACIÓN

A continuación se muestra el resultado máximo exacto que obtuve:

ingrese la descripción de la imagen aquí

Por supuesto, la imagen resultante cambia de tamaño un poco.

ACTUALIZACIÓN 2:

He dado una solución mucho mejor en mi respuesta a continuación: https://dsp.stackexchange.com/a/7526/818

Abid Rahman K
fuente
¿Tu fondo es siempre blanquecino?
1
mi idea era calcular la "saturación" y limitar el valor de sat sat pero usando su ejemplo no funciona muy bien (calculando la saturación como max (RG, RB, GB). El hecho de que algunos de los cuadrados se vean casi como el fondo hace que la cosa es bastante difícil. Si todas sus imágenes tienen el mismo patrón (largas franjas blancas con cuadrados al lado), debería considerar encontrar los bits más fáciles (como los cuadrados realmente coloreados o las franjas blancas) deduzca la posible ubicación para otros cuadrados y ... encontrar una manera de comprobar si son realmente allí o not.Tough pero interesante le puede dar más imágenes!?
Bueno, creo que esto no debería haberse movido.
Junuxx
1
¿Puedes proporcionar más imágenes? Además, ¿qué es esta cosa?
Andrey Rubshtein
2
OP necesita responder algunas preguntas. Quizás el fondo blanco no sea necesario. ¿Y qué pasa con la luz? ¿Va a ser tan malo? Estos me parecen una complejidad innecesaria.
Tae-Sung Shin

Respuestas:

9

Un primer intento con Matlab:

im = imread('squares.jpg');
im2 = rgb2gray(im);

se = strel('disk', 15);

for i = 1:16;
    t = 60+i*5; % try out a range of bw thresholds to see what works best
    labelled = bwlabel(im2>t); % label regions in the BW image
    closed = imclose(labelled, se); % close small regions
    cleared = imclearborder(~closed,4); % clear regions touching the border
    subplot(4,4,i); 
    imshow(cleared); 
    title(['T = ' num2str(t)]);
end

Resultados en las siguientes regiones:

regiones etiquetadas

Como puede ver, seleccionar el umbral que da como resultado el mayor número de regiones (T = 120) ya daría 7 ubicaciones correctas, algunas ubicaciones fusionadas, un falso positivo y dos falsos negativos.

Este fue un intento bastante simple, pero creo que muestra que el enfoque funciona. Agregar algunas cosas para dividir regiones alargadas, o hacer esto para cada canal de color por separado, son solo algunas de las cosas que puede hacer para mejorar esto.

También ayudaría si proporcionara algunas imágenes de prueba más.

Junuxx
fuente
8

Había intentado algo más para mejorar mi resultado en cuestión. La siguiente solución supone que el primer cuadrado (naranja) siempre se detecta en el paso 1. Y es práctico debido a su alto contraste de color en comparación con el fondo. Incluso el resultado que mostré en cuestión lo ha detectado correctamente

Paso 1: Encuentra tantos cuadrados como sea posible

Dividí la imagen en planos R, G, B, H, S, V y puse un umbral de la imagen para diferentes valores de umbral, como múltiplos de 25. Para cada imagen, encontré cuadrados en ella y los puse en una "imagen de máscara" . También encontré la altura y el ancho promedio del cuadrado.

imagen de máscara (total 7/12 cuadrados detectados):

imagen de máscara

Paso 2: forma una cuadrícula de cuadrados

Luego encontré los centroides de estos cuadrados en la imagen de la máscara. Los clasifiqué y encontré el centroide del primer cuadrado (naranja). A partir de un análisis detallado, podemos ver que la brecha entre dos cuadrados es un cuadrado tanto en dirección horizontal como vertical. Entonces, de esta manera, hice una cuadrícula de cuadrados como a continuación y la llamé ideal_squares (es solo un nombre, no significa que este sea el resultado que necesito):

Cuadrados ideales:

imagen ideal

Paso 3: reasigna la imagen ideal

Ahora tenemos los centroides ideal_squares y los centroides originales. Descubrí las coincidencias correctas para cada centroide original de ideal_centroids (tomando la distancia euclidiana entre ellos). Luego utilicé Scipy interpolate.griddata para la interpolación y reasigne la imagen ideal según los valores del centroide (es casi lo mismo que la deformación realizada en estas preguntas y respuestas: cómo eliminar defectos de convexidad en el cuadrado de sudoku y la transformación de imagen en OpenCV ). Así que a continuación se muestra la salida que obtuve:

Salida:

Imagen de salida

Paso 4: O opere por encima de la salida con la imagen de máscara del primer paso

salida final

Ahora puede ver que se detectan todos los cuadrados, pero con un problema mencionado a continuación:

Problema:

Mire la salida del Paso 3, es decir, la imagen reasignada de la cuadrícula cuadrada. Excepto dos cuadrados centrales, todos los otros cuadrados están recortados. Es un problema asociado con esta reasignación. No estoy seguro de dónde está el problema, con scipy.interpolate.griddata () o cv2.remap (). Pensé que toda la imagen se deformaría, pero no lo es. Solo deforma la imagen dentro de los centroides que le dimos. Si puedo corregir eso, la salida estará bien.

Entonces, si alguien conoce una buena idea para eso, ¡bienvenido!

Abid Rahman K
fuente
5

Nota: Este método va a ser realmente lento.

Genere una máscara que se parezca a los contornos de un objeto ideal. Similar a ésto:

máscara del objeto

luego deslice (posición, escala, rotación) la máscara sobre la imagen y combínela con el contorno de la imagen real (quizás borrosa un poco para obtener una respuesta más suave) para calcular cuán similares son, la (posición, escala, rotación) con La respuesta de mayor similitud debe ser la (posición, escala, rotación) del objeto real.

Al método no le importan los cuadrados que se mezclan en el fondo o incluso las oclusiones parciales del objeto, ya que considera todo el objeto.

Personalmente, he utilizado este método con éxito para rastrear el hocico y los bigotes de un mouse, pero tenía algunas presunciones como si estuviera cerca de la última posición conocida, etc. Pero creo que puede reducir el espacio de búsqueda aplicando algunas suposiciones como: tamaños posibles del objeto en la cámara, a qué distancia del centro puede estar o rotación <10 grados, etc.

Jim Delgado
fuente
5

Paso 1: Cualquiera que sea la imagen binaria final que obtenga al analizar en el plano B, G, R, H, S, V, en esa imagen haga un algoritmo de conteo de manchas.

Paso 2: Encuentra la gota más grande en función del área o la longitud del contorno. Dado que sus blobs serán en su mayoría tipos de paralelogramo, por lo que el área o el contorno, cualquiera lo hará.

Paso 3: con el blob más grande (dado que el blob más grande es el mejor blob que se asemeja a sus cuadrados del mundo real) intente encontrar la orientación del blob ... esto puede obtener ajustando un rectángulo que mejor se ajuste O puede obtener los puntos de esquina ... obtenga la pendiente de las líneas que las unen (tanto en el horizonte como en la dirección vertical).

Paso 4: Una vez que obtengas las dos pendientes, dibuja dos líneas que atraviesen el eje de la burbuja. para el eje puede promediar los puntos de esquina o puede usar el centroide (centro de masa) ... Yo iría con el promedio de puntos de esquina ...

Paso 5: Dado que en cada dirección horizontal y vertical, el espaciado es igual (idealmente, el espaciado horizontal y vertical también es igual, ya que proviene de su imagen cuadrada ideal, pero no lo asumiremos ...) solo necesita ubicar los posibles centroides del otro paralelogramos

LÍNEA INFERIOR: si se detecta perfectamente un cuadrado, puede hacer toda la cuadrícula. Simplemente mantenga los centros de marcado en un intervalo de 2H (H = ancho horizontal de la gota más grande) a lo largo del eje horizontal de la gota más grande y en un intervalo de 2V (V = altura vertical de la gota más grande) verticalmente a lo largo del eje vertical de la gota.

Algunas fotos para apoyar ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

imagen_rotación
fuente
1
+1: sería genial si pudieras implementarlo.
Abid Rahman K
2
@AbidRahmanK Para eso no es StackExchange. Pregunta -> Respuesta. De lo contrario, esto terminaría siendo una feria de trabajo.
Jan Krüger
2

este arreglo es fijo

Realmente no sé qué tipo de predicción hiciste antes, pero ¿has tratado de enfocarte en las largas franjas blancas como raíz? Luego (si 3 columnas de cuadrados son del mismo tamaño), puede detectar la altura de un cuadrado (distancia entre las dos tiras) y puede detectar el área máxima y mínima (altura y ancho) en la imagen.

Luego, intente detectar el color más común dentro de todo su cuadrado y configúrelo en un área "no cuadrada". Se supone que el resto son los cuadrados que estás buscando.


fuente
Encontré 3-4 cuadrados usando el método de contorno. Luego obtuve la altura y el ancho de cada cuadrado. Luego se verificó el espacio entre los cuadrados detectados y se supuso si el espacio entre ellos es lo suficientemente grande como para contener otro cuadrado. Esa es la predicción que hice.
Abid Rahman K
Algunos cuadrados tienen un color casi similar al del fondo. Así que me temo que también se considerarán como áreas no cuadradas según su método.
Abid Rahman K
Tal vez podría intentar trabajar en cada columna para trazar una curva donde el eje x sería la altura (en píxeles) de la imagen y el eje y sería la intensidad. Luego, podría intentar encontrar algunos bordes de corte con la forma derivada.
eso es detección de bordes en sí, ¿verdad? Lo intenté, pero no obtuve un buen resultado.
Abid Rahman K
1
Sí, lo es, pero podría ver por sí mismo por qué falla y tal vez aislar algunas regiones interesantes en la trama. Por cierto, si encuentra algunos consejos útiles para resolver su problema, publíquelos. Buena suerte para tus investigaciones
0

Sugeriría usar la transformación Hough, que es un algoritmo muy robusto para encontrar formas paramétricas simples, por ejemplo, líneas, círculos, etc. La detección de líneas sería la mejor en su caso. Podrías encontrar los lados de los largos sripes blancos al menos; luego, con cualquier algoritmo de extracción de esquinas (Harris o tal vez incluso SIFT o SURF) podría encontrar esquinas a lo largo de esas líneas, incluso utilizando el hecho de que los cuadrados están aproximadamente espaciados por igual.

canahari
fuente