Java识别简单的验证码

1.老规矩,先上图

要破解类似这样的验证码:

拆分后结果:

Java识别简单的验证码

然后去匹配,得到结果。

2.拆分图片

拿到图片后,首先把图片中我们需要的部分截取出来。

具体的做法是,创建一个的和图片像素相同的一个代表权重的二维数组,遍历图片的每个像素点,如果接近白色,就标记为1,否则标记为0;

然后遍历这个二维数据,如果一个竖排都1,说明是空白列,直到第一次遇到不全为1一列,记住列的下标作为起始值,再次遇到全为1的,记住下标作为结束值,然后从起始列到结束列截取图片,依次类推。

1   //分割图片
 2    private Java.util.List<BufferedImage> splitImage(BufferedImage originImg)
 3            throws Exception {
 4        java.util.List<BufferedImage> subImgList = new ArrayList<>();
 5        int height = originImg.getHeight();
 6        int[][] weight = getImgWeight(originImg);
 7        int start = 0;
 8        int end = 0;
 9        boolean isStartReady = false;
10        boolean isEndReady = false;
11        for (int i = 0; i < weight.length; i++) {
12            boolean isBlank = isBlankArr(weight[i]);
13            if (isBlank) {
14                if (isStartReady && !isEndReady) {
15                    end = i;
16                    isEndReady = true;
17                }
18            } else {
19                if (!isStartReady) {
20                    start = i;
21                    isStartReady = true;
22                }
23            }
24            if (isStartReady && isEndReady) {
25                subImgList.add(originImg.getSubimage(start, 0, end - start, height));
26                isStartReady = false;
27                isEndReady = false;
28            }
29        }
30        return subImgList;
31    }
32
33    //颜色是否为空白
34    private boolean isBlank(int colorInt) {
35        Color color = new Color(colorInt);
36        return color.getRed() + color.getGreen() + color.getBlue() > 600;
37    }
38
39    //数组是不是全空白
40    private boolean isBlankArr(int[] arr) {
41        boolean isBlank = true;
42        for (int value : arr) {
43            if (value == 0) {
44                isBlank = false;
45                break;
46            }
47        }
48        return isBlank;
49    }
50
51    //获取图片权重数据
52    private int[][] getImgWeight(BufferedImage img) {
53        int width = img.getWidth();
54        int height = img.getHeight();
55        int[][] weight = new int[width][height];
56        for (int x = 0; x < width; ++x) {
57            for (int y = 0; y < height; ++y) {
58                if (isBlank(img.getRGB(x, y))) {
59                    weight[x][y] = 1;
60                }
61            }
62        }
63        return weight;
64    }

3.与拆分好的图片进行比较

拆分好的图片后,把拆分好的图片再次计算它的权重二维数据,加载之前准备好的"已知值的图片",也计算权重数组。

然后对比两个二维数组,如果大部分都匹配,就确定了值。

如果没有找到匹配的,就把图片保存下来,人工识别后放入已知值的图片组。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/d0f0395d529723f16ed5d639d541e48f.html