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

如何使用pytesseract为有意义的连续词组生成单个边界框

问题说明

使用pytesseract.image_to_data()开展OCR识别时,默认绘制所有粒度的边界框会得到单单词独立框选的效果,原始实现代码如下:

import pytesseract
from pytesseract import Output
import cv2
img = cv2.imread('Page_2.jpg')

d = pytesseract.image_to_data(img, output_type=Output.DICT)
n_boxes = len(d['level'])
for i in range(n_boxes):
    (x, y, w, h) = (d['left'][i], d['top'][i], d['width'][i], d['height'][i])
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)


cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

目标是将类似invoice number的连续有意义词组用单个边界框整体包裹。

待识别原始图片
单单词框选效果
目标整体框选效果

实现方案

方案1:调用Tesseract内置行级识别结果

image_to_data返回结果的level字段对应不同识别粒度:

  • 层级1:整页
  • 层级2:文本块
  • 层级3:段落
  • 层级4:单行文本
  • 层级5:单个单词

原始代码遍历了所有层级的框,因此拿到最细粒度的单词框。直接筛选level=4的行级结果绘制,即可得到同一行连续文本的整体边界框,代码修改如下:

import pytesseract
from pytesseract import Output
import cv2
img = cv2.imread('Page_2.jpg')

d = pytesseract.image_to_data(img, output_type=Output.DICT)
n_boxes = len(d['level'])
for i in range(n_boxes):
    # 仅绘制行级边界框
    if d['level'][i] == 4:
        x, y, w, h = d['left'][i], d['top'][i], d['width'][i], d['height'][i]
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

如果行内存在间距过大的无关文本,可在拿到行级结果后,基于行内单词的水平间距做二次过滤,仅合并间距小于阈值(通常设为平均字符宽度的1-2倍)的相邻单词,避免无关内容被整体框选。

方案2:自定义规则合并语义词组

如果需要精准框选特定语义词组(如仅框选"invoice number"这类字段,不框选整行其他内容),可按以下逻辑实现:

  1. 提取所有level=5的单词结果,记录每个单词的文本、坐标、所属行号
  2. 按行号对单词分组,同一行内单词按x轴坐标从小到大排序
  3. 遍历同组相邻单词,符合合并规则则归为同一词组:可预设目标词表匹配,也可通过单词间距、垂直对齐度判断是否属于同一语义块
  4. 合并后的词组框取组内所有单词的最小x、y为左上角,最大x+w、y+h为右下角,绘制矩形即可。
    该方案灵活度最高,可根据业务场景自由调整合并规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:57:20