3.与拆分好的图片进行比较
  拆分好的图片后,把拆分好的图片再次计算它的权重二维数据,加载之前准备好的"已知值的图片",也计算权重数组。
  然后对比两个二维数组,如果大部分都匹配,确定了值。
  如果没有找到匹配的,把图片保存下来,人工识别后放入已知值的图片组。
1   //分析识别
2     private String realize(java.util.List<BufferedImage> imgList) {
3         String resultStr = "";
4         for (BufferedImage img : imgList) {
5             String key = getKey(Global.trainedMap, img);
6             if (key == null) {
7                 String noTrainedKey = getKey(Global.noTrainedMap, img);
8                 if(noTrainedKey == null){
9                     try {
10                         ImageIO.write(img, "JPG", new File(Global.LIB_NO + File.separator + UUID.randomUUID() + ".jpg"));
11                     } catch (IOException e) {
12                         e.printStackTrace();
13                     }
14                 }
15             } else {
16                 resultStr += key;
17             }
18         }
19         return resultStr;
20     }
21
22     //获取已知值
23     private String getKey(Map<String, BufferedImage> map, BufferedImage img){
24         String resultStr = null;
25         Set<Map.Entry<String, BufferedImage>> entrySet = map.entrySet();
26         for (Map.Entry<String, BufferedImage> one : entrySet) {
27             if (isSimilarity(img, one.getValue())) {
28                 resultStr = one.getKey();
29                 break;
30             }
31         }
32         return resultStr;
33     }
34
35     //是否相似
36     private boolean isSimilarity(BufferedImage imageA, BufferedImage imageB) {
37         int widthA = imageA.getWidth();
38         int widthB = imageB.getWidth();
39         int heightA = imageA.getHeight();
40         int heightB = imageB.getHeight();
41         if (widthA != widthB || heightA != heightB) {
42             return false;
43         } else {
44             int[][] weightA = getImgWeight(imageA);
45             int[][] weightB = getImgWeight(imageB);
46             int count = 0;
47             for (int i = 0; i < widthA; i++) {
48                 for (int j = 0; j < heightB; j++) {
49                     if (weightA[i][j] != weightB[i][j]) {
50                         count++;
51                     }
52                 }
53             }
54             if ((double) count / (widthA * widthB) > (1 - Global.SIMILARITY)) {
55                 return false;
56             } else {
57                 return true;
58             }
59         }
60     }
  4.完整代码
