复杂扫描工程文档表格结构化提取(含合并单元格、OCR)方案求助
复杂扫描工程文档表格结构化提取(含合并单元格、OCR)方案求助
我现在要处理的是扫描版工程文档里的表格提取,这个表格的情况特别棘手,具体有这些麻烦点:
- 表头存在大量合并单元格
- 行高、列宽完全不规则
- 表格边框淡、有多处断裂
- 每个单元格里都有文本内容
- 文本里的竖笔画(比如I、|、1这类)和表格边框长得几乎一样
- 还混着工程符号和logo
我的核心目标是1:1还原原表格的结构:包括正确的行列划分、合并单元格的准确识别、每个单元格的OCR文本都对应正确位置,最后输出成结构化格式(比如Pandas DataFrame)。
我需要的解决方案
我要的是能解决以下问题的完整方案:
- 精准检测出真实的表格横竖线(不管是淡的、断的都要识别到)
- 准确重建出表格的网格结构
- 正确识别并处理合并单元格
- 按人类阅读顺序逐个提取单元格的OCR文本
- 输出和原表格布局完全匹配的结构化结果(比如Pandas DataFrame)
我已经尝试过的方法(附代码)但都失败了
我试了好几种OpenCV的经典表格检测方法,但全都踩了坑,下面是每个方法的情况:
1. 基于轮廓的单元格检测
代码片段:
cnts, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
❌ 遇到的问题:
- 单元格内的文本会生成额外的小轮廓,严重干扰检测
- 碰到文本的网格线会和文本轮廓合并成不规则的大多边形,根本没法区分
- 完全搞不定单元格的阅读顺序
- 合并单元格直接破坏了轮廓的层级关系
- 表头行被拆成无数个子轮廓,根本没法正确识别
2. Hough直线变换
代码片段:
lines = cv2.HoughLinesP(binary, 1, np.pi/180, threshold=50)
❌ 遇到的问题:
- 淡的、断裂的边框被检测成一堆零散的线段
- 没法区分断裂的边框和噪声
- 文本里的短竖笔画(I、|、1)会被误判成竖线
- 要把零散的线段合并成完整的表格线,难度高到离谱
3. 形态学直线检测
代码片段:
# 检测水平线 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个假列
- 淡的断裂边框会生成多条零散的线
补充:尝试过连通域过滤但还是失败
我还加了强过滤规则,比如只保留高度≥图像高度70%、宽度≤10的竖线:
def filter_vertical(binary, min_height): num, _, stats, _ = cv2.connectedComponentsWithStats(binary) out = np.zeros_like(binary) for i in range(1, num): x,y,w,h,area = stats[i] if h >= 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]))
❌ 还是不行:真实的断裂边框会被误过滤掉,而有些文本竖笔画的高度刚好超过阈值,还是会被当成表格线,把网格拆得乱七八糟。
为什么这个问题这么难
这个工程表格的特殊点,导致纯OpenCV的几何重建完全不靠谱:
- 大量合并单元格,打破了规则的网格结构
- 多层表头进一步增加了结构复杂度
- 扫描质量差导致边框断裂、变淡
- 文本和边框经常重叠
- 文本里的竖笔画和表格边框几乎无法区分
- 内部分隔线特别淡,容易被忽略
我想请教的问题
有没有推荐的方法(纯OpenCV、混合方案、或者基于ML的模型)能解决这个棘手的问题?具体要能:
- 可靠检测表格网格(不管边框有多淡、多断)
- 完整保留表格的原始结构(包括合并单元格)
- 正确处理所有不规则的行高列宽
- 按正确阅读顺序提取每个单元格的OCR文本
我能接受的方案类型:
- 鲁棒的OpenCV流水线优化思路
- 基于深度学习的模型(比如TableNet、CascadeTabNet、YOLO表格模型这类)
- OpenCV+ML的混合方案
- 现成的、能处理这种复杂表格的工具
最小可复现代码
下面是我当前的测试代码,即使加了过滤,还是会把文本竖笔画当成表格线:
import cv2 import numpy as np img = cv2.imread("table.png") gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) bw = cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 15, 8 ) # 形态学直线检测 h_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (80, 1)) raw_h = cv2.morphologyEx(bw, cv2.MORPH_OPEN, h_kernel) v_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 80)) raw_v = cv2.morphologyEx(bw, cv2.MORPH_OPEN, v_kernel) # 过滤竖直线(仍然失败) def filter_vertical(binary, min_height): num, _, stats, _ = cv2.connectedComponentsWithStats(binary) out = np.zeros_like(binary) for i in range(1, num): x,y,w,h,area = stats[i] if h >= 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 DataFrame,满足:
- 每个单元格的位置完全对应原表格
- 合并单元格的结构被正确保留(比如跨列/跨行的单元格在DataFrame里也能体现)
- 文本按正确的阅读顺序填充
- 整体布局和扫描件里的表格完全一致
麻烦各位大佬给点建议,不管是优化思路、工具推荐还是模型用法都可以!万分感谢🙏




