Tengo un conjunto de imágenes, cada una con una tabla. Algunas imágenes tienen las tablas alineadas y los bordes están dibujados, no es difícil identificar la tabla principal en esas imágenes usando la detección de bordes Canny. Sin embargo, algunas imágenes tienen sus tablas sin bordes, por lo que estoy tratando de identificar la tabla en una imagen y trazar los contornos de los bordes y las columnas.

Estoy usando la versión 3.4 de openCV y el enfoque que adopto generalmente es el siguiente:

  1. dilatar la imagen en escala de grises para identificar los puntos de texto
  2. aplique la función cv2.findContours para obtener los cuadros delimitadores del texto.
  3. agrupe los cuadros delimitadores en caso de que se hayan identificado tablas más pequeñas en lugar de la tabla principal.
  4. Trate de dibujar los contornos con la esperanza de identificar los bordes de la mesa.

Este enfoque parece funcionar hasta cierto punto, pero los contornos dibujados no son del todo precisos.

    img, contours, hierarchy = cv2.findContours(gray_matrix, cv2.RETR_LIST, 
    cv2.CHAIN_APPROX_SIMPLE)

    # get bounding boxes around any text
    boxes = []
    for contour in contours:
        box = cv2.boundingRect(contour)
        h = box[3]

    rows = {}
    cols = {}

    # Clustering the bounding boxes by their positions
    for box in boxes:
        (x, y, w, h) = box
        col_key = 10 # cell threshold
        row_key = 10 # cell threshold
        cols[row_key] = [box] if col_key not in cols else cols[col_key] + [box]
        rows[row_key] = [box] if row_key not in rows else rows[row_key] + [box]

    # Filtering out the clusters having less than 4 cols
    table_cells = list(filter(lambda r: len(r) >= 4, rows.values()))
    # Sorting the row cells by x coord
    table_cells = [list(sorted(tb)) for tb in table_cells]

    table_cells = list(sorted(table_cells, key=lambda r: r[0][1]))

    #attempt to identify columns

    max_last_col_width_row = max(table_cells, key=lambda b: b[-1][2])
    max_x = max_last_col_width_row[-1][0] + max_last_col_width_row[-1][2]

    ver_lines = []

    for box in table_cells:
        x = box[0][0]
        y = box[0][1]
        hor_lines.append((x, y, max_x, y))

    for box in table_cells[0]:
        x = box[0]
        y = box[1]
        ver_lines.append((x, y, x, max_y))

    (x, y, w, h) = table_cells[0][-1]
    ver_lines.append((max_x, y, max_x, max_y))
    (x, y, w, h) = table_cells[0][0]
    hor_lines.append((x, max_y, max_x, max_y))

    for line in ver_lines:
        [x1, y1, x2, y2] = line
    cv2.line(output_image, (x1, y1), (x2, y2), (0, 0, 255), 1)

    cv2.imshow('Proper Table Borders', output_image)

Estoy tratando de lograr algo como la imagen de abajo.

a busy cat

En resumen, ¿cómo puedo encontrar los bordes invisibles de una estructura de tabla en una imagen, así como identificar las coordenadas x de las columnas de la tabla identificada?

Sé que el código anterior no es en absoluto óptimo para producir el resultado requerido, pero todavía estoy aprendiendo openCV, así que estoy probando varios enfoques pero aún no alcancé el resultado deseado.

0
ramez 16 oct. 2019 a las 16:40

1 respuesta

La mejor respuesta

Pruebe el perfil vertical, que es el recuento de píxeles de texto (negros) con la misma coordenada X en cierto rango (Y0, Y1) (extensión vertical de la tabla). Las regiones cero o cercanas a cero indicarán los bordes de las columnas de la tabla. Aquí hay un perfil aproximado dibujado a mano para su ejemplo:

enter image description here

1
Paul Jurczak 18 oct. 2019 a las 07:21