实际的代码也非常简单,请看我项目Decaptcha目录下的decaptcha_test.py文件,关键代码也就十几行。影响代码长短或复杂性的,就是二值化这一步了。其实很多图形验证码比较简单,细心分析一下,不难得出二值化的条件。下面以我工作中遇到过的一些验证码为例:
有5组,均来自于我公司的不同业务网站。识别代码请参看我项目目录下decaptcha_demo.py文件,所有的示例验证码放在images目录下。大家可以用图片编辑器打开相关的验证码文件观察和分析像素的规律。
第一组aa系列,字符颜色偏白,背景偏黑,所以可试着以像素RGB均值(或总和)大于某个数值为条件进行转换:r+g+b>=480则为1,否则为0。
第二组bb系列,字符有颜色,背景偏白色,转换条件考虑为RGB中是否有两个要素大于0xf0:int(r/240)+int(g/240)+int(b/240) <=1则为1,否则为0。
第三组cc系列,字符和背景都是单色,但是有不固定位置的点干扰,干扰点颜色与字符颜色相同,但是都是离散的。这种情况下,像素是白色的就是背景0,否则再判断一下是否离散的点,可以简单地判断它右边和下边的点是否都是白色背景来判定。
第四组dd系列,字符颜色偏紫色,并且有背景干扰线。通过将一些样本图片的每个像素的RGB值打印出来,确赫然发现字符像素的G通道值都为0,其它情况要么是背景,要么是干扰线。
第五组ee系列是最复杂的,有干扰线,干扰点,字符也有变形,颜色也不固定。实际上它来源于一个叫做securimage的php库所产生,恐怕不能一两行代码就二值化了。但是仔细观察它的模式会发现,它的大背景、干扰线、干扰点、字符都是用同一种颜色产生。所以我们可以以统计数量的方式来找出哪些是背景颜色(出现次数最多的自然是背景颜色)。另外我们再统计每个字符的颜色与背景颜色的偏差(将rgb差值的平方加起来),找出干扰线、字符与背景色的偏差值的阈值范围,再将其在二值化的时候进行应用,也可以成功地将其二值化。而字符变形的问题则不需要担心,交给tesseract就可以了。
在二值化的时候,我在屏幕上用# 符号打印出了二值化后的图像,大家可以看下效果:
python decaptcha_demo.py aa aa1.gif验证码实际是5648,识别为5649,错了一位。
下面来个正确识别的:
python decaptcha_demo.py bb bb1.jpg第五组的识别情况:
python decaptcha_demo.py ee ee9.png > 1.txt因图片有点长,超过了终端的列数,故输出到txt文件后再用notepad++打开的:
验证码实际是912065,识别为912085,错了一位。
再看看总体成绩如何:
aa组10个验证码,整体正确识别的有5个。
bb组10个验证码,整体正确识别的3个。
cc组10个验证码,整体正确识别的9个。
dd组10个验证码,整体正确识别的3个。
ee组10个验证码,整体正确识别的4个。
aa组、cc组和ee组识别得还可以,没有识别出来的多数仅错了一个字符。而bb和dd组识别得较差,没有识别出来的可能都错了两三个字符。