1 import javax.imageio.ImageIO;
2 import java.awt.image.BufferedImage;
3 import java.io.File;
4 import java.io.IOException;
5 import java.util.HashMap;
6 import java.util.Map;
7
8 public class Global {
9     public static final String LIB_PATH = "C:/lib";
10     public static final String LIB_NO = "C:/no";
11     public static final double SIMILARITY = 0.9;
12     public static Map<String, BufferedImage> trainedMap;
13     public static Map<String, BufferedImage> noTrainedMap = new HashMap<>();
14
15     static {
16         trainedMap = getMap(LIB_PATH);
17         noTrainedMap = getMap(LIB_NO);
18     }
19
20     private static Map<String, BufferedImage>  getMap(String path) {
21        Map<String, BufferedImage> map = new HashMap<>();
22         File parentFile = new File(path);
23         for (String filePath : parentFile.list()) {
24             File file = new File(path + File.separator + filePath);
25             String fileName = file.getName();
26             String key = fileName.substring(0,fileName.indexOf(".")).trim();
27             try {
28                 map.put(key, ImageIO.read(file));
29             } catch (IOException e) {
30                 e.printStackTrace();
31             }
32         }
33         return map;
34     }
35 }
36 import javax.imageio.ImageIO;
37 import java.awt.*;
38 import java.awt.image.BufferedImage;
39 import java.io.File;
40 import java.io.IOException;
41 import java.util.*;
42
43 /**
44  * 识别验证码
45  */
46 public class ImageProcess {
47     private String imgPath;
48
49     public ImageProcess(String imgPath) {
50         this.imgPath = imgPath;
51     }
52
53     public String getResult() {
54         java.util.List<BufferedImage> imgList = null;
55         try {
56             BufferedImage img = ImageIO.read(new File(imgPath));
57             imgList = splitImage(img);
58         } catch (IOException e) {
59             e.printStackTrace();
60         } catch (Exception e) {
61             e.printStackTrace();
62         }
63         return realize(imgList);
64     }
65
66     //分析识别
67     private String realize(java.util.List<BufferedImage> imgList) {
68         String resultStr = "";
69         for (BufferedImage img : imgList) {
70             String key = getKey(Global.trainedMap, img);
71             if (key == null) {
72                 String noTrainedKey = getKey(Global.noTrainedMap, img);
73                 if(noTrainedKey == null){
74                     try {
75                         ImageIO.write(img, "JPG", new File(Global.LIB_NO + File.separator + UUID.randomUUID() + ".jpg"));
76                     } catch (IOException e) {
77                         e.printStackTrace();
78                     }
79                 }
80             } else {
81                 resultStr += key;
82             }
83         }
84         return resultStr;
85     }
86
87     //获取已知值
88     private String getKey(Map<String, BufferedImage> map, BufferedImage img){
89         String resultStr = null;
90         Set<Map.Entry<String, BufferedImage>> entrySet = map.entrySet();
91         for (Map.Entry<String, BufferedImage> one : entrySet) {
92             if (isSimilarity(img, one.getValue())) {
93                 resultStr = one.getKey();
94                 break;
95             }
96         }
97         return resultStr;
98     }
99
100     //是否相似
101     private boolean isSimilarity(BufferedImage imageA, BufferedImage imageB) {
102         int widthA = imageA.getWidth();
103         int widthB = imageB.getWidth();
104         int heightA = imageA.getHeight();
105         int heightB = imageB.getHeight();
106         if (widthA != widthB || heightA != heightB) {
107             return false;
108         } else {
109             int[][] weightA = getImgWeight(imageA);
110             int[][] weightB = getImgWeight(imageB);
111             int count = 0;
112             for (int i = 0; i < widthA; i++) {
113                 for (int j = 0; j < heightB; j++) {
114                     if (weightA[i][j] != weightB[i][j]) {
115                         count++;
116                     }
117                 }
118             }
119             if ((double) count / (widthA * widthB) > (1 - Global.SIMILARITY)) {
120                 return false;
121             } else {
122                 return true;
123             }
124         }
125     }
126
127     //分割图片
128     private java.util.List<BufferedImage> splitImage(BufferedImage originImg)
129             throws Exception {
130         java.util.List<BufferedImage> subImgList = new ArrayList<>();
131         int height = originImg.getHeight();
132         int[][] weight = getImgWeight(originImg);
133         int start = 0;
134         int end = 0;
135         boolean isStartReady = false;
136         boolean isEndReady = false;
137         for (int i = 0; i < weight.length; i++) {
138             boolean isBlank = isBlankArr(weight[i]);
139             if (isBlank) {
140                 if (isStartReady && !isEndReady) {
141                     end = i;
142                     isEndReady = true;
143                 }
144             } else {
145                 if (!isStartReady) {
146                     start = i;
147                     isStartReady = true;
148                 }
149             }
150             if (isStartReady && isEndReady) {
151                 subImgList.add(originImg.getSubimage(start, 0, end - start, height));
152                 isStartReady = false;
153                 isEndReady = false;
154             }
155         }
156         return subImgList;
157     }
158
159     //颜色是否为空白
160     private boolean isBlank(int colorInt) {
161         Color color = new Color(colorInt);
162         return color.getRed() + color.getGreen() + color.getBlue() > 600;
163     }
164
165     //数组是不是全空白
166     private boolean isBlankArr(int[] arr) {
167         boolean isBlank = true;
168         for (int value : arr) {
169             if (value == 0) {
170                 isBlank = false;
171                 break;
172             }
173         }
174         return isBlank;
175     }
176
177     //获取图片权重数据
178     private int[][] getImgWeight(BufferedImage img) {
179         int width = img.getWidth();
180         int height = img.getHeight();
181         int[][] weight = new int[width][height];
182         for (int x = 0; x < width; ++x) {
183             for (int y = 0; y < height; ++y) {
184                 if (isBlank(img.getRGB(x, y))) {
185                     weight[x][y] = 1;
186                 }
187             }
188         }
189         return weight;
190     }
191
192
193     public static void main(String[] args) throws Exception {
194         String result = new ImageProcess("C:/login.jpg").getResult();
195         System.out.println(result);
196
197     }
198 }