Skip to the content.

带线框表格识别设计

使用入口见 Inference README。本模块复用 本地 OCR 的模型、运行环境、固定字节快照、输入预算和进程生命周期,在 OCR 之前提取直线网格,再以几何关系分配文字。没有新模型或新的项目,也不依赖表格版面模型。

支持定义

候选表格必须是 EXIF 归一化后轴对齐的横竖直线网格,有闭合外框,至少包含两个基础格。每个基础格的 x/y 间距都必须至少为 MinimumLineLength,默认 40 像素:小于同一形态学核的独立分隔段会被抹去,无法可靠区分短边缺失与合并。降低该参数可接收小格,也会提高文字笔画和图形形成伪网格的风险。1×N 和 N×1 支持,孤立矩形框不返回 1×1 表格。可从缺失的内部边界识别矩形合并格;所有合并格必须完整覆盖网格,不能重叠、留洞、形成 L 形或保留悬空内部线。

无框、旋转、透视、曲线和外边不闭合的图像不属于支持范围,通常返回空表格集合;形态学识别不是严格的输入类型分类器,不能保证对所有超范围图像均返回空。普通文本仍可得到 OCR 结果,但不能只凭文字行间距创建表格。大号网格状字形或图案与真实表格可能具有相同可见结构,纯几何方法不能保证区分语义;结果统一标记 ReviewRecommended=true,不表达语义表格分类准确率。

图像中完整缺失的一条内部边,与有意合并单元格在视觉上可能相同。模块按可见矩形结构解释,不能恢复原作者的表格意图。如果某条分割线在所有行或列都消失,就没有足够证据恢复原来的分割坐标;输出只反映仍可观察到的网格。

线网与单元格

灰度图使用自适应二值化,再以长水平、垂直矩形结构元素做开运算。它采用 OpenCV 官方横竖线形态学提取方法中的方向结构元素思路;实现以 morphologyEx(MORPH_OPEN) 合并腐蚀和膨胀步骤。最短线长是规范化原图中的像素值,不随检测模型的缩图变化。

横竖线合并成掩码,使用 connectedComponentsWithStats 建立线网标签。每条线段只属于它实际连接到的线网,不能因为落在某个外框包络中就成为该网格的分割线。这个约束避免把字形中的长笔画、下划线等孤立成分添加为伪行或伪列。与表格线直接接触的文字仍可能污染线网,这是当前方法的限制。

每个候选的竖线 x 坐标、横线 y 坐标在容差内聚类。最外层分割坐标必须贴合该连通线网的完整包络,再检查四边覆盖率。只检查内部闭合子网会把缺失左边框的 3×3 错当成裁剪后的 3×2;包络一致性约束在四个方向共同拒绝此类错误。线宽和线端容差允许形态学处理造成少量像素扩张。

相邻分割之间形成基础格。沿每条边界的容差带检查有线像素所占比例:达到 MinimumBoundaryCoverage 视为存在,低于其补值视为缺失,处于中间的不完整边界拒绝整个候选。少量断点可能仍达到覆盖率阈值,不会被解释成合并。该阈值是几何接收规则,不是结构正确率。

沿缺失的内部边把基础格连接成组。每组必须等于自己的最小矩形行列范围,且矩形内部所有分割段都缺失;否则拒绝整个候选。单元格输出零起始行列、正的 RowSpan/ColumnSpan 和规范化原图中的整数矩形。网格没有足够外框证据时不返回部分内部表格。

真实 OCR 与唯一归属

只擦去已接收线网的线像素及一像素邻域,再调用同一个 OcrEngine 识别整张图,不为每个单元格重复加载模型。文字笔画碰到表格线时可能被一并擦去;实际跨线样本中的 Crossing 曾被识别为 Cro:ising,该区域仍完整保留为未归属文字,没有据此修正识别结果或强行放入单元格。OCR 漏检或误识别仍需宿主核对。

每个 OCR 四角框与单元格矩形用 OpenCV intersectConvexConvex 求交。仅当唯一单元格覆盖至少 80% 的文字框面积时分配给该格。跨线或无法唯一匹配的文字保留为未归属区域,不强行放入最近格。

TableRecognitionResult.Ocr.Regions 保存一次完整 OCR 结果。单元格的 RegionIndices 和结果的 UnassignedRegionIndices 引用它;索引必须恰好分配一次,不允许跨格重复或静默丢弃。Text 按文字框的最小 y、再最小 x 排序后用换行连接;这只是几何排序,不等同于语义分行、文档阅读顺序或对混排段落的理解。空单元格的文字为空字符串,索引集合为空。

最终 C# 边界重新验证 OCR 尺寸/文字/分数/坐标、表格和基础格总预算、单元格跨度的完整覆盖,以及所有文字索引的唯一归属。结果集合复制为只读对象。表格缺失不影响未归属 OCR 的返回。

生命周期与预算

OcrImageWorkspace 是从原 OCR 路径抽出的规范化图像工作区:共享 ImageCodec 的编码字节、尺寸、像素和 EXIF 行为,输出 PNG 受独立的 MaximumIntermediateBytes 限制。它只管理本次临时目录,不创建工作队列或通用 worker 框架。原图流保持打开,从调用方当前位置读取。Pillow 只接收已经规范化的 PNG,并沿用白底 alpha 合成,不能再次应用 EXIF。

每次调用独立启动 Python 进程,复用 MediaProcessRunner 的无 shell 参数传递、超时、进程树取消和诊断输出上限。没有实例级串行门,宿主负责并发控制。操作失败且清理失败时保留两者的聚合异常。源图、宿主模型目录和临时父目录不归识别器所有。

表格数、行数、列数、所有表格基础格总数,以及 OCR 的区域数、字符数、识别宽度均有显式预算;超限失败,不截断结果。基础格预算在合并之前计数,不能靠大跨度绕过网格处理限额。横/竖线组件和候选线网各最多 4,096,JSON 输出沿用 OCR 的 240,000 字符上限。字符内容在单元格便捷 Text 中还会出现一次,大量单元格/文字可能先达到序列化预算。

形态学掩码、连通标签和 OCR 光栅都是全图数组。像素限额给它们设定上界,但不会成为操作系统内存或磁盘配额;处理大图时宿主仍需按实际容量限制并发。

验证依据

Python 几何测试覆盖正常线网、四方向缺外框、孤立长笔画、rowspan/colspan/二维合并、局部断线、L 形和悬空内部线、空图/普通文本/孤立框反例,以及跨单元格文字的唯一分配。格间距覆盖 39/40 像素边界、默认单字“田”反例以及显式降低核长后的小格正例。四方向外框和孤立笔画问题均先通过回归复现,再在候选线网层修复。

C# 测试用固定真实模型识别合成中英文表格、合并格、空单元格、多行、表外文字、两张独立表格、透明背景和带 EXIF 的图像,并验证规范化像素尺寸和预先知道的网格边界。旋转/透视和破损线网保留实际 OCR,同时不返回表格。还覆盖预算、取消、流所有权、只读结果和非法/重复/遗漏索引。原 OCR 的中文、透明、EXIF、CTC 与模型字节快照回归须一并通过。

这些用例证明功能和契约,不是开放文档集上的表格准确率评测。当前方法不能替代无框表格模型、透视校正或人工核对,也不声称具有 PP-Structure 的能力。