图像验证码识别(七)——字符分割

前面经过各种去除噪点、干扰线,验证码图片现在已经只有两个部分,如果pixel为白就是背景,如果pixel为黑就为字符。正如前面流畅所提到的一样,为了字符的识别,这里需要将图片上的字符一个一个“扣”下来,得到单个的字符,接下来再进行OCR识别。

字符分割可以说是图像验证码识别最关键的一步,因为分割的正确与否直接关系到最后的结果,如果4个字符分割成了3个,即便后面的识别算法识别率达到100%,结果也是错的。当然,前面预处理如果做得够好,干扰因素能够有效的去除,而没有影响到字符的pixel,那么分割来讲要容易得多。反过来,如果前面的干扰因素都没有去除掉,那么分割出来的可能就不是字符了。

字符的粘连是分割的难点,这一点也可以作为验证码安全系数的标准,如果验证码上的几个字符完全是分开的,那么可以保证字符分割成功率百分之百,这样验证码破解的难度就降低了很多,比如下面的字符:


这个就是CSDN的验证码,经过二值化和降噪得到的图片,可以看到这里图片已经非常干净,没有一点多余的信息,字符之间没有重叠的部分,分割起来毫无难度。

当然,大多数IT巨头的网页验证码里地字符都是粘连在一起的,比如谷歌的验证码:


谷歌的验证码不仅粘连成都很大,而且字符扭曲地也特别厉害,所以破解起来那是难度非常大了

至于图片分割,我再这里介绍两种简单地方法。

一、 泛水填充法

泛水填充法在前面降噪的地方就提到过,主要思路还是连通域的思想。对于相互之间没有粘连的字符验证码,直接对图片进行扫描,遇到一个黑的pixel就对其进行泛水填充,所有与其连通的字符都被标记出来,因此一个独立的字符就能够找到了。这个方法优点是效率高,时间复杂度是O(N),N为像素的个数;而且不用考虑图片的大小、相邻字符间隔以及字符在图片中得位置等其他任何因素,任何验证码图片只要字符相互是独立的,不需要对其他任何阀值做预处理,直接就操作;用这种方法分割正确率非常高,几乎不会出现分割错误的情况。但是缺点也很致命:那就是字符之间必须完全隔离,没有粘连的部分,否则会将两个字符误认为一个字符。

代码如下:

[cpp]  view plain  copy
  1. for (i = 0; i < nWidth; ++i)  
  2.         for (j = 0; j < nHeight; ++j)  
  3.         {  
  4.             if ( !getPixel(i,j) )  
  5.             {  
  6.                 //FloodFill each point in connect area using different color  
  7.                 floodFill(m_Mat,cvPoint(i,j),cvScalar(color));  
  8.                 color++;  
  9.             }  
  10.         }  
  11.   
  12.     int ColorCount[256] = { 0 };  
  13.     for (i = 0; i < nWidth; ++i)  
  14.     {  
  15.         for (j = 0; j < nHeight; ++j)  
  16.         {  
  17.             //caculate the area of each area  
  18.             if (getPixel(i,j) != 255)  
  19.             {  
  20.                 ColorCount[getPixel(i,j)]++;  
  21.             }  
  22.         }  
  23.     }  
  24.     //get rid of noise point  
  25.     for (i = 0; i < nWidth; ++i)  
  26.     {  
  27.         for (j = 0; j < nHeight; ++j)  
  28.         {  
  29.             if (ColorCount[getPixel(i,j)] <= nMin_area)  
  30.             {  
  31.                 setPixel(i,j,WHITE);  
  • 5
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值