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

为何使用Tesseract无法精准识别清晰可见的数字?

Tesseract数字识别效果不佳的问题

尝试用Tesseract检测数字,图像背景噪声极低、为清晰单行样式,但识别效果始终不理想。已制作最小测试用例,先后对图像执行去除红通道、转灰度、二值化预处理,还尝试了缩放、降噪模糊、膨胀、腐蚀及不同PSM、OEM模式的组合处理。

测试图像

测试数字图像

实际识别输出

img:                       2 22419 2330
blur:                      23 22419 226 16 333 03
Erode: 
Dilate:                    22 22419 266330
Morphology:                2 22419 24
BlurMorphology:            2222419 26 116
BlurErode: 
BlurDilate:                23 22419 226633 3 03
BlurErodeDilate:           22 22419 226 16 3343 03
BlurErodeDilateMorphology: 2222419 26 116

期望输出

23 22 4 19 2 2 6 11 6 3 3 14 3 4 4 4 10 3 11 9

相关代码

from pytesseract import pytesseract
import os
import cv2
import numpy as np

# 切换工作目录到脚本所在文件夹
os.chdir(r'C:\Users\tesseract')

path_to_tesseract = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
pytesseract.tesseract_cmd = path_to_tesseract

def remove_noise(image):
    return cv2.medianBlur(image,5)
 
def dilate(image):
    kernel = np.ones((4,4),np.uint8)
    return cv2.dilate(image, kernel, iterations = 1)
    
def erode(image):
    kernel = np.ones((4,4),np.uint8)
    return cv2.erode(image, kernel, iterations = 1)

def morphology(image):
    kernel = np.ones((5,5),np.uint8)
    return cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)

def boundingBox(name, img):
    hImg, wImg, _ = img.shape
    h, w, c = img.shape
    boxes = pytesseract.image_to_boxes(img, config = "_char_whitelist=0123456789") 
    for b in boxes.splitlines():
        b = b.split(' ')

        x, y, w, h = int(b[1]), int(b[2]), int(b[3]), int(b[4])
        img = cv2.rectangle(img, (x, hImg - y), (w, hImg - h), (0, 255, 0), 2)
        cv2.putText(img, b[0], (x, hImg - y + 13), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (50, 205, 50), 1)

    cv2.imshow(name, img)
    cv2.waitKey(0)

def findNumbers(img, name):
    text = pytesseract.image_to_string(img, config = "-c tessedit"
            "_char_whitelist=' '0123456789"
            " --psm 3 "
            "lang='eng'")
    # 打印结果
    print(str(name) + ": " + str(text))

    
img = cv2.imread('testData2.png')
#-------------------------------------------------------------------
# 第一阶段预处理
Blur = remove_noise(img)
Erode = erode(img)
Dilate = dilate(img)
Morphology = morphology(img)

# 第二阶段预处理
BlurErode = erode(Blur)
BlurDilate = dilate(Blur)
BlurMorphology = morphology(Blur)

# 第三阶段预处理
BlurErodeDilate = dilate(BlurErode)

# 第四阶段预处理
BlurErodeDilateMorphology = morphology(BlurErodeDilate)
#-------------------------------------------------------------------
# 第一阶段输出
findNumbers(img, "img")
findNumbers(Blur, "blur")
findNumbers(Erode, "Erode")
findNumbers(Dilate, "Dilate")
findNumbers(Morphology, "Morphology")
# 第二阶段输出
findNumbers(BlurMorphology, "BlurMorphology")
findNumbers(BlurErode, "BlurErode")
findNumbers(BlurDilate, "BlurDilate")
# 第三阶段输出 
findNumbers(BlurErodeDilate, "BlurErodeDilate")
# 第四阶段输出
findNumbers(BlurErodeDilateMorphology, "BlurErodeDilateMorphology")
#-------------------------------------------------------------------
# 第一阶段检测框标注
boundingBox('img', img)
boundingBox('Blur', Blur)
boundingBox('Erode', Erode)
boundingBox('Dilate', Dilate)
boundingBox('Morphology', Morphology)
# 第二阶段检测框标注
boundingBox('BlurErode',BlurErode)
boundingBox('BlurDilate',BlurDilate)
# 第三阶段检测框标注
boundingBox('BlurErodeDilate',BlurErodeDilate) 
# 第四阶段检测框标注
boundingBox('BlurErodeDilateMorphology', BlurErodeDilateMorphology) 

解决方案

1. 优化预处理流程

当前预处理未落实灰度化和自适应二值化的核心步骤,Tesseract对单通道灰度图识别效果远优于彩色图。调整步骤:

  • 先将彩色图转为灰度图
  • 采用自适应二值化,避免全局二值化丢失局部细节
  • 缩小降噪、形态学操作的核尺寸,防止过度腐蚀/膨胀破坏数字结构

2. 调整Tesseract配置参数

  • PSM模式:替换默认的--psm 3为--psm 7(将图像视为单行文本),匹配图像的单行特征
  • 字符白名单:修正语法错误,正确格式为-c tessedit_char_whitelist=" 0123456789"
  • OEM模式:添加--oem 3,启用LSTM+传统引擎的混合模式,提升识别精度

3. 修改后的代码示例

from pytesseract import pytesseract
import os
import cv2
import numpy as np

os.chdir(r'C:\Users\tesseract')
path_to_tesseract = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
pytesseract.tesseract_cmd = path_to_tesseract

def preprocess_image(img):
    # 转灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 自适应二值化
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
    # 轻度降噪
    denoised = cv2.medianBlur(thresh, 3)
    return denoised

def findNumbers(img, name):
    # 优化后的识别配置
    config = r'-c tessedit_char_whitelist=" 0123456789" --psm 7 --oem 3'
    text = pytesseract.image_to_string(img, config=config, lang='eng')
    print(f"{name}: {text.strip()}")

img = cv2.imread('testData2.png')
processed_img = preprocess_image(img)

# 测试识别效果
findNumbers(processed_img, "processed_img")

# 查看预处理后的图像
cv2.imshow("Processed Image", processed_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

4. 额外优化建议

  • 若存在数字粘连,可尝试垂直形态学梯度分割字符
  • 将图像放大1-2倍,提升小数字的识别清晰度
  • 针对图像中的字体训练自定义Tesseract字库,进一步优化识别准确率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:45:45