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

如何使用pytesseract获取文本图像整行/整段文本边界框坐标

问题根因

之前的实现未得到预期整行/整段外框,核心原因有两个:

  • 自定义行合并的边界框更新逻辑错误:行/段外框是包裹所有子文本块的最小矩形,不能直接累加top、width、height参数,必须对同组所有单词框取坐标极值计算
  • 自行判断同行的逻辑可靠性差:pytesseract.image_to_data本身返回了完整的层级ID字段,不需要自己写坐标阈值判断行归属,自定义规则很容易因行间距、字体偏移出现错判,导致合并失败
正确实现方案

image_to_data返回结果自带3个层级标识字段,可直接用于分组:

  • block_num:检测到的独立文本块ID
  • par_num:文本块内的自然段落ID
  • line_num:段落内的行ID
    以上字段搭配页码字段page_num可唯一定位到一行,搭配block_num可唯一定位到一个段落/文本块。

完整实现代码

import cv2
import pytesseract
from pytesseract import Output
import pandas as pd

# 读取图像
img = cv2.imread("your_text_image.png")
# 获取OCR原始结果,lang参数按需替换为对应的语言包
ocr_result = pytesseract.image_to_data(img, output_type=Output.DICT, lang='eng+chi_sim')
# 转为DataFrame并过滤无效条目
df = pd.DataFrame(ocr_result)
df = df[
    df['text'].notna() 
    & (df['text'].str.strip() != '') 
    & (df['conf'] != -1) # 过滤置信度为-1的无效识别结果
].reset_index(drop=True)
# 坐标列转为数值类型,避免字符串计算错误
for col in ['left', 'top', 'width', 'height']:
    df[col] = pd.to_numeric(df[col])

# 计算行级外框
line_groups = df.groupby(['page_num', 'block_num', 'par_num', 'line_num'])
line_df = []
for group_key, group in line_groups:
    page, block, para, line = group_key
    # 取极值计算最小外框
    left = group['left'].min()
    top = group['top'].min()
    right = (group['left'] + group['width']).max()
    bottom = (group['top'] + group['height']).max()
    line_df.append({
        'page_num': page,
        'block_num': block,
        'par_num': para,
        'line_num': line,
        'left': left,
        'top': top,
        'width': right - left,
        'height': bottom - top,
        'text': ' '.join(group['text'].str.strip().tolist())
    })
line_df = pd.DataFrame(line_df)

# 计算段落级外框
para_groups = df.groupby(['page_num', 'block_num', 'par_num'])
para_df = []
for group_key, group in para_groups:
    page, block, para = group_key
    left = group['left'].min()
    top = group['top'].min()
    right = (group['left'] + group['width']).max()
    bottom = (group['top'] + group['height']).max()
    para_df.append({
        'page_num': page,
        'block_num': block,
        'par_num': para,
        'left': left,
        'top': top,
        'width': right - left,
        'height': bottom - top,
        'text': ' '.join(group['text'].str.strip().tolist())
    })
para_df = pd.DataFrame(para_df)

# 绘制结果验证
# 红色线绘制行级框
for _, row in line_df.iterrows():
    cv2.rectangle(
        img,
        (row['left'], row['top']),
        (row['left'] + row['width'], row['top'] + row['height']),
        (0, 0, 255),
        2
    )
# 蓝色线绘制段落级框
for _, row in para_df.iterrows():
    cv2.rectangle(
        img,
        (row['left'], row['top']),
        (row['left'] + row['width'], row['top'] + row['height']),
        (255, 0, 0),
        1
    )
cv2.imwrite("ocr_box_result.png", img)
关键规则说明

同一分组(行/段落/整页)的外框计算必须遵循极值规则:

  • 外框左边界 = 组内所有单词框left的最小值
  • 外框上边界 = 组内所有单词框top的最小值
  • 外框右边界 = 组内所有单词框left + width的最大值
  • 外框下边界 = 组内所有单词框top + height的最大值
  • 外框宽度 = 右边界 - 左边界
  • 外框高度 = 下边界 - 上边界

如果需要整页文本的全局外框,直接对所有有效单词框套用以上极值规则计算即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 04:09:31