JavaSE图像验证码简单识别程序

首先你应该对图片进行样本采集,然后将样本进行灰度处理,也就是变成黑白两色。

然后你就可以使用该类,对目标文件进行分析。具体怎么实现我觉得这个类非常清楚,就是将样本从左都有这么横向移动,匹配出一个合适的就将坐标调整到下个位置。  

此程序已是3年多前写的,后来没有在深入写下去,图像识别一个很深的领域,得需要很深的数学功底跟思维能力,这个java的程序效率不高,也不能识别变形的或者拉伸的图片,但在那个年代,已经足够用了,大家如果有更好的开源的图像识别代码,请务必来信交流:)

 

/**
 * 图片解析引擎,适合做网站验证码的分析。
 * 首先必须载入样品,解析器将从左到右横向扫描,发现于样本的就自动记录。
 * 当然本程序不适合样本不是唯一的,也就是说要识别的图片被缩放或者坐标变动和变形本程序无法进行这样的识别。
 * 如果图片中的颜色变化非常大,此程序可能会有问题,当然了你可以选择一个标准的值做为转换成0,1矩阵的标准。
 * 
 * 样本的制作:请将样本转换成灰度模式,只含有两色最好,当然了不转换我也帮你转换了。
 * 
 
*/


import  java.awt.Image;
import  java.awt.image.BufferedImage;
import  java.io.File;
import  java.util.ArrayList;
import  java.util.Iterator;
import  java.util.List;

import  javax.imageio.ImageIO;

