声明: 此文章只是记录我在处理163相册验证码图片识别过程时的想法思路,在此发表只是纯粹基于技术探讨目的.因此在文章中不会提供任何源码下载!!任何人利用这里介绍的方法所做任何事情而出现的责任本人概不负责!!如果需要转载此文,请注明原作者和出处!!

 

一.认识验证码图片

下面提供几种163相册的验证码图片样例:

                                       

 

 从上面的样例图中可知道163相册的验证码只是使用了平常所见的中规中距的0-9数字验证码和外加一些干扰措施,其中0-9数字图如下:

                           

 

 

二.去除干扰

从上面的样例图中可知道163相册的验证码图片使用了"变色","干扰点","干扰线","变位"等几种用于干扰自动识别的"手段".因此为了方便程序识别则必须先将干扰去掉.

 

"变色" : 在某些简单的验证码图片中常常将背景色或干扰色和前景色(验证码颜色)的颜色值分别固定用不同范围内的颜色表进行填充.而对于使用此种"变色手段"的图片则可以使用"二值分化"将验证图片处理为只有两种颜色的图片后再进行处理即可.而163的验证码图片中的干扰点和干扰线的颜色和数字的颜色都基本都是随机的.所以"二值分化"方案在这里就用不上了.(注:但也幸好有了"变色",导致各个干扰点/线和各个验证码的颜色是基本不相同的,所以对干扰去除提供了更大的方便).

 

"干扰点" : 处理那些单独的干扰点就实在太容易了.只要扫描一遍图片,判断哪些颜色点的四周是空的(颜色值为背景色)就基本可以判断那点为干扰点了.然后将去除(置为背景色)即可.

 

去除干扰点后的验证码图片样例如下:

                                        

 

"干扰线" : 从上面两组对比可看出.去除干扰点后,效果也不是很明显:( 干扰线占的比率太大了.所以还要进一步去掉干扰线.而对于直线型的干扰线.则可以简单直接判断某点的颜色值是否连续出现,如果连续出现次数超过10次(嘿嘿,留个作业.这个值怎么来的?)则基本可以判断为干扰线.但可惜的是.163验证码图片中使用的是非直线型干扰线.所以此方法行不通.只好采用"块判断法"(嘿嘿,自己取的名字).也就是扫描一遍图片.当扫描到某点时,则以此点为左上角,取宽为8高为10的块(又是一个作业.这两个值怎么来的?如果上面的作业会做了.这个应该不是问题了.嘿嘿).然后判断此点的颜色值在此块中出现的次数.如果出现的次数越过一定数量(这个数量值很重要,因为关系到干扰线清除的"干净度"又关系到是否会"误杀"掉验证码图片.我试验过程中使用的是17)则可认为此颜色值是验证码使用的颜色.否则继续扫描下一点.直到图象的所有点扫描完成.扫描完后则可认为除了刚扫描到的验证码颜色外其它颜色都可认为为干扰色直接去除即可.

 

根据上面方法进行处理后的验证码图片样例如下:

                                      

 

效果出来了.部份图片明显的将干扰线去掉了.但是对某些特殊(弯曲特历害的)的干扰线还是去除不了.分析到这里后我的思路卡壳了.要怎么样才能将那些弯曲的干扰线去除掉呢?来来回回的看了验证码样例图片和0-9数字图片,终于有一个"啊哈"闪光在我头脑里呈现:为什么我要取块来判断呢(把问题搞复杂化了-_-),直接使用颜色"步长"(又是我自己取的名字>p<)统计不就可以了吗?

 

颜色步长统计法:

在验证码图片里干扰线和验证码的颜色是分别不相同的(拜"变色"所托!)并且0-9数字图片的长宽是固定的(作业答案在这里.嘿嘿).所以直接在扫描图片时记录每种颜色的出现次数和第一次与最后出现的坐标.扫描完图像后统计"出现次数大于一定数量(这个数量值很重要,我试验时取的是20)并且最后出现和第一次出现的x轴差必须为正负8之内,y轴差必须为正负10"的颜色(验证码颜色).如果不满足此统计条件的颜色都可认为为干扰色直接去除即可.

 

根据上面方法进行处理后的验证码图片样例如下:

                                      

 

到此,所有干扰线都完美的去除了.剩下的就是怎么识别验证码了.

本文转自:http://www.cnblogs.com/kingthy/archive/2008/08/06/1262475.html