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

如何优化Pytesseract从低质量小尺寸数字图像中提取文本的准确率?

如何优化Pytesseract从低质量小尺寸数字图像中提取文本的准确率?

问题背景

我正在尝试用pytesseract从图像中提取数字,它能识别部分数字(1、2、3、5、6、20...),但没法覆盖所有情况。我用的图像尺寸很小(75x26),字体质量一般,但人眼可以清晰识别。

我试过一些预处理,比如对比度增强:

from PIL import Image, ImageEnhance

image = Image.open(f"{i}.png")
gray = image.convert("L")
enhancer = ImageEnhance.Contrast(gray)
image_enhanced = enhancer.enhance(2.0)
text = pytesseract.image_to_string(image_enhanced, config="--psm 6 -c tessedit_char_whitelist=0123456789")
print(text)

也试过用OpenCV做阈值处理,但效果还是不好(比如识别不出1,把11识别成0,把9识别成3...):

img = cv2.imread(f'/content/{i}.png')
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 170, 255, cv2.THRESH_BINARY)
text = pytesseract.image_to_string(thresh, config="--psm 6 -c tessedit_char_whitelist=0123456789")

想知道有没有更多预处理步骤能提升识别准确率?我知道可以微调pytesseract,但觉得这应该是基础问题,不想先花太多时间在微调上。


我的解决方案

嘿,我之前也踩过类似小尺寸低质量数字识别的坑,结合实战经验给你几个针对性的优化方向,应该能解决你识别7、11、415这类数字的难题:

  • 优先放大图像,解决小尺寸核心问题
    Tesseract的训练样本大多是常规尺寸的文本,75x26的小图像特征太模糊,先把图像放大2-4倍(用高质量插值算法,避免边缘锯齿),会让数字的轮廓特征清晰很多。比如用PIL实现:
from PIL import Image, ImageEnhance

image = Image.open(f"{i}.png")
# 放大3倍,用LANCZOS插值保持清晰度
scaled_image = image.resize((image.width*3, image.height*3), Image.Resampling.LANCZOS)
gray = scaled_image.convert("L")

用OpenCV的话可以这么写:

img = cv2.imread(f'/content/{i}.png')
img = cv2.resize(img, None, fx=3, fy=3, interpolation=cv2.INTER_LANCZOS4)
  • 替换固定阈值为自适应阈值,适配局部明暗
    你用的固定阈值(170)没法适配所有图像的明暗差异,自适应阈值会根据每个局部区域的亮度自动调整阈值,对付这类模糊字体效果更好。注意如果你的数字是深色、背景浅色,记得用THRESH_BINARY_INV反转颜色,让数字变成白色、背景黑色,更贴合Tesseract的训练习惯:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 自适应阈值:blockSize选奇数(比如11),C是微调偏移量(比如2)
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
  • 调整PSM参数,精准匹配单数字串场景
    你用的--psm 6是假设图像是一块均匀文本,但对于单数字串,试试--psm 8(假设图像是单个词)或者--psm 10(假设图像是单个字符),这两个参数能让Tesseract更聚焦于你的目标内容:
text = pytesseract.image_to_string(thresh, config="--psm 8 -c tessedit_char_whitelist=0123456789")
# 记得strip()去掉多余的换行和空格
print(text.strip())
  • 用形态学操作修复字体瑕疵
    有些模糊数字会有断笔、毛刺,用OpenCV的闭运算修复断笔,开运算去除毛刺,让数字轮廓更规整:
# 创建3x3的矩形结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
# 闭运算:先膨胀后腐蚀,填补断笔
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# 开运算:先腐蚀后膨胀,去除毛刺
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
  • 组合预处理流程,效果翻倍
    把上面的步骤组合起来,完整流程大概是:
  1. 放大图像 → 2. 转灰度 → 3. 自适应阈值二值化(反转) → 4. 形态学修复 → 5. Tesseract识别

我之前用这套流程解决过类似的小尺寸数字识别问题,识别准确率提升非常明显,不需要微调模型就能覆盖大部分场景。


备注:内容来源于stack exchange,提问作者User_123917425

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 16:55:26