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

如何在pytesseract的image_to_boxes中降低文本粒度实现单词级框选?

解决单词级文本边界框识别问题

针对你遇到的情况,给你几个实用的解决思路:

1. 调整Tesseract的页面分割模式(PSM)

image_to_data出现漏检,大概率是页面分割模式参数没适配你的图片。可以根据文本排版尝试不同的PSM参数:

  • 如果图片是单行文本,用psm=7
  • 如果是整块无格式的文本块,用psm=6
  • 多行规整文本可以用默认psm=3搭配--oem=3(混合引擎模式)

示例代码:

import pytesseract
from PIL import Image

img = Image.open("你的图片.png")
# 配置单行文本识别模式
custom_config = r'--oem 3 --psm 7'
data = pytesseract.image_to_data(img, config=custom_config, output_type=pytesseract.Output.DICT)

# 过滤空文本条目,提取单词级框
word_boxes = []
for i in range(len(data['text'])):
    text = data['text'][i].strip()
    if text:
        x = data['left'][i]
        y = data['top'][i]
        w = data['width'][i]
        h = data['height'][i]
        word_boxes.append((x, y, x+w, y+h, text))

2. 手动合并image_to_boxes的字符框为单词框

如果调整PSM后效果仍不好,可以用image_to_boxes拿到每个字符的框,再根据位置特征合并成单词:

  • 同一行的字符(y轴范围重叠)
  • 字符间的水平间距小于设定阈值(比如字符宽度的一半)

示例代码:

import pytesseract
from PIL import Image

img = Image.open("你的图片.png")
img_height = img.height
boxes = pytesseract.image_to_boxes(img).splitlines()
word_boxes = []
current_word = []
line_y_min, line_y_max = None, None

for box in boxes:
    char, x1, y1, x2, y2, _ = box.split()
    x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
    # 转换坐标(Tesseract的y轴从图片底部开始计算)
    y1, y2 = img_height - y1, img_height - y2

    if not current_word:
        current_word.append((x1, y1, x2, y2, char))
        line_y_min, line_y_max = y1, y2
    else:
        # 判断是否为同一行且间距符合单词内字符的间距
        same_line = abs(y1 - line_y_min) < 10 and abs(y2 - line_y_max) < 10
        gap = x1 - current_word[-1][2]
        if same_line and gap < 20:  # 间距阈值可根据图片实际情况调整
            current_word.append((x1, y1, x2, y2, char))
        else:
            # 合并当前单词的边界框
            word_x1 = min([b[0] for b in current_word])
            word_y1 = min([b[1] for b in current_word])
            word_x2 = max([b[2] for b in current_word])
            word_y2 = max([b[3] for b in current_word])
            word_text = ''.join([b[4] for b in current_word])
            word_boxes.append((word_x1, word_y1, word_x2, word_y2, word_text))
            current_word = [(x1, y1, x2, y2, char)]
            line_y_min, line_y_max = y1, y2
# 处理最后一个单词
if current_word:
    word_x1 = min([b[0] for b in current_word])
    word_y1 = min([b[1] for b in current_word])
    word_x2 = max([b[2] for b in current_word])
    word_y2 = max([b[3] for b in current_word])
    word_text = ''.join([b[4] for b in current_word])
    word_boxes.append((word_x1, word_y1, word_x2, word_y2, word_text))

3. 图片预处理优化

针对字体过大、字母间距大的情况,预处理能提升Tesseract的识别准确性:

  • 对图片做二值化处理,减少背景干扰
  • 调整对比度,强化文本边缘
  • 适当缩放图片,让字符大小更贴合Tesseract的默认识别范围

示例二值化代码:

img = Image.open("你的图片.png").convert('L')
threshold = 127
# 把灰度图转为黑白二值图
img = img.point(lambda x: 0 if x < threshold else 255, '1')

内容的提问来源于stack exchange,提问作者Bex T.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:25:07