Pregunta

Tengo una imagen con líneas horizontales y verticales. De hecho, esta imagen es el sitio web de la BBC convertido en líneas horizontales y verticales. Mi problema es que quiero poder encontrar todos los rectángulos en la imagen. Quiero escribir un programa de computadora para encontrar todos los rectángulos. ¿Alguien sabe cómo hacer esto o sugerir ideas sobre cómo comenzar? Esta tarea es fácil para mí como persona para encontrar los rectángulos visuales, pero no estoy seguro de cómo describirlo como un programa.

La imagen es el sitio web de la BBC aquí http://www.bbc.co.uk/


Actualice esto, escribí el código que convierte la imagen del sitio web de la BBC en la línea horizontal y vertical, el problema es que estas líneas no se encuentran completamente en las esquinas y, a veces, no forman completamente un rectángulo. Gracias!

¿Fue útil?

Solución

Opencv (procesamiento de imágenes y biblioteca de visión por computadora escrita en c) tiene implementación para la transformación completa ( la simple transformación transforma las líneas de búsqueda en una imagen, mientras que la generalizada busca objetos más complejos), por lo que podría ser un buen comienzo. Para los rectángulos que tienen esquinas cerradas también hay detectores de esquinas, como cornerHarris, que pueden ayudar.

Ejecuté la demostración de houghlines provista con opencv y aquí está el resultado en la imagen que proporcionó (líneas detectadas marcadas en rojo): texto alternativo ??
(fuente: splintec.com )

Otros consejos

Creo que está buscando la transformación Hough generalizada .

En la visión por computadora hay un algoritmo llamado Transformación Hough generalizado que quizás pueda resolver su problema . Debe haber un código fuente abierto que haya implementado este algoritmo. Solo búscalo.

Suponiendo que es una imagen razonablemente libre de ruido (no un video de una pantalla), entonces uno de los algoritmos simples de relleno debería funcionar. Es posible que deba ejecutar una dilatación / erosión en la imagen para cerrar los huecos.

La forma normal de encontrar líneas es una transformación de Hough (luego encontrar líneas en ángulo recto) Opencv es la forma más fácil.

Eche un vistazo a esta pregunta Detección de objetos OpenCV - Punto central

Hay varios enfoques diferentes para su problema. Usaría una herramienta procesamiento de imágenes morfológicas como este . Tendrá la flexibilidad de definir " rectángulo " incluso algo que no está "exactamente cerrado" (donde el algoritmo de relleno fallará).

Otra posibilidad podría ser utilizar un enfoque de aprendizaje automático , que básicamente es más datos- impulsado que impulsado por la definición como el anterior. Tendrá que dar a su algoritmo varios "ejemplos". de lo que es un rectángulo, y eventualmente aprenderá (con un sesgo y una tasa de error) .

itere de izquierda a derecha hasta que toque un píxel de color y luego use el algoritmo de relleno de inundación modificado. más información sobre algo flood fill @ wiki

otro enfoque sería encontrar CUALQUIER píxel de color en la imagen y luego ir con

while(pixel under current is colored)
{
  lowest pixel coordinate = pixel under current
  current = pixel under
}

luego haz lo mismo hacia arriba. ahora has definido una sola línea. luego use los extremos de las líneas para hacer coincidir aproximadamente las líneas en rectángulos. si no son perfectos en píxeles, podría hacer algún tipo de tenencia de la propiedad.

El relleno de inundación funcionaría, o podría usar una modificación de un algoritmo de seguimiento de bordes.

lo que haces es: cree una matriz 2d (o cualquier otra estructura de datos d2): cada fila representa una línea de píxeles horizontal en la pantalla y cada columna una línea vertical

recorra todos los píxeles, de izquierda a derecha, y cada vez que encuentre uno de color agregue sus coordenadas a la matriz

iterar a través de la matriz y encontrar líneas y almacenar el píxel inicial y final para cada uno (estructura de datos diferente)

sabiendo que el comienzo de cada línea es su píxel izquierdo / superior, puede verificar fácilmente si alguna de las 4 líneas comprende un rectángulo

Para pasar de la imagen que tiene con las líneas horizontales y verticales casi conmovedoras a solo los rectángulos:

  1. Convertir a binario (es decir, todas las líneas son blancos, el resto es negro)
  2. Realiza una dilatación binaria (aquí haces cada píxel que toca un píxel blanco en la imagen de origen o es un píxel blanco en la imagen de origen blanco. El tacto es solo recto (por lo que cada píxel "toca" los píxeles a su izquierda, derecha, arriba y debajo de él) esto se denomina "4-conectado" ;
  3. repita el paso 3 varias veces si los espacios entre los extremos son mayores que 2 píxeles de ancho, ¡pero no con demasiada frecuencia!
  4. Realice una operación de esqueleto (aquí hace que cada píxel en la imagen de salida sea negro si es un píxel blanco en la imagen de origen que toca al menos un píxel negro y los píxeles blancos que toca (en la imagen de origen) se tocan entre sí Nuevamente, toque definido con conexión 4. Vea el ejemplo a continuación.
  5. Repita el paso 4 hasta que la imagen no cambie después de una repetición (todos los píxeles blancos son extremos de línea o conectores)

Esto, con un poco de suerte, mostrará primero los cuadros con líneas gruesas y gruesas, dejando artefactos gruesos y gruesos en toda la imagen (después del paso 3) y luego, después del paso 5, se habrán eliminado todos los artefactos gruesos y gruesos, mientras que Quedan todas las cajas. Debe ajustar el número de repeticiones en el paso 3 para obtener mejores resultados. Si está interesado en la morfología de la imagen, este es el libro de un curso introductorio realmente bueno que tomé.

Muestra: (0 = negro, 1 = blanco, se están considerando píxeles en el centro de cada bloque 3x3, entrada izquierda, salida derecha)

011 => 011    
011 => 001  all other white pixels touch, so eliminate      
011 => 011    

010 => 010    
010 => 010  top pixel would become disconnected, so leave      
010 => 010    

010 => 010    
010 => 000  touches only one white pixel, so remove     
000 => 000    

010 => 010    
111 => 111  does not touch black pixels, leave    
010 => 010    

010 => 010    
011 => 011  other pixels do not touch. so leave    
000 => 000    
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top