Lesson 5: 基于最大似然估计的验证码识别实践

验证码以前是非常简单的。。后来越来越难了。。本文也不能解决所有问题,但是一些简单的验证码还是能解决的。

知乎有个帖子写得很好,让大家可以回顾一下互联网的验证码历史:

知乎验证码历史

总的来,验证码最难的地方是分割部分,只要分割出来,单个图片的识别还是很容易的。

a13abd810416893afeaaebbd8345d435_b

2a105b98c92afa83f0131a40369fd5ba_b

989e1cad214bf0b2e3b2bbb872305cd1_b

f8b67343e06c3bac59d82ae647e4987a_b

譬如上面的验证码还是很容易识别的,二值化后做垂直投影即可找到每个数字或字母,代码可以看 Lesson 1: 如何做文本行和文字分割。成功分割后发送给识别器识别即可完成任务。但是现代验证码一般比较复杂,譬如下面的案例,小编暂时无能为力。。以后看看深度学习FC Semantic Segmentation能否解决这些问题。。

1f9d9c6b491b74ef10496c947731d133_b

f9b7559189389f4de67bedfc9a1e4d45_b

fe23544eada58ca0b06408bfe9f2f216_b

0d4acb4c563064035e7bf5c807c0175e_b

我们还是先解决去识别简单的验证码(复杂的验证码这里放弃了。。)

从上面的案例,有一些先验知识可以很容易从肉眼观察到的:

1, 在验证码中,有多少个字符。
2, 字符是什么集合,例如:数字,大写字母,小写字母,大写字母+小写字母,数字+大写字母,中文等等。。排列组合吧,不过所有情况都需要一个独立caffe识别器作为单独字符识别。

获取这些先验信息可以大量提高识别率。

我们挑战一个比较难的验证码:

captcha

首先我们也是做二值化处理,把图片变为白字黑底:

screenshot-from-2016-10-23-22-49-50

这里的思路是把图片先 过分割, 然后把所有的分割出来的图片排列组,因为有5个数字,所有可以产生出所有5个图片的分割,利用caffe对每个图片进行识别,然后对caffe输出的概率求乘法,看哪个图像分割(segmentation)最有可能。

这里写一个简单的算法,有点像下雨那样,找出的最低点,做为图像分割的点。下图是一个的的手绘的图例:

chongdata_captcha

下面的真实的曲线图以及系统找到的最低点(我自己加了一些去噪音):

screenshot-from-2016-10-23-23-06-35

如何通过docker安装需要参考文章:创建自定义Caffe训练数据库,安装后启动container后,可以执行下面命令


([u'5', u'2', u'3', u'5', u'6'], 0.67714580002694125)
([u'5', u'2', u'3', u'5', u'6'], 0.67437163988345394)
[...]
([u'5', u'3', u'5', u'1', u'5'], 0.43565324874193939)
([u'2', u'3', u'5', u'1', u'5'], 0.43254809218978107)

上面[u’5′, u’2′, u’3′, u’5′, u’6′]是识别结果,0.67714580002694125是识别出来的可信度。最大的可信很低,只有0.67714580002694125,其实这个结果可以忽略,不过我们还是分析一下TOP10结果。

TOP10其实还是能找出来的[u’5′, u’3′, u’5′, u’1′, u’5′],其中第二个1被识别为3了,这里的主要问题是识别是由mnist数据库训练出来的。这个数据库是手写数字为主,不是印刷体和没有太多旋转。以后再弄一个版本,基于印刷体的训练模型+旋转,这样可以把这个验证码识别出来。

如果最高的概率才0.67714580002694125,这个识别率可以考虑为识别失败。

下面来个容易的图片:

screenshot-from-2016-10-23-23-31-01

可以获取以下的识别率:

所有调试的中间调试保存的图片保存在:

可以考虑如何从container拷贝文件到host

微信公众号 changdata

wechat: changdata
wechat: changdata

发表评论

电子邮件地址不会被公开。 必填项已用*标注