public   class  ImageParser  {

    
// ------------------------------------------------------------ Private Data

    
// 样本的矩阵
    private static List swatches      = null;

    
// 样本的值
    private static List swatcheValues = null;

    
// 图片文件的矩阵化
    private byte[][]    targetColors;
    
    
// ------------------------------------------------------------ Test main method
    public static void main(String[] args) {
        
// 加入样本与其样本对应的数值
        String[] files = new String[10];
        String[] values 
= new String[10];
        
for (int i = 0; i < files.length; i++){
            files[i] 
= "D:/workspace/SZXClientAPP/res/" + i + ".jpg";
            values[i] 
= String.valueOf(i);
        }

        
        ImageParser parse 
= new ImageParser(files, values);
        
long startime = System.currentTimeMillis();
        
try {
            
// 解析图片
            System.out.println(parse.parseValue("D:/workspace/SZXClientAPP/res/ValidateNum"));
            
long sincetime = System.currentTimeMillis();
            System.out.println(
"所花时间 = " + (sincetime - startime));
        }
 catch (Exception e) {
            e.printStackTrace();
        }

    }


    
// ------------------------------------------------------------ Constructors

    
/**
     * 载入所有样本路径与其样本对应的数值
     * 
     * 
@param files
     
*/

    
public ImageParser(String[] files, String[] values) {
        
// 只允许样本创建一次即可
        if (swatches == null && swatcheValues == null{
            
int fileslength = files.length;
            
int valueslength = values.length;
            
if(fileslength != valueslength){
                System.out.println(
"样本文件与样本数值不匹配!请重新设置!");
                
return;
            }

            swatches 
= new ArrayList(fileslength);
            swatcheValues 
= new ArrayList(valueslength);
            
int i = 0;
            
try {
                
for (; i < files.length; i++{
                    swatches.add(imageToMatrix(files[i]));
                    swatcheValues.add(i, values[i]);
                }

            }
 catch (Exception e) {
                System.out.println(files[i] 
+ " can not be parsed");
                e.printStackTrace();
            }

        }

    }


    
public ImageParser() {
        
super();
        
if (swatches == null || swatcheValues == null{
            System.out.println(
"您未载入样本,请先载入样本!");
        }

    }


    
/**
     * 解析图片的值
     * 
     * 
@param parseFilePath
     *            给出图片路径
     * 
@return 返回字符串
     * 
@throws Exception
     
*/

    
public String parseValue(String parseFilePath) throws Exception {
        StringBuffer result 
= new StringBuffer();
        targetColors 
= imageToMatrix(parseFilePath);
        
// printMatrix(targetColors);
        int height = targetColors.length;
        
int targetWidth = targetColors[0].length;

        
int width = 0;
        Iterator it 
= swatches.iterator();
        
while (it.hasNext()) {
            
byte[][] bytes = (byte[][]) it.next();
            
int templen = bytes[0].length;
            
if (templen > width)
                width 
= templen;
        }

        
// System.out.println("MaxWidth = " + width);
        
// System.out.println("MaxHeight = " + height);
        int xTag = 0;
        
while ((xTag + width) < targetWidth) {
            cout: 
{
                Iterator itx 
= swatches.iterator();
                
int i = 0;
                
while (itx.hasNext()) {
                    
byte[][] bytes = (byte[][]) itx.next();
                    
byte[][] temp = splitMatrix(targetColors, xTag, 0, width, height);
                    
// System.out.println(i++);
                    if (isMatrixInBigMatrix(bytes, temp)) {
                        xTag 
+= width;
                        
// System.out.println("new maxtrix: ");
                        
// printMatrix(temp);
                        
                        result.append(swatcheValues.get(i));
                        
break cout;
                    }

                    i
++;
                }

                xTag
++;
            }

        }

        
return result.toString();
    }


    
// ------------------------------------------------------------ Private methods

    
/**
     * 判断一个矩阵是否在另外的矩阵中
     * 
     * 
@param source
     *            源矩阵
     * 
@param bigMatrix
     *            大的矩阵
     * 
@return 如果存在就返回 true
     
*/

    
private static final boolean isMatrixInBigMatrix(byte[][] source, byte[][] bigMatrix) {
        
if (source == bigMatrix)
            
return true;
        
if (source == null || bigMatrix == null)
            
return false;

        
if (source.length > bigMatrix.length)
            
return false;

        
try {
            
for (int i = 0; i < source.length; i++{
                
if (source[i].length > bigMatrix[i].length)
                    
return false;
            }

        }
 catch (ArrayIndexOutOfBoundsException e) {
            
return false;
        }


        
int height = source.length;
        
int width = source[0].length;
        
int x = 0, y = 0;
        
int i = 0, j = 0;
        
int count = 0;

        
int comparecount = height * width;

        
for (; i < bigMatrix.length - height + 1; i++{
            
for (j = 0; j < bigMatrix[i].length - width + 1; j++{
                cout: 
{
                    x 
= 0;
                    count 
= 0;
                    
for (int k = i; k < height + i; k++{
                        y 
= 0;
                        
for (int l = j; l < width + j; l++{
                            
// System.out.println("bytes[" + x + "][" + y + "]"
                            
// + " = " + source[x][y] + ", " + "other["
                            
// + k + "][" + l + "] = " + bigMatrix[k][l]);
                            if ((source[x][y] & bigMatrix[k][l]) == source[x][y]) {
                                count
++;
                            }
 else
                                
break cout;
                            y
++;
                        }

                        x
++;
                    }

                    
// System.out.println("count = " + count);
                    if (count == comparecount)
                        
return true;
                }

            }

        }

        
return false;
    }


    
/**
     * 切割矩阵
     * 
     * 
@param source
     *            源矩阵
     * 
@param x
     *            X坐标
     * 
@param y
     *            Y坐标
     * 
@param width
     *            矩阵的宽度
     * 
@param height
     *            矩阵的高度
     * 
@return 切割后的矩阵
     
*/

    
private static final byte[][] splitMatrix(byte[][] source, int x, int y, int width, int height) {
        
byte[][] resultbytes = new byte[height][width];
        
for (int i = y, k = 0; i < height + y; i++, k++{
            
for (int j = x, l = 0; j < width + x; j++, l++{

                resultbytes[k][l] 
= source[i][j];
                
// System.out.println("source[" + i + "][" + j + "]" + " = " +
                
// source[i][j] + ", " + "resultbytes["
                
// + k + "][" + l + "] = " + resultbytes[k][l]);
            }


        }

        
return resultbytes;
    }


    
/**
     * 图片转换成矩阵数组
     * 
     * 
@param filePath
     *            文件路径
     * 
@return 返回矩阵
     * 
@throws Exception
     *             可能会抛出异常
     
*/

    
private byte[][] imageToMatrix(String filePath) throws Exception {
        
// 读入文件
        Image image = ImageIO.read(new File(filePath));
        
int w = image.getWidth(null);
        
int h = image.getHeight(null);
        BufferedImage src 
= new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        src.getGraphics().drawImage(image, 
00null);

        
byte[][] colors = new byte[h][w];

        
for (int i = 0; i < h; i++{
            
for (int j = 0; j < w; j++{
                
int rgb = src.getRGB(j, i);
                
// 像素进行灰度处理
                String sRed = Integer.toHexString(rgb).substring(24);
                String sGreen 
= Integer.toHexString(rgb).substring(46);
                String sBlank 
= Integer.toHexString(rgb).substring(68);
                
long ired = Math.round((Integer.parseInt(sRed, 16* 0.3 + 0.5d));
                
long igreen = Math.round((Integer.parseInt(sGreen, 16* 0.59 + 0.5d));
                
long iblank = Math.round((Integer.parseInt(sBlank, 16* 0.11 + 0.5d));
                
long al = ired + igreen + iblank;

                
// if (al > 127)
                
// System.out.print(" " + " ");
                
// else
                
// System.out.print(" " + "1");
                
// System.out.print(" " + (tempint > = maxint ? 0 : 1));
                
// System.out.println("tempInt = " + tempint);

                
/* 将图像转换成0,1 */
                
// 此处的值可以将来修改成你所需要判断的值
                colors[i][j] = (byte) (al > 127 ? 0 : 1);
            }

            
// System.out.println();
        }


        
return colors;
    }


    
/**
     * 打印矩阵
     * 
     * 
@param matrix
     
*/

    
private static final void printMatrix(byte[][] matrix) {
        
for (int i = 0; i < matrix.length; i++{
            
for (int j = 0; j < matrix[i].length; j++{
                
if (matrix[i][j] == 0)
                    System.out.print(
" ");
                
else
                    System.out.print(
" 1");
            }

            System.out.println();
        }

    }

}

  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值