jTessBoxEditorFX训练数据步骤
字库训练
下载jTessBoxEditorFX
https://sourceforge.net/projects/vietocr/files/jTessBoxEditor/
文件名必须是如下格式:
[lang].[fontname].exp[num]
lang:语言名(训练生成的示为语言)
fontname:字体名
num:序号(无所谓)
于是可以得到一个命名为 num.peng.exp1.tif 的文件
1、准备样本图片,合并为.tif文件
jTessBoxEditorFX -> tools->merge tiff
2、生成.bok文件
tesseract num.peng.exp1.tif num.peng.exp1 batch.nochop makebox
3、字符矫正
jTessBoxEditorFX -> Box Editor->Open,num.peng.exp1.tif,调整校正
生成训练数据
示例假设有3个文件,tif文件
1、创建font_properties文件
文件内容为 :
<fontname> <italic> <bold> <fixed> <serif> <fraktur> # eg: echo peng 0 0 0 0 0 > font_properties
2、产生字符特征文件.tr
tesseract num.peng.exp1.tif num.peng.exp1 nobatch box.train tesseract num.peng.exp2.tif num.peng.exp2 nobatch box.train tesseract num.peng.exp3.tif num.peng.exp3 nobatch box.train
3、计算字符集文件 unicharset
unicharset_extractor num.peng.exp1.box num.peng.exp2.box num.peng.exp3.box
4、聚集字符特征 生成文件 shapetable
shapeclustering -F font_properties -U unicharset num.peng.exp1.tr num.peng.exp2.tr num.peng.exp3.tr mftraining -F font_properties -U unicharset -O num.unicharset num.peng.exp1.tr num.peng.exp2.tr num.peng.exp3.tr cntraining num.peng.exp1.tr num.peng.exp2.tr num.peng.exp3.tr
5、重命名
mv shapetable num.shapetable && \ mv normproto num.normproto && \ mv inttemp num.inttemp && \ mv pffmtable num.pffmtable
6、生成字库
combine_tessdata num.
参考
文字识别 OCR 训练样本
基于Tesseract的OCR识别
Tesseract-OCR-3.0.5 数字识别训练与合并多次训练数据
python tesseract 4.0 安装踩过的坑(基于macOS )
综合示例
1、数据合成助手
假设只有一个tif文件 num.peng.exp1.tif
上面的步骤有点多,合成一个脚本便于使用
备注:需要设置好环境变量:TESSDATA_PREFIX
traindata.sh
#!/bin/bash # 所用到的变量 lang="num" fontname="peng" num="1" name="${lang}.${fontname}.exp${num}" # 环境变量中需要设置好资源文件路径 TESSDATA_PREFIX 重启电脑生效 if [ -e "${name}.tif" ]; then echo "文件存在" else echo "文件不存在: ${name}.tif" exit 0 fi # 生成box box=$1 if [[ ${box} == 'box' ]]; then echo "生成box" tesseract "${name}.tif" ${name} batch.nochop makebox exit 0 else echo "生成训练数据" fi # 1、创建font_properties文件 echo 'peng 0 0 0 0 0' > font_properties && \ # 2、产生字符特征文件.tr tesseract "${name}.tif" ${name} nobatch box.train && \ # 3、计算字符集文件 unicharset unicharset_extractor "${name}.box" && \ # 4. 聚集字符特征 生成文件 shapetable shapeclustering -F font_properties -U unicharset "${name}.tr" && \ mftraining -F font_properties -U unicharset -O "${lang}.unicharset" "${name}.tr" && \ cntraining "${name}.tr" && \ # 5、重命名 mv shapetable "${lang}.shapetable" && \ mv normproto "${lang}.normproto" && \ mv inttemp "${lang}.inttemp" && \ mv pffmtable "${lang}.pffmtable" && \ # 6、生成字库 combine_tessdata "${lang}." && \ # 拷贝字库 cp *.traineddata ${TESSDATA_PREFIX} && \ echo "完成"
使用方式
将文件拷贝到样本数据目录下
# 生成box文件 bash traindata.sh box # 生成traineddata文件 bash traindata.sh
2、数据准备
执行下面的python代码,在目录sample下生成10个样本
VerifyCode.py
# -*- coding: utf-8 -*- import random import string from PIL import Image, ImageFilter, ImageFont, ImageDraw class VerifyCode(object): @classmethod def get_char(cls): """获取一个字母或数字 """ return random.choice( string.ascii_letters + string.digits ) @classmethod def get_num(cls): """获取一个字母或数字 """ return random.choice(string.digits) @classmethod def get_color1(cls): """获取颜色值 3元组 """ return ( random.randint(64, 255), random.randint(64, 255), random.randint(64, 255) ) @classmethod def get_color2(cls): return ( random.randint(32, 127), random.randint(32, 127), random.randint(32, 127) ) @classmethod def get_code(cls, num): lst = [] for idx in range(num): lst.append(cls.get_char()) return ''.join(lst) @classmethod def get_num_code(cls, num): lst = [] for idx in range(num): lst.append(cls.get_num()) return ''.join(lst) @classmethod def get_verifycode_image(cls, code, save_path): """生成字母验证码图片 @param n: {int} 字母数量 @param save_path: {str} 保存路径 @return: None """ # 图片尺寸 width = 60 * len(code) height = 60 image = Image.new("RGB", (width, height), (255, 255, 255)) # 创建Font对象 font = ImageFont.truetype('Arial.ttf', 36) # 创建Draw对象 draw = ImageDraw.Draw(image) # 填充每个像素 # for x in range(width): # for y in range(height): # draw.point((x, y), fill=cls.get_color1()) # 输出文字 for idx in range(len(code)): draw.text((60 * idx + 10, 10), code[idx], font=font, fill='black') # 模糊处理 # image = image.filter(ImageFilter.BLUR) image.save(save_path, "jpeg", dpi=(300.0, 300.0)) if __name__ == '__main__': for i in range(10): code = VerifyCode.get_num_code(4) VerifyCode.get_verifycode_image(code, f"sample/{code}.jpg")
3、数据训练
(1)第一次识别测试
直接使用tesseract 识别生成的数据
# -*- coding: utf-8 -*- import glob import os import pytesseract from PIL import Image def to_string(filename): name, ext = os.path.splitext(filename) code = name.split("/")[-1] img = Image.open(filename) img = img.convert("L") # 转为黑白图 ret = pytesseract.image_to_string(img) print(code, ret) lst = glob.glob("sample/*.jpg") for file in lst: to_string(file)
第一次识别结果:
实际内容 识别结果 3791 379 1 7455 7455 7195 8502 5502 1107 9375 9375 3498 3493 0384 0354 6519 4631 463 1
(2)第二次识别测试
增加参数 --psm 6
ret = pytesseract.image_to_string(img, config='--psm 6')
实际内容 识别结果 3791 3791 7455 7455 7195 7195 8502 5502 <- 1107 1107 9375 9375 3498 3493 <- 0384 0354 <- 6519 6519 4631 4631
(3)第三次识别
上面的步骤总结为4步:
(3.1)先使用jTessBoxEditorFX生成tif文件
jTessBoxEditorFX -> tools->merge tiff
(3.2)生成box文件
bash traindata.sh box
(3.3)校正数据
jTessBoxEditorFX -> Box Editor->Open,num.peng.exp1.tif,调整校正
(3.4)生成traineddata文件
bash traindata.sh
添加参数lang='num'
后,识别数据
ret = pytesseract.image_to_string(img, lang='num', config='--psm 6')
训练数据后,100%准确率
实际内容 识别结果 3791 3791 7455 7455 7195 7195 8502 8502 1107 1107 9375 9375 3498 3498 0384 0384 6519 6519 4631 4631
(4)第四次识别
再使用VerifyCode.py文件生成10个新的验证码图片,再试试
新数据的准确率也是100%
实际内容 识别结果 2465 2465 8765 8765 1912 1912 5815 5815 3704 3704 0974 0974 9548 9548 4236 4236 2655 2655 3763 3763