记得很早以前,我对如携程飞猪等第三方平台购买火车票不用输入验证码感到很……牛!百度后发现其可能是实现了自动打码,或者说机器自动识别验证码,我很好奇。
后来,当我觉得我必须要给自己找些有趣的知识来学习的时候,脑海里萌生了去实现一个简单的验证码识别程序的想法。在一切未知以前,我觉得很难,甚至望而却步。但,真正一点点地行动下来,我发现,其实慢慢深入后,无论多么困难的问题,都能一点点解决。
不要着急,不要慌张,一点点地啃下来,一个方式不通,换个思路解决,不要轻易放弃。这个过程中,世上无难事,只怕有心人,古人诚不欺我。任何事情,流于表面而不做,是永远不会成长的——谨以告诫自己。
好了,废话不多说。
-----------------------------------------------------我是萌萌的分割线--------------------------------------------------------准备:
- 语言:python
- python库:opencv,sklearn,requests等
流程:整体大致流程为四部分,预处理,字符分割,字符标记分类,字符识别
- 预处理:对原始验证码图片进行如灰度处理,二值化,降噪等处理,为下一步的字符分割提供一个好的素材
- 字符分割:将预处理后的图片中的每个字符单独分割出来,本次分割的图片比较取巧,当预处理后,图片中各个字符的位置是相对固定的,所以,采用的分割方法为等距分割。
- 字符标记分类:当字符分割好后,需要人为为字符进行分类标记,这个过程属于体力活,比较繁琐。我尝试过直接调用谷歌的ocr(光学字符识别)工具库pytesseract来代替人工识别,但是结果非常不好,无奈,还是只能先人工仔细分类。
- 字符识别:分类好后,图片经过二值化转换为01的数据,写入一个txt格式文件中,作为训练集,其结果类似如下所示:
再利用机器学习算法对之进行训练,本文使用的是经典的svm(支持向量机)算法对图片验证码进行训练。支持向量机的原理以及优势百度谷歌均可详细查到。
实现:
- 获取图片验证码
巧妇难为无米之炊,首先,我们要有原材料。在网上,我们可以很轻易地找到图片验证码。本文找的是csdn上的图片验证码。当然了,我们需要的验证码素材至少也要百张以上吧。如果傻乎乎地鼠标刷新保存图片,那效率太低了。要充分利用好可以利用的工具,python中的url库,requests库等都是很强大的工具库。用来爬取网络资源数据可以说是无往不利,哈哈,莫笑我略装*哈~
# coding=utf8
import requests
res = requests.get('img_code_url') # 这是一个get请求,获取图片资源
with open(file_path + "/%d.jpg" % num, "wb") as f: # 将图片保存在本地
f.write(res.content)
print("%d" % num + "获取成功")
如何获取图片验证码呢,我们可以利用浏览器的开发者模式(一般F12快捷键即可打开)或者利用专业的抓包软件如Charles(收费)等来查看获取。以上是个简单地将网上的图片验证码保存到本地的程序代码。
如果我们选择的图片验证码本身是十分清晰的没有太多混淆的状态,我们可以考虑用pytesseract直接对它进行识别。比如此类图片:
可以看出,以上这张图片验证码并未经过太多复杂处理,文本清晰,所以可以很容易ocr直接识别。但是如此类验证码则不然:
可以看出,这类验证码被经过了很多噪声处理,很多像素点在混淆,如果不经过处理直接用ocr识别会很糟糕。
- 图片预处理
对图片进行灰度化,二值化,等距切割。
# coding=utf8
import cv2
def pre_img(file_name): # 图片灰度,二值化处理
img = cv2.imread(file_name, 0)
img = cv2.threshold(img, 180, 255, 1)
以上是对图片进行灰度化以及二值化的处理程序,利用的opencv库,opencv的使用方法可以看它的官方文档,或者百度搜索相应的博客等等。
然后,图片变成这样的了: