20

Estoy tratando de encontrar líneas horizontales y verticales de una imagen que proviene de un "documento". Los documentos son páginas escaneadas de contratos y, por lo tanto, las líneas se parecen a lo que vería en una tabla o en un bloque de contrato.Detección de línea horizontal con OpenCV

He estado probando OpenCV para el trabajo. La implementación de la transformada Hough en OpenCV me pareció útil para el trabajo, pero no pude encontrar ninguna combinación de parámetros que le permitiera encontrar limpiamente las líneas verticales y horizontales. Intenté con y sin detección de bordes. Sin suerte. Si alguien ha hecho algo similar, me interesa saber cómo.

Vea aquí una imagen de mi experimentación antes y después con HoughP en OpenCV. Es lo mejor que puedo hacer, http://dl.dropbox.com/u/3787481/Untitled%201.png

Así que ahora me pregunto si hay otro tipo de transformación que podría usar que me permita encontrar de manera confiable líneas horizontales y verticales (y preferiblemente también líneas punteadas).

Sé que este problema se puede solucionar porque tengo las herramientas Nuance y ABBYY OCR que pueden extraer de manera fiable las líneas horizontales y verticales y devolverme el cuadro delimitador de las líneas.

Gracias! Patrick.

Respuesta

25

¿Has visto un ejemplo de código de HoughLinesP documentación de la función?

Creo que puede usarlo como punto de partida para su algoritmo. Para elegir líneas horizontales y verticales solo necesita filtrar otras líneas por ángulo de línea.

ACTUALIZACIÓN:

Como veo que no necesita encontrar las líneas verticales, pero un bordes horizontales en la página. Para esta tarea, debe combinar varios pasos de procesamiento para obtener buenos resultados.

Para su imagen, puedo obtener buenos resultados al combinar la detección de bordes Canny con HoughLinesP. Aquí está mi código (que he usado pitón, pero creo que se ve la idea):

img = cv2.imread("C:/temp/1.png") 
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
edges = cv2.Canny(gray, 80, 120) 
lines = cv2.HoughLinesP(edges, 1, math.pi/2, 2, None, 30, 1); 
for line in lines[0]: 
    pt1 = (line[0],line[1]) 
    pt2 = (line[2],line[3]) 
    cv2.line(img, pt1, pt2, (0,0,255), 3) 
cv2.imwrite("C:/temp/2.png", img) 

El resultado será similar a:

+0

Hola Andrey, gracias. Sí, probé HoughLinesP con muchas variables diferentes. Ajusté mi pregunta original e incluí un enlace a la mejor imagen que pude obtener de HoughLinesP. Y sí, traté de restringirme solo a líneas casi horizontales. –

+0

Genial. Claramente, me faltaba el detector Canny. Ese es un buen resultado. También encontré un algoritmo llamado Ortogonal Zig-Zag que puede tomar las líneas provistas y luego expandirlas para determinar también el ancho de la línea (algo que HoughP no puede hacer). –

+0

sin punto y coma en python;) – mak

5

Se podría considerar dejar la detección línea de Hough ya que este método busca líneas "globales", no necesariamente segmentos de línea. Recientemente implementé una aplicación que identificaba "paralelogramos", esencialmente cuadrados que podían rotarse y acortarse en perspectiva debido al ángulo de visión. Puede considerar algo similar.Mi oleoducto fue:

  1. Convertir de RGB a escala de grises (cvCvtColor)
  2. liso (cvSmooth)
  3. Umbral (cvThreshold)
  4. bordes detectar (cvCanny)
  5. Encuentra contornos (cvFindContours)
  6. Contornos aproximados con características lineales (cvApproxPoly)

En su aplicación, la lista de contorno resultante probablemente será grande (dependiendo de la "agresividad" del suavizado y la mejora de características del detector de bordes Canny). Puede podar esta lista mediante una variedad de parámetros: número de puntos devueltos desde el buscador de contorno, área del contorno (cvContourArea), etc. Desde mi experiencia, esperaría que las líneas "válidas" en su aplicación estuvieran bien definidas propiedades de área y conteo de vértices. Además, puede filtrar los contornos en función de la distancia entre los puntos finales, el ángulo definido por la línea que conecta los puntos finales, etc.

Según la cantidad de "tiempo" de CPU que tenga, siempre puede emparejar el algoritmo Hough con un algoritmo como el anterior para identificar robustamente las líneas horizontales y verticales.

8

Si solo quiere las "líneas" y no los "segmentos de línea", evitaría usar Canny, Hough, FindContours o cualquier otra función en caso de que quiera más velocidad en su código. Si sus imágenes no se giran y lo que desea encontrar es siempre vertical u horizontal, simplemente usaría cv :: Sobel (una para verticales y otra para horizontales) y crearía matrices de acumulación para columnas y filas. Luego puede buscar máximos en tales acumulaciones o perfiles, por ejemplo, estableciendo un umbral, y sabrá la fila o columna en la que hay líneas de borde verticales u horizontales.

+1

¿Conoce los parámetros que se deben establecer para las líneas horizontales y verticales en cv :: sobel? –

4

No convierta el RGB a escala de grises. A veces, diferentes colores en RGB se pueden combinar con el mismo valor de escala de grises, por lo que podría perder algunos contornos. Debe analizar cada uno de los canales RGB por separado.