Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Java识别简单的验证码

1.老规矩,先上图要破解类似这样的验证码:拆分后结果:然后去匹配,得到结果。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.与拆分好的图片进行比较拆分好的图片后,把拆分好的图片再次计算它的权重二维数据,加载之前准备好的"已知值的图片",也计算权重数组。然后对比两个二维数组,如果大部分都匹配,就确定了值。如果没有找到匹配的,就把图片保存下来,人工识别后放入已知值的图片组。 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 }本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-09/122965.htm