关于中文点选验证码的识别
背景描述
之前对yolov3
学习了挺多,包括Keras
和Pytorch
版本的框架代码都有使用过,而且还针对网易易盾的滑块验证码做过训练和识别,因为整体上所有滑块仅可看作一类目标,所以任务比较简单;接下来打算对网易易盾的文字点选验证码进行尝试,其中又分为有语序要求和无语序要求的两类。
无语序要求
无语序要求的就是一张验证码图片上给4~5个字,然后再给你三个字,让你按顺序点击。
有语序要求
有语序要求的就是一张验证码图片上给4~5个字,但是不再直接给出让你点击的文字,而是让你根据语义顺序点击,一般是一个成语(词语)或古诗(古文里的句子,比如这里”感时花溅泪”),成语的话比较简单,利用结巴分词一般就可以解决,古诗不太好弄。
解决方案
针对文字点选类型的验证码,首先我们应该可以想到关于有语序要求的这种,实际上就涉及NLP
自然语言处理领域的技术了,所以理论上我们应该把问题的解决分为两个大的阶段
第一阶段
把图片中的每个文字的位置定位到,并且分别识别出来每个位置的字是什么,这个是计算机视觉方面的技术;
第二阶段
如果是有语序要求的验证码,要通过
NLP
方面的技术去解决,若无语序要求那就没有第二阶段。
我们可以清楚地意识到,第一阶段和第二阶段用到的技术栈相当于是完全不同的,这篇文章会介绍下关于第一阶段的一些解决思路(大部分是理论)。第二阶段会用另一篇文章分词相关的来单独介绍。
根据第一阶段工作目标的描述,我们很容易就想到两种方案。
方案一:
第一步:先定位文字,也就是仅做目标检测,所有文字认为是1类
这一步yolov3
可以轻松将问题解决,我只使用100张数据集图片就得到了一个比较不错的检测模型;
第二步:对定位区域进行切割(把字抠出来),单个文字进行识别
注意点:有些文字的角度可能不正,后面识别的时候可能需要旋转;
关于单个文字的识别方式,我能想到这样几种方式:
利用识别普通的字符验证码(只包括字母和数字)的方式我觉得应该也是可以,只不过类别更多(几千个常见文字),相应的需要的数据集更多!需要的神经网络深度更深!
还有一种比较取巧的方式——模板匹配,这个方案有个前提是验证码图片里要给出想让你点的文字
这也分两种情况:
1、验证码图片上既给了可以点击的若干个汉字,又给了想让你点击的汉字(就像上面那张图一样),也就是说你实际上也是不知道让你点的文字是什么,这个的意思是你的程序不知道(可能比较绕,希望你能懂),除非你把两个区域的文字都进行识别;
这个时候你就可以拿需要点的文字去图中匹配(
opencv
中有可用的模板匹配方法,我前面的文章也有介绍使用过),这种一般在两个区域文字字体比较相似的时候,效果好一些。2、你能通过网站直接获取到让你点击的文字,意思的是你的程序可以获取到具体的文字,那你就可以自己将文字生成到图片中,按照可以点击的汉字字体来生成,这个就需要你能找到究竟是什么字体。
还有其他类似相似度匹配的方法也是这样一个原理。
OCR识别,按照经验普通的字符验证码识别网络肯定得到的准确率不是很高,所以才会有一系列OCR识别的特殊网络被研究出来,关于OCR在文章后面的地方会单独介绍。
当然现在已经有一些通用的OCR识别接口(可能需要收费)或者模块(例如
muggle
),可以直接拿来用,针对那种字体比较“端正”,背景干扰比较少的情况,这个方法还是可行的。
第三步:返回相应文字的坐标(像素点)
方案二:
第一步:定位+分类同时实现,那就要做一个几千个类别的目标检测和分类模型
这时候第一想到的可能也是yolov3
,因为yolov3
本身就是支持目标检测+分类的算法,但是这样一个几千个类别应该不行,yolov3应该默认可以进行80个类别的分类,但是通过改写网络说不定可以。
不过我还是试了一下,使用4000+张图片,2200+个文字分类进行训练,训练到18轮mAP
还是0,所以自动就终止训练了,我推测可能是数据集太少,因为类别较多,相应的每个类别对应的图片数量就比较少了,所以不足以神经网络来提取特征。但是目前没有办法获取更多的数据集,所以没有进行下一步的工作。
按照之前字符验证码的训练经验,针对每个字符至少要有100个样本,这里4000x5/2200
,平均每个字只有不到10个样本,并且文字又比字母和数字复杂的多!
第二步:返回相应文字的坐标(像素点)
下面是在实践上述部分操作时,针对pytorch-yolov3
框架的使用记录和一些其他的技术。
pytorch-yolov3
修改anchor box尺寸和数量
针对上面方案二的第一步,因为验证码图片大小固定,且文字大小差距也不大,所以anchor box的尺寸只需要3种大小就够了,所以这里尝试了下要做哪些调整
1 | [convolutional] |
filters = x*(classes+5),x表示每个尺寸的特征图对应的anchor box大小。
yolov3
原本是输出三个尺寸的特征图,且共有9种尺寸的anchor box,相当于每个尺寸的特征图平均分得3种尺寸的anchor box,当把anchor box尺寸数量改为3,那么x就等于1了。
多分类配置cfg
文件
共2293个文字,也就是2293个分类
需要修改这两个值,共三处;x=1,fliters=1*(2293+5)
1 | filters=2298 |
Resize图片
1 | import cv2 |
切割图片
1 | from PIL import Image |
读写 xml
- 读取标注文件,并修改坐标信息
1 | import xml.dom.minidom |
- 自己编写标注文件
1 | from xml.dom import minidom |
OCR
光学字符识别(Optical Character Recognition,OCR)。
传统OCR方法的一般流程
图像输入
图像预处理:主要包括二值化、去噪声、倾斜校正等;
版面分析
字符切割
字符识别
版面恢复:按照原文档图片的顺序排列;
后处理:根据语言模型,对识别的结果进行语义校正。
缺点:整个处理流程工序太多,而且是串行的,导致错误不断被传递放大。例如,每一步都是90%的正确率,正确率看似很高,但是经过五步的错误叠加之后为0.59049,结果就已经不合格。另外,整个处理过程涉及太多人工设计,人工设计难以抓住问题的本质,而且面对稍复杂的问题,难以应对,泛化能力弱。
基于深度学习OCR方法的一般流程
主要分为两个步骤
文本检测(定位文本的位置)
文本识别(识别文本的具体内容)
文本检测的主流方法主要包含:基于候选框(Anchor)的文本检测、基于语义分割(Segmentation)的文本检测,以及基于两种方法的混合方法(Hybrid)。
文本识别的常用框架主要有两个:即CNN+RNN+CTC
和CNN+Seq2Seq+Attention
。