如何通过示例训练Pytesseract提升大数字与特殊字符识别准确率?
Pytesseract识别数字与特殊字符的优化方案
问题概述
- 带空格分隔的大数字识别不全:比如4 000 000被识别为4或4 000,5 311 111被识别为531 111
- 数字0与其他字符混淆,特殊符号($、₽、€)识别错误:$被识别为8/5,₽被识别为2
- 调整阈值后无明显改善,询问是否可通过图像示例训练Pytesseract区分易混淆字符
一、无需训练的快速优化方案
先试试这些低成本调整,多数场景下能解决问题:
1. 调整Tesseract配置参数
- 补全字符白名单:当前配置只允许数字,要加上需要识别的特殊符号,修改为:
-c tessedit_char_whitelist=0123456789€$₽ - 优化PSM模式:PSM 7适合单行文本,但带空格的大数字可以试试PSM 6(把图像视为单一文本块)或PSM 8(单一单词),同时开启空格保留:
-c preserve_interword_spaces=1 - 完整配置示例:
--psm 6 --oem 3 -c tessedit_char_whitelist=0123456789€$₽ -c preserve_interword_spaces=1
2. 图像预处理升级
- 替换固定阈值为自适应阈值:适合光照不均的屏幕截图,避免部分字符被误过滤:
blackAndWhiteImage = cv2.adaptiveThreshold(grayImage, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) - 形态学膨胀增强字符:填补字符边缘的小缺口,让字符轮廓更清晰:
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2)) blackAndWhiteImage = cv2.dilate(blackAndWhiteImage, kernel, iterations=1) - 放大图像:针对小尺寸的数字,放大后能提升识别精度:
scale_percent = 200 # 放大2倍 width = int(grayImage.shape[1] * scale_percent / 100) height = int(grayImage.shape[0] * scale_percent / 100) grayImage = cv2.resize(grayImage, (width, height), interpolation=cv2.INTER_CUBIC)
二、自定义训练Pytesseract(针对顽固混淆字符)
如果上述方法无效,可以针对易混淆字符训练自定义模型,步骤如下:
1. 准备训练数据
- 收集目标字符的图像:每个易混淆字符(0、8、$、₽、€等)准备50-100张,覆盖实际场景中的字体、大小、光照变化
- 用jTessBoxEditor工具标注字符:生成对应
.box(字符位置+标签)和.tif文件,也可手动编写.box文件(适合少量字符)
2. 训练流程(Tesseract 4.x版本)
- 在Tesseract的
tessdata目录下新建自定义语言文件夹(比如mynum) - 生成训练基础文件:
tesseract your_image.tif your_image nobatch box.train - 提取字符集:
unicharset_extractor your_image.box - 创建字体配置文件
font_properties,内容示例:
其中screen_font 0 0 0 0 0screen_font是你训练用的字体名称,后面5个0分别代表加粗、倾斜等属性 - 生成特征文件:
shapeclustering -F font_properties -U unicharset your_image.tr mftraining -F font_properties -U unicharset -O mynum.unicharset your_image.tr cntraining your_image.tr - 重命名生成的4个文件:
inttemp→mynum.inttemp、pffmtable→mynum.pffmtable、normproto→mynum.normproto、shapetable→mynum.shapetable - 合并生成自定义模型:
combine_tessdata mynum. - 在代码中使用自定义模型:
text = pyt.image_to_string(blackAndWhiteImage, config="--psm 6 --oem 3 -c tessedit_char_whitelist=0123456789€$₽", lang='mynum')
三、优化后的完整代码示例
import cv2 import pytesseract as pyt def read_image(tresh, path, img, show=False): originalImage = cv2.imread(f"{path}\\{img}") grayImage = cv2.cvtColor(originalImage, cv2.COLOR_BGR2GRAY) # 自适应阈值处理 blackAndWhiteImage = cv2.adaptiveThreshold(grayImage, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 形态学膨胀增强字符 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2)) blackAndWhiteImage = cv2.dilate(blackAndWhiteImage, kernel, iterations=1) # 优化后的Tesseract配置 config = "--psm 6 --oem 3 -c tessedit_char_whitelist=0123456789€$₽ -c preserve_interword_spaces=1" text = pyt.image_to_string(blackAndWhiteImage, config=config) string = text.strip().replace("\n", "") return string
内容的提问来源于stack exchange,提问作者the shadow
相关产品推荐
相关产品推荐

