java验证码识别--3

来源:互联网 发布:舞蹈软件下载 编辑:程序博客网 时间:2024/04/27 11:50

来自:http://blog.csdn.net/problc/article/details/5800093

(本文仅用于学习研究图像匹配识别原理,不得用于其他用途。)

完整eclipse工程http://download.csdn.net/detail/problc/3829004

前面的验证码背景都比较简单,用亮度稍微区分一下就可以去掉背景

来看个稍微复杂一点的

1。图片预处理

     怎么去掉背景干扰呢。

     可以注意到每个验证码数字或字母都是同一颜色,所以把验证码平均分成5份

    计算每个区域的颜色分布,除了白色之外,颜色值最多的就是验证码的颜色

    因此很容易将背景去掉

代码:

[java] view plaincopyprint?
  1. public static BufferedImage removeBackgroud(String picFile)  
  2.             throws Exception {  
  3.         BufferedImage img = ImageIO.read(new File(picFile));  
  4.         img = img.getSubimage(11, img.getWidth() - 2, img.getHeight() - 2);  
  5.         int width = img.getWidth();  
  6.         int height = img.getHeight();  
  7.         double subWidth = (double) width / 5.0;  
  8.         for (int i = 0; i < 5; i++) {  
  9.             Map<Integer, Integer> map = new HashMap<Integer, Integer>();  
  10.             for (int x = (int) (1 + i * subWidth); x < (i + 1) * subWidth  
  11.                     && x < width - 1; ++x) {  
  12.                 for (int y = 0; y < height; ++y) {  
  13.                     if (isWhite(img.getRGB(x, y)) == 1)  
  14.                         continue;  
  15.                     if (map.containsKey(img.getRGB(x, y))) {  
  16.                         map.put(img.getRGB(x, y), map.get(img.getRGB(x, y)) + 1);  
  17.                     } else {  
  18.                         map.put(img.getRGB(x, y), 1);  
  19.                     }  
  20.                 }  
  21.             }  
  22.             int max = 0;  
  23.             int colorMax = 0;  
  24.             for (Integer color : map.keySet()) {  
  25.                 if (max < map.get(color)) {  
  26.                     max = map.get(color);  
  27.                     colorMax = color;  
  28.                 }  
  29.             }  
  30.             for (int x = (int) (1 + i * subWidth); x < (i + 1) * subWidth  
  31.                     && x < width - 1; ++x) {  
  32.                 for (int y = 0; y < height; ++y) {  
  33.                     if (img.getRGB(x, y) != colorMax) {  
  34.                         img.setRGB(x, y, Color.WHITE.getRGB());  
  35.                     } else {  
  36.                         img.setRGB(x, y, Color.BLACK.getRGB());  
  37.                     }  
  38.                 }  
  39.             }  
  40.         }  
  41.         return img;  
  42.     }  

处理成这样了,基本就跟验证码识别--2一样了,只是黑白换了一下而已。

2。分割原理和3。训练原理,4。识别都水到渠成了。

 

识别结果如下,识别率100%

上面的处理之后的图片和识别结果,下面是原始图片

完整源码:

