在网络上,无论登陆论坛还是注册帐户的经常采用图片识别码来提高安全性,防止暴力破解和恶意注册。图片字符识别,就是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));//复制 biDest到ii
}
}
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));
}
}
最后结果如下:
下一篇将介绍如何切割图象,把一个个字符分离出来。