如何用Python实现符合人类阅读顺序的文档Bounding Box排序?
文档Bounding Box贴合阅读顺序的排序方案
1. 行聚类+列划分的分层排序
- 行聚类:计算每个Box的垂直中心坐标
(y1+y2)/2,把中心距离小于Box平均高度1/3的Box归为同一行——这个阈值可根据文档字号灵活调整,目的是把同一视觉行的Box聚在一起。 - 列划分:统计所有Box的x1坐标分布,找峰值之间的谷值作为列分隔线;或者用K-means聚类x坐标,用肘部法确定最优列数,把x坐标相近的Box划到同一列。
- 排序逻辑:先按行的顶部y1从上到下排,同一行内按x1从左到右排;多栏场景下,先排完第一栏的所有行,再依次排后面的列。
2. 模拟人类阅读路径的动态排序
- 核心是模拟人读文档的跳转逻辑:从最左上角的Box开始,优先找当前Box下方同列的Box,没有的话再找右侧列的最上方Box。
- 具体步骤:
- 从所有未排序Box里挑初始节点:选y1最小的,若y1相同则选x1最小的。
- 对每个已选的Box,计算所有未排序Box的「阅读优先级」:优先级=当前Box底部y2与候选Box顶部y1的距离绝对值 + 候选Box左侧x1与当前Box右侧x2的距离绝对值——值越小,越符合阅读顺序。
- 挑优先级最高的Box加入排序结果,标记为已处理,重复直到所有Box排完。
- 多栏优化:先按x坐标聚类分好列,每列内部按y轴从上到下排,再按列的从左到右顺序拼接结果。
3. 结合布局识别的自适应排序
- 先判断页面布局类型:
- 统计所有Box的x1方差,方差小就是单栏;x1有2个明显峰值就是双栏,以此类推。
- 混合布局(比如上半双栏下半单栏):按y轴切分区域,每个区域单独判断布局类型。
- 对应排序规则:
- 单栏:直接按y1从上到下,同一行x1从左到右排。
- 多栏:先聚类分列,每列内部按y轴排序,再按列顺序拼接。
- 混合区域:每个区域单独排序后,按区域的垂直顺序拼接。
4. 优化DBSCAN列排序的方法
- 调整参数解决准确率低的问题:把eps设为页面宽度的
1/(预估列数+1),或者用Box的平均宽度做参考;min_samples设为1,避免漏掉只有少量Box的列。 - 聚类后,计算每个簇(列)的x1均值,按均值从左到右排序列,再每个列内按y1从上到下排Box。
- 跨列簇处理:如果聚类出现跨列的簇,先对簇内Box做行聚类,同一行的Box按x坐标拆分到对应列。
内容的提问来源于stack exchange,提问作者Sebas Fernández
相关产品推荐
相关产品推荐