[java] view plaincopyprint?
  1. public class ImagePreProcess3 {  
  2.   
  3.     private static Map<BufferedImage, String> trainMap = null;  
  4.     private static int index = 0;  
  5.   
  6.     public static int isBlack(int colorInt) {  
  7.         Color color = new Color(colorInt);  
  8.         if (color.getRed() + color.getGreen() + color.getBlue() <= 100) {  
  9.             return 1;  
  10.         }  
  11.         return 0;  
  12.     }  
  13.   
  14.     public static int isWhite(int colorInt) {  
  15.         Color color = new Color(colorInt);  
  16.         if (color.getRed() + color.getGreen() + color.getBlue() > 600) {  
  17.             return 1;  
  18.         }  
  19.         return 0;  
  20.     }  
  21.   
  22.     public static BufferedImage removeBackgroud(String picFile)  
  23.             throws Exception {  
  24.         BufferedImage img = ImageIO.read(new File(picFile));  
  25.         img = img.getSubimage(11, img.getWidth() - 2, img.getHeight() - 2);  
  26.         int width = img.getWidth();  
  27.         int height = img.getHeight();  
  28.         double subWidth = (double) width / 5.0;  
  29.         for (int i = 0; i < 5; i++) {  
  30.             Map<Integer, Integer> map = new HashMap<Integer, Integer>();  
  31.             for (int x = (int) (1 + i * subWidth); x < (i + 1) * subWidth  
  32.                     && x < width - 1; ++x) {  
  33.                 for (int y = 0; y < height; ++y) {  
  34.                     if (isWhite(img.getRGB(x, y)) == 1)  
  35.                         continue;  
  36.                     if (map.containsKey(img.getRGB(x, y))) {  
  37.                         map.put(img.getRGB(x, y), map.get(img.getRGB(x, y)) + 1);  
  38.                     } else {  
  39.                         map.put(img.getRGB(x, y), 1);  
  40.                     }  
  41.                 }  
  42.             }  
  43.             int max = 0;  
  44.             int colorMax = 0;  
  45.             for (Integer color : map.keySet()) {  
  46.                 if (max < map.get(color)) {  
  47.                     max = map.get(color);  
  48.                     colorMax = color;  
  49.                 }  
  50.             }  
  51.             for (int x = (int) (1 + i * subWidth); x < (i + 1) * subWidth  
  52.                     && x < width - 1; ++x) {  
  53.                 for (int y = 0; y < height; ++y) {  
  54.                     if (img.getRGB(x, y) != colorMax) {  
  55.                         img.setRGB(x, y, Color.WHITE.getRGB());  
  56.                     } else {  
  57.                         img.setRGB(x, y, Color.BLACK.getRGB());  
  58.                     }  
  59.                 }  
  60.             }  
  61.         }  
  62.         return img;  
  63.     }  
  64.   
  65.     public static BufferedImage removeBlank(BufferedImage img) throws Exception {  
  66.         int width = img.getWidth();  
  67.         int height = img.getHeight();  
  68.         int start = 0;  
  69.         int end = 0;  
  70.         Label1: for (int y = 0; y < height; ++y) {  
  71.             for (int x = 0; x < width; ++x) {  
  72.                 if (isBlack(img.getRGB(x, y)) == 1) {  
  73.                     start = y;  
  74.                     break Label1;  
  75.                 }  
  76.             }  
  77.         }  
  78.         Label2: for (int y = height - 1; y >= 0; --y) {  
  79.             for (int x = 0; x < width; ++x) {  
  80.                 if (isBlack(img.getRGB(x, y)) == 1) {  
  81.                     end = y;  
  82.                     break Label2;  
  83.                 }  
  84.             }  
  85.         }  
  86.         return img.getSubimage(0, start, width, end - start + 1);  
  87.     }  
  88.   
  89.     public static List<BufferedImage> splitImage(BufferedImage img)  
  90.             throws Exception {  
  91.         List<BufferedImage> subImgs = new ArrayList<BufferedImage>();  
  92.         int width = img.getWidth();  
  93.         int height = img.getHeight();  
  94.         List<Integer> weightlist = new ArrayList<Integer>();  
  95.         for (int x = 0; x < width; ++x) {  
  96.             int count = 0;  
  97.             for (int y = 0; y < height; ++y) {  
  98.                 if (isBlack(img.getRGB(x, y)) == 1) {  
  99.                     count++;  
  100.                 }  
  101.             }  
  102.             weightlist.add(count);  
  103.         }  
  104.         for (int i = 0; i < weightlist.size();i++) {  
  105.             int length = 0;  
  106.             while (i < weightlist.size() && weightlist.get(i) > 0) {  
  107.                 i++;  
  108.                 length++;  
  109.             }  
  110.             if (length > 2) {  
  111.                 subImgs.add(removeBlank(img.getSubimage(i - length, 0,  
  112.                         length, height)));  
  113.             }  
  114.         }  
  115.         return subImgs;  
  116.     }  
  117.   
  118.     public static Map<BufferedImage, String> loadTrainData() throws Exception {  
  119.         if (trainMap == null) {  
  120.             Map<BufferedImage, String> map = new HashMap<BufferedImage, String>();  
  121.             File dir = new File("train3");  
  122.             File[] files = dir.listFiles();  
  123.             for (File file : files) {  
  124.                 map.put(ImageIO.read(file), file.getName().charAt(0) + "");  
  125.             }  
  126.             trainMap = map;  
  127.         }  
  128.         return trainMap;  
  129.     }  
  130.   
  131.     public static String getSingleCharOcr(BufferedImage img,  
  132.             Map<BufferedImage, String> map) {  
  133.         String result = "#";  
  134.         int width = img.getWidth();  
  135.         int height = img.getHeight();  
  136.         int min = width * height;  
  137.         for (BufferedImage bi : map.keySet()) {  
  138.             int count = 0;  
  139.             if (Math.abs(bi.getWidth()-width) > 2)  
  140.                 continue;  
  141.             int widthmin = width < bi.getWidth() ? width : bi.getWidth();  
  142.             int heightmin = height < bi.getHeight() ? height : bi.getHeight();  
  143.             Label1: for (int x = 0; x < widthmin; ++x) {  
  144.                 for (int y = 0; y < heightmin; ++y) {  
  145.                     if (isBlack(img.getRGB(x, y)) != isBlack(bi.getRGB(x, y))) {  
  146.                         count++;  
  147.                         if (count >= min)  
  148.                             break Label1;  
  149.                     }  
  150.                 }  
  151.             }  
  152.             if (count < min) {  
  153.                 min = count;  
  154.                 result = map.get(bi);  
  155.             }  
  156.         }  
  157.         return result;  
  158.     }  
  159.   
  160.     public static String getAllOcr(String file) throws Exception {  
  161.         BufferedImage img = removeBackgroud(file);  
  162.         List<BufferedImage> listImg = splitImage(img);  
  163.         Map<BufferedImage, String> map = loadTrainData();  
  164.         String result = "";  
  165.         for (BufferedImage bi : listImg) {  
  166.             result += getSingleCharOcr(bi, map);  
  167.         }  
  168.         ImageIO.write(img, "JPG"new File("result3//" + result + ".jpg"));  
  169.         return result;  
  170.     }  
  171.   
  172.     public static void downloadImage() {  
  173.         HttpClient httpClient = new HttpClient();  
  174.         GetMethod getMethod = new GetMethod("http://game.tom.com/checkcode.php");  
  175.         for (int i = 0; i < 30; i++) {  
  176.             try {  
  177.                 // 执行getMethod  
  178.                 int statusCode = httpClient.executeMethod(getMethod);  
  179.                 if (statusCode != HttpStatus.SC_OK) {  
  180.                     System.err.println("Method failed: "  
  181.                             + getMethod.getStatusLine());  
  182.                 }  
  183.                 // 读取内容  
  184.                 String picName = "img3//" + i + ".jpg";  
  185.                 InputStream inputStream = getMethod.getResponseBodyAsStream();  
  186.                 OutputStream outStream = new FileOutputStream(picName);  
  187.                 IOUtils.copy(inputStream, outStream);  
  188.                 outStream.close();  
  189.                 System.out.println(i + "OK!");  
  190.             } catch (Exception e) {  
  191.                 e.printStackTrace();  
  192.             } finally {  
  193.                 // 释放连接  
  194.                 getMethod.releaseConnection();  
  195.             }  
  196.         }  
  197.     }  
  198.   
  199.     public static void trainData() throws Exception {  
  200.         File dir = new File("temp3");  
  201.         File[] files = dir.listFiles();  
  202.         for (File file : files) {  
  203.             BufferedImage img = removeBackgroud("temp3//" + file.getName());  
  204.             List<BufferedImage> listImg = splitImage(img);  
  205.             if (listImg.size() == 5) {  
  206.                 for (int j = 0; j < listImg.size(); ++j) {  
  207.                     ImageIO.write(listImg.get(j), "JPG"new File("train3//"  
  208.                             + file.getName().charAt(j) + "-" + (index++)  
  209.                             + ".jpg"));  
  210.                 }  
  211.             }  
  212.         }  
  213.     }  
  214.   
  215.     /** 
  216.      * @param args 
  217.      * @throws Exception 
  218.      */  
  219.     public static void main(String[] args) throws Exception {  
  220.         //trainData();  
  221.         // downloadImage();  
  222.         for (int i = 0; i < 30; ++i) {  
  223.             String text = getAllOcr("img3//" + i + ".jpg");  
  224.             System.out.println(i + ".jpg = " + text);  
  225.         }  
  226.     }  
  227. }