现在的位置: 首页 > 综合 > 正文

破解百度验证码—去背景

2013年09月04日 ⁄ 综合 ⁄ 共 2304字 ⁄ 字号 评论关闭
 

在网络上,无论登陆论坛还是注册帐户的经常采用图片识别码来提高安全性,防止暴力破解和恶意注册。图片字符识别,就是ocr(光学字符识别),通常在背景没有干扰的情况,可以识别印刷体字符。而在网站的识别嘛,常常有干扰背景,并且字体是变形的。在百度贴吧和百度知道中采用的验证图片如下:


字体变形,并且有倾斜,背景随机渐变变化。

要想进行识别第一步要去掉背景具体步骤如下:

先定义如下:

      

       FileInputStream i=new FileInputStream("1.bmp");

       BufferedImage ii=ImageIO.read(i);

       int w=ii.getWidth(this);

       int h=ii.getHeight(this);

1. 去到格子背景。

观察多个图片发现有一个共同的特点,背景都是通过,格子的变化得到的。用phtoshopshop做图如下(不知道为什么ps不能生成和打开bmp文件)

 

取名为mask.gif。我门要做的就是把mask黑的地方,坐标对应到图片1.bmp中置成白色。程序如下:

FileInputStream f=new FileInputStream("mask1.gif");

              BufferedImage ff=ImageIO.read(f);

for(int x=0;x<w;x++){

                     for(int y=0;y<h;y++){                

                           

                      if((ff.getRGB(x,y)&0x00111111)==0x00000000){

                            ii.setRGB(x,y,0x00ffffff);

                       }               

                     }

              }

效果很明显吧!如下图:

2. 加强对比度

就是让黑的更黑,白的更白,去掉由渐变形成的灰色象素。具体的程序如下,

biDest = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);

              ///提高对比度

              RescaleOp rescale = new RescaleOp(2f, 0f, null);

        rescale.filter(ii,biDest);

 

效果比较明显。如下图。

 

背景完全去掉了,但看起来不是很清楚,问题就是前面的操作对文字也造成了伤害。对人来说造成了识别上的站碍,对计算机识别有没暂碍我们下次再说。现在采用一个简单的算法把图象补全(欢迎大家推荐更好的算法)。

3.补全图象

 

        for(int x=0;x<w;x++){

                     for(int y=0;y<h;y++){         

                    

                      ii.setRGB(x,y,biDest.getRGB(x,y));//复制 biDestii

                     }

              }

 

for(int x=0;x<w;x++){

                            for(int y=0;y<h;y++){

                                                       

                             if((biDest.getRGB(x,y)&0x00ffffff)!=0x00ffffff&&x>0&&y>0&&x<w-1&&y<h-1){

                                   ii.setRGB(x+1,y,0);

                                   ii.setRGB(x-1,y,0);

                                   ii.setRGB(x,y+1,0);

                                   ii.setRGB(x,y-1,0);

                                   ii.setRGB(x+1,y+1,0);

                                   ii.setRGB(x-1,y-1,0);

                                   ii.setRGB(x+1,y-1,0);

                                   ii.setRGB(x-1,y+1,0);

//让有黑的像素的地方八个方向置成黑色

                //也不知道这个叫什么算法

                                  

                              }

                             biDest.setRGB(x,y,ii.getRGB(x,y));

                            }

                     }

最后结果如下:

 

下一篇将介绍如何切割图象,把一个个字符分离出来。

 

 

抱歉!评论已关闭.