You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于真实自然阅读顺序对OCR识别的bbox进行排序?

基于Bounding Box的OCR文本自然阅读顺序排序方案

问题背景

  • 已完成文档OCR识别,获得每个单词的bbox坐标(x0、y0、x1、y1)及单词内容
  • OCR默认按创作者预期的“左上到右下”顺序返回结果,但存在两类排序错误:
    1. 多列文本被拆分为独立块:比如两列事件列表,本该按「年份→对应条目」的逻辑顺序(如1999 → Item 1 → 2000 → Item 2...)返回,但实际会把年份列和条目列分开,返回顺序变成所有年份在前、所有条目在后,完全打乱逻辑
    2. 倾斜文档排序失效:默认规则认为bbox位置越高(y值越小)越靠前,若文档逆时针倾斜,一行末尾的单词y值会比开头单词更小,导致被错误排到该行最前面

现有尝试与局限

  • 曾尝试计算每个bbox到文档中点的距离作为排序指标,不仅效果差,逻辑也过于复杂
  • 可行思路:通过bbox推断文本行(设置阈值适配倾斜文本),将每个bbox分配到对应行后,再按x轴位置从左到右排序,但尚未实现
  • 架构限制:无法在解析前对文档进行去倾斜处理,只能通过已有的bbox信息完成排序推断

当前代码

def read_pdf(source_path: str, **kw) -> dict:
    pages = fitz.open(source_path)
    data = {}
    for page_number, page in enumerate(tqdm(pages), start=1):
        text_blocks = page.get_text('words')
        data[page_number] = text_blocks
    return data

def calculate_distances_to_order_bboxes(document: list) -> dict:
    min_x, min_y = min([min(bbox[0], bbox[2]) for bbox in document]), min([min(bbox[1], bbox[3]) for bbox in document])
    max_x, max_y = max([max(bbox[0], bbox[2]) for bbox in document]), max([max(bbox[1], bbox[3]) for bbox in document])
    document_mid_point_x, document_mid_point_y = (min_x + max_x) / 2, (min_y + max_y) / 2
    calculations_dict = {}
    enum_id = 0
    multiplier = 1
    for x0, y0, x1, y1, word, block_no, line_no, word_no in document:
        bbox_mid_x, bbox_mid_y = (x0 + x1) / 2, (y0 + y1) / 2
        dist_to_mid_x, dist_to_mid_y = document_mid_point_x - bbox_mid_x, document_mid_point_y - bbox_mid_y
        if dist_to_mid_x < 0:
            multiplier += 0.2
        if dist_to_mid_y < 0:
            multiplier += 1
        dist_to_mid = (sqrt(dist_to_mid_x**2 + dist_to_mid_y**2)) * multiplier
        calculations_dict[enum_id] = {
            'word': word, 'x0': x0, 'y0': y0, 'x1': x1, 'y1': y1, 'bbox_mid_x': bbox_mid_x, 'bbox_mid_y': bbox_mid_y,
            'dist_to_mid_x': dist_to_mid_x, 'dist_to_mid_y': dist_to_mid_y, 'dist_to_mid': dist_to_mid
        }
        enum_id += 1
    return calculations_dict


import fitz
from tqdm import tqdm
from math import sqrt

data = read_pdf(source_path_to_pdf)
document = data[0]
calculations_dict = calculate_distances_to_order_bboxes(document)

内容的提问来源于stack exchange,提问作者qoob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 11:14:56