Я пытаюсь извлечь табличные данные из отсканированного технического документа.
Таблица содержит:
- объединенные ячейки заголовка
- неправильную высоту строк
- неправильную ширину столбцов
- тусклый свет и сломанные границы
- текст внутри каждой ячейки
- вертикальные штрихи в тексте, похожие на границы
- технические символы и логотипы
- исправить строки
- исправить столбцы
- исправить объединенные ячейки
- исправить текст OCR внутри каждой ячейки
Решение, которое сможет:
- Обнаруживать истинные горизонтальные и вертикальные линии
- Точно восстанавливать сетку таблицы
- Определять и обрабатывать объединенные ячейки
- Извлечение OCR ячейка за ячейкой в правильном порядке чтения
- Создание структурированного вывода (например, Pandas DataFrame), соответствующего исходному макету
Я пробовал несколько подходов на основе OpenCV, но ни один из них не смог точно восстановить таблицу.
Ниже приводится краткое описание каждого метода и причины его неудачи.
1. Обнаружение клеток по контурам
Код: Выделить всё
cnts, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
- текст внутри ячеек создает дополнительные контуры.
- линии сетки, соприкасающиеся с текстом, сливаются в большие неправильные многоугольники.
- трудно добиться порядка чтения.
- объединенные ячейки нарушают иерархию.
- Строка заголовка разбивается на множество подконтуров
Код: Выделить всё
lines = cv2.HoughLinesP(binary, 1, np.pi/180, threshold=50)
- частичные слабые линии обнаруживаются при большом количестве сегментов.
- невозможно отличить ломаные границы от шума.
- короткие текстовые штрихи («I», «|», «1») обнаруживаются как вертикальные линии.
- слияние точно сегментировать прямые становится очень сложно
Горизонтальные линии:
Код: Выделить всё
h_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (80, 1))
h_lines = cv2.morphologyEx(bw, cv2.MORPH_OPEN, h_kernel)
Код: Выделить всё
v_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 80))
v_lines = cv2.morphologyEx(bw, cv2.MORPH_OPEN, v_kernel)
- вертикальные штрихи таких букв, как «M», «I», «H», «T», «1» распознаются как линии столбцов.
- небольшие горизонтальные штрихи под текстом распознаются как линии строк.
- строка заголовка разбивается на 10–20 false. столбцы
- слабые разорванные границы создают несколько строк
4. Фильтрация связанных компонентов
Я попробовал строгую фильтрацию:
Код: Выделить всё
if h >= 0.7 * image_height and w = min_height and w < 10:
out[y:y+h, x:x+w] = 255
return out
v_lines = filter_vertical(raw_v, int(0.7 * img.shape[0]))
cv2.imwrite("vlines_debug.png", v_lines)
Кадр данных Pandas, где:
- положения ячеек соответствуют реальной структуре таблицы
- объединенные ячейки уважаемый
- данные извлечены в правильном порядке чтения
- макет таблицы соответствует отсканированному изображению
Я открыт для:
- Решения только для OpenCV
- Модели структуры таблиц на основе машинного обучения
- гибридные подходы
- или предложения по более надежным инструментам
Подробнее здесь: https://stackoverflow.com/questions/798 ... lls-from-a
Мобильная версия