如何让YOLOS预测的手写文本行边界框按图像从上到下排序?
解决手写文本行检测边界框排序问题
核心解决方案:基于坐标的后处理排序
手写文本行天然遵循从上到下、每行从左到右的阅读顺序,直接利用预测边界框的坐标即可实现排序,这是最简洁高效的方案:
步骤说明
- 提取所有预测边界框的
top(y轴起始坐标,即bbox的y1值)和left(x轴起始坐标,即bbox的x1值) - 先按top值从小到大排序,将垂直方向距离相近的框判定为同一行(可根据图像高度设置阈值,比如相邻框top差小于图像高度的5%)
- 同一行内的框再按left值从小到大排序
- 提取所有预测边界框的
示例代码
def sort_text_line_bboxes(bboxes, img_height, row_threshold=0.05): # bboxes格式示例:[{'bbox': [x1, y1, x2, y2], 'score': 0.9, ...}, ...] # y1为边界框顶部y坐标,x1为左侧x坐标 threshold = img_height * row_threshold # 先按垂直方向(top)排序 sorted_by_vertical = sorted(bboxes, key=lambda item: item['bbox'][1]) # 分组并排序每行内的框 sorted_rows = [] current_row = [sorted_by_vertical[0]] for bbox in sorted_by_vertical[1:]: # 判断是否属于同一行 if bbox['bbox'][1] - current_row[-1]['bbox'][1] < threshold: current_row.append(bbox) else: # 对当前行按水平方向(left)排序后加入结果 sorted_rows.append(sorted(current_row, key=lambda item: item['bbox'][0])) current_row = [bbox] # 处理最后一行 sorted_rows.append(sorted(current_row, key=lambda item: item['bbox'][0])) # 展平所有行得到最终排序后的边界框 return [bbox for row in sorted_rows for bbox in row]
进阶优化方案
如果手写文本存在倾斜、换行不规则等情况,可尝试以下方法:
- 基于边界框中心坐标排序:将判断条件从top改为边界框中心的y坐标,适配倾斜文本行
- 加入方向聚类:对倾斜文本行,先通过旋转角度聚类,再按旋转后的坐标排序
- 训练阶段加入顺序监督:修改数据集标注,给每个文本行添加顺序标签(如1、2、3...),在训练时加入排序损失,让模型直接学习文本行的顺序逻辑(需修改YOLOS的训练代码和损失函数)
参考资源指引
开源OCR工具(如PaddleOCR、EasyOCR)的后处理模块中,都包含成熟的文本行排序逻辑,可参考它们的实现思路,优化自己的排序代码。
内容的提问来源于stack exchange,提问作者phade 160
相关产品推荐
相关产品推荐

