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:
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:
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
fuente
Respuestas:
Un primer intento con Matlab:
Resultados en las siguientes regiones:
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.
fuente
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):
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:
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:
Paso 4: O opere por encima de la salida con la imagen de máscara del primer paso
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!
fuente
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:
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.
fuente
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
fuente
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
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.
fuente
Intenté este problema usando opencv, python. El enfoque implica enmascarar la imagen en función de los colores, seguido de la búsqueda de contornos adecuados.
Código: https://github.com/rbhambriiit/computer_vision/blob/master/find_color_box
[Se perdió 1 casilla, pero eso debería venir ajustando la función de enmascaramiento]
fuente