JAVA识别图形验证码

最近一直在开发一个用于自动发帖的工具,用HttpClient模拟客户端浏览器注册发帖。但是碰到了图形验证码的问题了,对单数字的验证码,通过一些OCR引擎,如:tesseract,AspriseOCR很容易解决问题。但碰到如CSDN论坛这中图形验证码就比较麻烦,必须先通过预处理。使图象二值化,黑白灰度,增加亮度。我的代码如下: 

package myfilter; 
import java.io.*; 
import java.awt.image.*; 
import java.awt.geom.AffineTransform; 
import java.awt.color.ColorSpace; 
import java.awt.image.ConvolveOp; 
import java.awt.image.Kernel; 
import java.awt.image.BufferedImage; 
import javax.imageio.ImageIO; 
import java.awt.Toolkit; 
import java.awt.Image; 
public class MyImgFilter { 
BufferedImage image; 
private int iw, ih; 
private int[] pixels; 
public MyImgFilter(BufferedImage image) { 
this.image = image; 
iw = image.getWidth(); 
ih = image.getHeight(); 
pixels = new int[iw * ih]; 

public BufferedImage changeGrey() { 
PixelGrabber pg = new PixelGrabber(image.getSource(), 0, 0, iw, ih, pixels,0, iw); 
try { 
pg.grabPixels(); 
} catch (InterruptedException e) { 
e.printStackTrace(); 

// 设定二值化的域值,默认值为100 
int grey = 100; 
// 对图像进行二值化处理,Alpha值保持不变 
ColorModel cm = ColorModel.getRGBdefault(); 
for (int i = 0; i < iw * ih; i++) { 
int red, green, blue; 
int alpha = cm.getAlpha(pixels[i]); 
if (cm.getRed(pixels[i]) > grey) { 
red = 255; 
} else { 
red = 0; 

if (cm.getGreen(pixels[i]) > grey) { 
green = 255; 
} else { 
green = 0; 

if (cm.getBlue(pixels[i]) > grey) { 
blue = 255; 
} else { 
blue = 0; 

pixels[i] = alpha << 24 | red << 16 | green << 8 | blue; //通过移位重新构成某一点像素的RGB值 

// 将数组中的象素产生一个图像 
Image tempImg=Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(iw,ih, pixels, 0, iw)); 
image = new BufferedImage(tempImg.getWidth(null),tempImg.getHeight(null), BufferedImage.TYPE_INT_BGR ); 
image.createGraphics().drawImage(tempImg, 0, 0, null); 
return image; 

public BufferedImage getMedian() { 
PixelGrabber pg = new PixelGrabber(image.getSource(), 0, 0, iw, ih, 
pixels, 
0, iw); 
try { 
pg.grabPixels(); 
} catch (InterruptedException e) { 
e.printStackTrace(); 

// 对图像进行中值滤波,Alpha值保持不变 
ColorModel cm = ColorModel.getRGBdefault(); 
for (int i = 1; i < ih - 1; i++) { 
for (int j = 1; j < iw - 1; j++) { 
int red, green, blue; 
int alpha = cm.getAlpha(pixels[i * iw + j]); 
// int red2 = cm.getRed(pixels[(i - 1) * iw + j]); 
int red4 = cm.getRed(pixels[i * iw + j - 1]); 
int red5 = cm.getRed(pixels[i * iw + j]); 
int red6 = cm.getRed(pixels[i * iw + j + 1]); 
// int red8 = cm.getRed(pixels[(i + 1) * iw + j]); 
// 水平方向进行中值滤波 
if (red4 >= red5) { 
if (red5 >= red6) { 
red = red5; 
} else { 
if (red4 >= red6) { 
red = red6; 
} else { 
red = red4; 


} else { 
if (red4 > red6) { 
red = red4; 
} else { 
if (red5 > red6) { 
red = red6; 
} else { 
red = red5; 



int green4 = cm.getGreen(pixels[i * iw + j - 1]); 
int green5 = cm.getGreen(pixels[i * iw + j]); 
int green6 = cm.getGreen(pixels[i * iw + j + 1]); 
// 水平方向进行中值滤波 
if (green4 >= green5) { 
if (green5 >= green6) { 
green = green5; 
} else { 
if (green4 >= green6) { 
green = green6; 
} else { 
green = green4; 


} else { 
if (green4 > green6) { 
green = green4; 
} else { 
if (green5 > green6) { 
green = green6; 
} else { 
green = green5; 



// int blue2 = cm.getBlue(pixels[(i - 1) * iw + j]); 
int blue4 = cm.getBlue(pixels[i * iw + j - 1]); 
int blue5 = cm.getBlue(pixels[i * iw + j]); 
int blue6 = cm.getBlue(pixels[i * iw + j + 1]); 
// int blue8 = cm.getBlue(pixels[(i + 1) * iw + j]); 
// 水平方向进行中值滤波 
if (blue4 >= blue5) { 
if (blue5 >= blue6) { 
blue = blue5; 
} else { 
if (blue4 >= blue6) { 
blue = blue6; 
} else { 
blue = blue4; 


} else { 
if (blue4 > blue6) { 
blue = blue4; 
} else { 
if (blue5 > blue6) { 
blue = blue6; 
} else { 
blue = blue5; 



pixels[i * iw + 
j] = alpha << 24 | red << 16 | green << 8 | blue; 


// 将数组中的象素产生一个图像 
Image tempImg=Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(iw,ih, pixels, 0, iw)); 
image = new BufferedImage(tempImg.getWidth(null),tempImg.getHeight(null), BufferedImage.TYPE_INT_BGR ); 
image.createGraphics().drawImage(tempImg, 0, 0, null); 
return image; 

public BufferedImage getGrey() { 
ColorConvertOp ccp=new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null); 
return image=ccp.filter(image,null); 

//Brighten using a linear formula that increases all color values 
public BufferedImage getBrighten() { 
RescaleOp rop=new RescaleOp(1.25f, 0, null); 
return image=rop.filter(image,null); 

//Blur by "convolving" the image with a matrix 
public BufferedImage getBlur() { 
float[] data = { 
.1111f, .1111f, .1111f, 
.1111f, .1111f, .1111f, 
.1111f, .1111f, .1111f, }; 
ConvolveOp cop = new ConvolveOp(new Kernel(3, 3, data)); 
return image=cop.filter(image,null); 

// Sharpen by using a different matrix 
public BufferedImage getSharpen() { 
float[] data = { 
0.0f, -0.75f, 0.0f, 
-0.75f, 4.0f, -0.75f, 
0.0f, -0.75f, 0.0f}; 
ConvolveOp cop = new ConvolveOp(new Kernel(3, 3, data)); 
return image=cop.filter(image,null); 

// 11) Rotate the image 180 degrees about its center point 
public BufferedImage getRotate() { 
AffineTransformOp atop=new AffineTransformOp(AffineTransform.getRotateInstance(Math.PI,image.getWidth()/2,image.getHeight()/2), 
AffineTransformOp.TYPE_NEAREST_NEIGHBOR); 
return image=atop.filter(image,null); 

public BufferedImage getProcessedImg() 

return image; 

public static void main(String[] args) throws IOException { 
FileInputStream fin=new FileInputStream(args[0]); 
BufferedImage bi=ImageIO.read(fin); 
MyImgFilter flt=new MyImgFilter(bi); 
flt.changeGrey(); 
flt.getGrey(); 
flt.getBrighten(); 
bi=flt.getProcessedImg(); 
String pname=args[0].substring(0,args[0].lastIndexOf(".")); 
File file = new File(pname+".jpg"); 
ImageIO.write(bi, "jpg", file); 


运行java myfilter.MyImgFilter t6.bmp,请确认图片t6.bmp与myfilter目录在同一目录下。 
顺便说一下,在JDK1.5下,ImageIO可以输出JPG,BMP,PNG三种格式图片,但不支持GIF图片输出。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值