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

使用Tesseract识别图像中数字时检测效果不佳的技术求助

问题描述

我在对如下类型的图像进行文本检测时遇到了困难:
未预处理的图像

目前Tesseract难以将数字与图像内的图表元素区分开,我的目标是识别出所有数字及其对应的位置坐标。

我对该图像运行了如下代码,预期可以在检测到的文本周围标注矩形框:

import cv2
import pytesseract
from pytesseract import Output
import numpy as np


pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract'

img = cv2.imread('Temp/VE_cropped.png')

kernel = np.ones((2,2),np.uint8)

img_processed = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_processed = cv2.medianBlur(img_processed,3)
img_processed = cv2.threshold(img_processed, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
img_processed = cv2.dilate(img_processed, kernel, iterations = 1)

dict_wordsDetected = pytesseract.image_to_data(img_processed, output_type=Output.DICT)
img_processed = cv2.cvtColor(img_processed, cv2.COLOR_GRAY2RGB)

n_boxes = len(dict_wordsDetected['text'])
for i in range(n_boxes):
    (x, y, w, h) = (dict_wordsDetected['left'][i]
                  , dict_wordsDetected['top'][i]
                  , dict_wordsDetected['width'][i]
                  , dict_wordsDetected['height'][i])
    img_processed = cv2.rectangle(img_processed, (x - 10, y - 10), (x + w + 10, y + h + 10), (0, 0, 255), 2)
cv2.imshow("processed", img_processed)
cv2.waitKey(0)

代码运行后得到的结果如下:
运行结果

当前识别效果不符合预期,恳请各位提供可行的解决思路。


解决方案

优化思路

  • 调整Tesseract识别参数:调用image_to_data时新增配置项config='--psm 11 -c tessedit_char_whitelist=0123456789.'。--psm 11为稀疏文本模式,适配图像中零散分布的文本识别场景,白名单配置会直接过滤所有非数字、小数点的识别结果,避免把图表线条误判为字符。
  • 优化图像预处理逻辑:现有预处理的膨胀操作容易让数字和邻近的图表细线粘连,建议将单纯的膨胀替换为形态学开运算(先腐蚀再膨胀),可先断开数字和周边细线的连接,再补全数字本身的断点。另外可新增轮廓筛选步骤,提前过滤掉面积过大的图表背景、面积过小的噪点,只保留符合数字宽高比、面积区间的轮廓区域再送入识别。
  • 更换适配性更高的识别模型:如果调整后Tesseract效果仍然不符合预期,可以替换为PaddleOCR、EAST这类专门针对场景文本的识别工具,内置的数字识别预训练模型对工业图表类场景的适配性远高于默认Tesseract模型,不需要复杂预处理就能拿到准确的数字内容和对应坐标。
  • 增加后处理校验规则:可根据业务场景加规则过滤识别结果,比如该场景下数字都是带小数点的数值,长度、格式不符合的结果直接剔除,重叠度过高的重复识别结果也可以按置信度排序后去重,进一步提升准确率。

优化后代码示例

import cv2
import pytesseract
from pytesseract import Output
import numpy as np

pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract'

img = cv2.imread('Temp/VE_cropped.png')
kernel = np.ones((2,2),np.uint8)

# 优化预处理:替换为开运算,避免数字和图表线条粘连
img_processed = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_processed = cv2.medianBlur(img_processed,3)
img_processed = cv2.threshold(img_processed, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
img_processed = cv2.morphologyEx(img_processed, cv2.MORPH_OPEN, kernel, iterations=1)

# 新增Tesseract配置,限定识别范围和分割模式
custom_config = r'--psm 11 -c tessedit_char_whitelist=0123456789.'
dict_wordsDetected = pytesseract.image_to_data(img_processed, output_type=Output.DICT, config=custom_config)
img_processed = cv2.cvtColor(img_processed, cv2.COLOR_GRAY2RGB)

n_boxes = len(dict_wordsDetected['text'])
for i in range(n_boxes):
    # 新增过滤规则:空文本、置信度过低的结果直接跳过
    text = dict_wordsDetected['text'][i].strip()
    conf = int(dict_wordsDetected['conf'][i])
    if not text or conf < 60:
        continue
    (x, y, w, h) = (dict_wordsDetected['left'][i]
                  , dict_wordsDetected['top'][i]
                  , dict_wordsDetected['width'][i]
                  , dict_wordsDetected['height'][i])
    img_processed = cv2.rectangle(img_processed, (x - 2, y - 2), (x + w + 2, y + h + 2), (0, 0, 255), 2)
cv2.imshow("processed", img_processed)
cv2.waitKey(0)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 12:45:07