Pregunta Detección de línea horizontal con OpenCV


Estoy tratando de encontrar líneas horizontales y verticales a partir 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.

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 existe otro tipo de transformación que pueda usar que me permita encontrar de manera confiable líneas horizontales y verticales (y preferiblemente líneas punteadas también).

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

¡Gracias! Patricio.


20
2017-08-29 07:01


origen


Respuestas:


¿Has visto una muestra de código de HoughLinesP documentación de la función?

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

ACTUALIZAR:

Como veo, necesitas encontrar no las líneas, sino horizontales y verticales 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 de Canny con HoughLinesP. Aquí está mi código (he usado Python, pero creo que ves 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 se ve así:


25
2017-08-29 10:19



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.


8
2017-07-27 12:46



Puede considerar abandonar la detección de línea 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 tubería fue:

  1. Convertir de RGB a escala de grises (cvCvtColor)
  2. Suave (cvSmooth)
  3. Umbral (cvThreshold)
  4. Detectar bordes (cvCanny)
  5. Buscar 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 por el buscador de contorno , área del contorno (cvContourArea), etc. Desde mi experiencia, esperaría que las líneas "válidas" en su aplicación tuvieran propiedades de área y recuento de vértices bien definidas. Además, puede filtrar los contornos en función de la distancia entre los extremos. puntos, ángulo definido por la línea que conecta los puntos finales, etc.

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


5
2017-08-29 18:30



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.


5
2018-02-25 15:24