java 简单验证码识别

import java.awt.Color;
import java.awt.Image;
import java.awt.Label;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.imageio.ImageIO;


public class Yanzhengma {
    private static Map<BufferedImage, String> trainMap = null;  
    public static void main(String[] args) {
        //File name = "e:/c.jpg";
        try {
            //ImageUtils.gray(name, "e:/b.jpg");
            //BufferedImage rb = removeBackgroud(name);
            //File file = new File("e:/c.jpg");
            //ImageIO.write(rb, "jpg", file);
            BufferedImage read = ImageIO.read(new File("E:\\新建文件夹\\b.jpg"));
            Map<BufferedImage, String> loadTrainData = loadTrainData();
            List<BufferedImage> listimg = splitImage(read);
            StringBuffer sb =new StringBuffer();
                for (int i = 0; i < listimg.size(); ++i) {
                    //ImageIO.write(listimg.get(i), "jpg", new File("e:\\新建文件夹\\"+i+".jpg"));
                    String singleCharOcr = getSingleCharOcr(listimg.get(i), loadTrainData);
                    
                    sb.append(singleCharOcr);
                }
                System.out.println(sb);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
     public static List<BufferedImage> splitImage(BufferedImage img) throws Exception  { 
         int iw = img.getWidth();
         int ih = img.getHeight();
         int start=0;
         int end=0;
         List<BufferedImage> subImgs = new ArrayList<BufferedImage>(); 
         List<Integer> weightlist = new ArrayList<Integer>();  
        /*第一次循环判断某一列像素值中有多少个不同于背景色的像素点,也就是图中内容的像素点,
         * 并计算有多少个需要的像素点,把每一列的结果放到list中去
         * 测试图片背景色是白色,
         * */
         for (int i = 0; i < iw; i++) {
            int count=0;
            for (int j = 0; j < ih; j++) {
                if (isBlack(img.getRGB(i, j))==1) {
                    count++;
                }
                
            }
            weightlist.add(count);
        }
         /*第二次循环根据判断的每一列内容的像素点来截取需要的图片区域,并放到一个list<bufferimg>
          * 判断某一列中的有效像素点大于1个的话就累计计数,如果连续12列都存在有效像素点,
          * 那就开始截取这一串累计区域的图片。或者大于3个有效像素也截取,虽然可能是噪点像素
          * 本判断是根据具体图片来判断有效像素的区域,不同图片需要不同分析
          * */
         for (int i = 0; i <weightlist.size(); i++) {
            int length=0;
            while (weightlist.get(i++)>1) {
                length++;
            }
            if (length>12) {
                subImgs.add(removeBlank(img.getSubimage(i-length-1, 0, length, ih)));
//                 subImgs.add(removeBlank(img.getSubimage(i - length / 2 - 1, 0,length , ih)));
            }else if (length>3) {
                 subImgs.add(removeBlank(img.getSubimage(i - length - 1, 0,  
                            length, ih)));  
            }
        }
         
         return subImgs;
        
    }
     
     /*处理单个黑白图片
      * */
     public static BufferedImage removeBlank(BufferedImage img) throws Exception {  
            int width = img.getWidth();  
            int height = img.getHeight();  
            int start = 0;  
            int end = 0;  
            Label1: for (int y = 0; y < height; ++y) {  
                int count = 0;  
                for (int x = 0; x < width; ++x) {  
                    if (isBlack(img.getRGB(x, y)) == 1) {  
                        count++;  
                    }  
                    if (count >= 1) {  
                        start = y;  
                        break Label1;  
                    }  
                }  
            }  
            Label2: for (int y = height - 1; y >= 0; --y) {  
                int count = 0;  
                for (int x = 0; x < width; ++x) {  
                    if (isBlack(img.getRGB(x, y)) == 1) {  
                        count++;  
                    }  
                    if (count >= 1) {  
                        end = y;  
                        break Label2;  
                    }  
                }  
            }  
            return img.getSubimage(0, start, width, end - start + 1);  
        } 
     /*
       * @param判断是否为黑色rgb范围内
       * */
     public static int isBlack(int colorInt) {  
            Color color = new Color(colorInt);  
            if (color.getRed() + color.getGreen() + color.getBlue() <= 100) {  
                return 1;  
            }  
            return 0;  
        } 
     /*
       * @param判断是否为白色rgb范围内
       * */
    public static int isWhite(int colorInt) {  
        Color color = new Color(colorInt);  
        if (color.getRed() + color.getGreen() + color.getBlue() > 100) {  
            return 1;  
        }  
        return 0;  
    }  
  /*
   * @param去除背景杂色,设置为黑白两色
   * */
    public static BufferedImage removeBackgroud(String picFile)  
            throws Exception {  
        BufferedImage img = ImageIO.read(new File(picFile));  
        int width = img.getWidth();  
        int height = img.getHeight();  
        for (int x = 0; x < width; ++x) {  
            for (int y = 0; y < height; ++y) {  
                if (isWhite(img.getRGB(x, y)) == 1) {  
                    img.setRGB(x, y, Color.WHITE.getRGB());  
                } else {  
                    img.setRGB(x, y, Color.BLACK.getRGB());  
                }  
            }  
        }  
        return img;  
    }  
    /*
     * 本方法是训练之后得到单个图片集合
     * @pragm 从已经切分好的图片得到图片和图片名称用来和后面的想要得到结果的图片做对比
     * */
    public static Map<BufferedImage, String> loadTrainData() throws Exception {  
        if (trainMap == null) {  
            Map<BufferedImage, String> map = new HashMap<BufferedImage, String>();  
            File dir = new File("E:\\验证码\\");  
            File[] files = dir.listFiles();  
            for (File file : files) {  
                String[] split = file.getName().split("\\.");
                map.put(ImageIO.read(file), split[0]);  
            }  
            trainMap = map;  
        }  
        return trainMap;  
    }  
    public static String getSingleCharOcr(BufferedImage img,  
            Map<BufferedImage, String> map) {  
        String result = "";  
        int width = img.getWidth();  
        int height = img.getHeight();  
        int min = width * height;  
        for (BufferedImage bi : map.keySet()) {  
            int count = 0;  
            int widthmin = width < bi.getWidth() ? width : bi.getWidth();  
            int heightmin = height < bi.getHeight() ? height : bi.getHeight();  
            Label1: for (int x = 0; x < widthmin; ++x) {  
                for (int y = 0; y < heightmin; ++y) {  
                    if (isBlack(img.getRGB(x, y)) != isBlack(bi.getRGB(x, y))) {  
                        count++;  
                        if (count >= min)  
                            break Label1;  
                    }  
                }  
            }  
            if (count < min) {  
                min = count;  
                result = map.get(bi);  
            }  
        }  
        return result;  
    }  
    public static int getmaxvalue(Map<String, Integer> map) {
        Iterator<Integer> iterator = map.values().iterator();
        int a=0;
        while (iterator.hasNext()) {
            Integer integer = (Integer) iterator.next();
            if (integer>a) {
                a=integer;
            }
            else {
                continue;
            }
        }
        System.out.println(a);
        return a;
 
    
    
    }
}


转载于:https://my.oschina.net/u/2256041/blog/645072

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值