完成了opencv基础知识学习,现在进行实践操作
1、生成随机四位数字验证码
import os
import random
# captcha是用于生成验证码图片的库,可以 pip install captcha 来安装它
from captcha.image import ImageCaptcha
def random_captcha_text(num):
# 验证码列表
captcha_text = []
for i in range(10): # 0-9数字
captcha_text.append(str(i))
# for i in range(65, 91): # 对应从“A”到“Z”的ASCII码
# captcha_text.append(chr(i))
# for i in range(97, 123): # 对应从“a”到“z”的ASCII码
# captcha_text.append(chr(i))
# 从list中随机获取6个元素,作为一个片断返回
example = random.sample(captcha_text, num)
# 将列表里的片段变为字符串并返回
verification_code = ''.join(example)
return verification_code
# 生成字符对应的验证码
def generate_captcha_image():
image = ImageCaptcha()
# 获得随机生成的验证码
captcha_text = random_captcha_text(4)
# 把验证码列表转为字符串
captcha_text = ''.join(captcha_text)
# 生成验证码
path = 'D:/验证码识别/test/'
if not os.path.exists(path):
print("目录不存在!,已自动创建")
os.makedirs(path)
print("生成的验证码的图片为:", captcha_text)
image.write(captcha_text, path + captcha_text + '.png')
if __name__ == '__main__':
number = 100
for i in range(number):
generate_captcha_image()
2、安装pytesseract包,中间出现很多问题,最终查阅资料得以解决
3、对验证码图片进行预处理
图像预处理主要包括对图像的灰度化、二值化、去噪声,以及图像倾斜的矫正和增强等。
(1)灰度化:
对图像进行灰度处理,是为了减少识别样本的计算量,将图像样本统一,简化训练和识别难度。
Gray=0-299R+0.587G+0.114B(1)
(2)二值化:
二值化指将图像上的像素点转化为黑白两种颜色的点,即将灰度值设置为0(黑)或255(白)。其目的是区分图像的前后景,使图像呈现明显的视觉效果,同时为后续的识别和处理做准备。我试了几种二值化的方法最后选择了OTSU,可以明显发现图像中有一些横线和小点点的干扰
# 二值图像就是将灰度图转化成黑白图,没有灰,在一个值之前为黑,之后为白
# 有全局和局部两种
# 在使用全局阈值时,我们就是随便给了一个数来做阈值,那我们怎么知道我们选取的这个数的好坏呢?答案就是不停的尝试。
# 如果是一副双峰图像(简 单来说双峰图像是指图像直方图中存在两个峰)呢?
# 我们岂不是应该在两个峰之间的峰谷选一个值作为阈值?这就是 Otsu 二值化要做的。
# 简单来说就是对 一副双峰图像自动根据其直方图计算出一个阈值。
# (对于非双峰图像,这种方法 得到的结果可能会不理想)。
(3)去噪声:
图像中往往含有噪声,要对图形进行噪声处理,减少噪声影响,将噪声干扰降到最低,我采用开运算,因为开运算的特性,正好可以降低干扰。
然后再试着改变kernel算子的值,我先设置的是(2,2)效果如上图,后来找到最合适的是(3,3)
基本没有小白点了
开运算:先进性腐蚀再进行膨胀就叫做开运算,它被用来去除噪声。
闭运算:先膨胀再腐蚀。它经常被用来填充前景物体中的小洞,或者前景物体上的小黑点。
这里我们用到的函数是 cv2.morphologyEx()。
开闭操作作用:
1. 去除小的干扰块-开操作
2. 填充闭合区间-闭操作
3. 水平或垂直线提取,调整kernel的row,col值差异。
比如:采用开操作,kernel为(1, 15),提取垂直线,kernel为(15, 1),提取水平线,
"""
def recongize_text(image):
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
cv.imshow("gray1",gray)
gray=interference_line(gray)
cv.imshow("gray2",gray)
ret,binary=cv.threshold(gray,0,255,cv.THRESH_BINARY_INV|cv.THRESH_OTSU)
# binary = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 25, 10)
kernel=cv.getStructuringElement(cv.MORPH_RECT,(3,4))
open_out=cv.morphologyEx(binary,cv.MORPH_OPEN,kernel)
# open_out=cv.morphologyEx(open_out,cv.MORPH_CLOSE,kernel)
cv.imshow("binary_image",open_out)
cv.bitwise_not(open_out,open_out)
cv.imshow("dd",open_out)
result = np.array(open_out)
ss = cv.medianBlur(result, 5)
cv.imshow('66666.png', ss)
textImage=Image.fromarray(ss)
target = tess.image_to_string(textImage)
print("识别结果:%s "%target)
但是由于,tesseract这个库识别的效果并不是很理想,他会自动把数字识别成其他的符号或者字母
或者直接识别不出来,不同的验证码,需要选取不同的opencv图像处理方式
所以上网查阅资料,自己创建库
(4)tesseract训练
大体流程为:安装jTessBoxEditor -> 获取样本文件 -> Merge样本文件 –> 生成BOX文件 -> 定义字符配置文件 -> 字符矫正 -> 执行批处理文件 -> 将生成的traineddata放入tessdata中
1、用jTessBoxEditor把要训练样本图片文件合并成tif文件(样本图片一定要为有效的格式图片)
运行jTessBoxEditor程序,界面如下:
点击顶栏的Tools选项,选择Merge TIFF.. 进入你要训练的样本图片所在的目录,点击Ctrl+Alt+A,选择所有图片点击打开:
然后保存文件名到指定目录,我这里保存的文件名为: langyp.font.exp0.tif
2、生成Box文件
打开cmd,到你langyp.font.exp0.tif文件所在目录,执行:
tesseract langyp.font.exp0.tif langyp.font.exp0 batch.nochop makebox
结果生成了langyp.font.exp0.box文件
3、 对样本图片用jTessBoxEditor工具进行矫正
点击jTessBoxEditor工具的Box Editor选项,点击下方的open选项,打开刚刚生成的langyp.font.exp0.tif文件,结果如下:
右侧为对应的Box文件数据,如果char的字符和当前的样本图片一致时就进行矫正,修改char里的字符,然后进行save,这样就矫正了,进入下张样本图片时,同样,矫正后点击save,当所有样本图片都矫正了,这一步也就完成了
4、生成font_properties文件(该文件没有后缀名)
在命令行执行:echo font 0 0 0 0 0 >font_properties
结果生成了font_properties文件
内容为字体名font,后面带5个0,分别代表字体的粗体、斜体等属性,这里全部是0
5、生成.tr训练文件
在命令行执行: tesseract langyp.font.exp0.tif langyp.font.exp0 -l eng -psm 7 nobatch box.train
6、生成字符集文件
在命令行执行 : unicharset_extractor langyp.font.exp0.box
结果生成了unicharset文件
7、生成shape文件
在命令行执行 : shapeclustering -F font_properties -U unicharset -O langyp.unicharset langyp.font.exp0.tr
结果生成了shapetable文件和langyp.unicharset文件
8、生成聚集字符特征文件
在命令行执行: mftraining -F font_properties -U unicharset -O langyp.unicharset langyp.font.exp0.tr
结果生成了pffmtable,inttemp,unicharset文件
9、生成字符正常化特征文件
在命令行执行: cntraining langyp.font.exp0.tr
结果生成了normproto文件
10、把h,i步骤生成的文件用rename命令进行更名
在命令行执行:
**rename normproto fontyp.normproto
rename inttemp fontyp.inttemp
rename pffmtable fontyp.pffmtable
rename unicharset fontyp.unicharset
rename shapetable fontyp.shapetable**
11、合并训练文件
在命令行执行: combine_tessdata fontyp.
12、将fontyp.traineddata文件拷贝至Tesseract-OCR文件夹里的tessdata语言包文件夹里
windows下面: