精华内容
下载资源
问答
  • 资源包括Java代码以及引用包、tesseract安装包和使用说明
  • NULL 博文链接:https://lvhuiqing.iteye.com/blog/1474186
  • Java验证码工具

    2018-07-20 17:42:44
    Java生成验证码图片工具类。使用时直接解压,将工具类导入Java项目即可,直接调用生成验证码方法即可。
  • 使用java来做验证码识别,识别一些普通的验证码图片 前言: 我们都知道,验证码的作用是用来验证你是否为机器人,基本是做反爬虫或刷数据的一类功能验证。针对这种情况,引用一位老人家的名言,“要用魔法打败魔法”...

    使用java来做验证码识别,识别一些普通的验证码图片

    最近公司要做爬虫
    前言:
    我们都知道,验证码的作用是用来验证你是否为机器人,基本是做反爬虫或刷数据的一类功能验证。针对这种情况,引用一位老人家的名言,“要用魔法打败魔法”,我们想爬别人数据只能通过更高明的技术。本文介绍的也不是啥高明的手段,毕竟只能识别一些简单的验证码,废话少说,直接上干货。

    思路分析:
    代码并不是我原创的,我只是一个裁缝,把别人的布自己拼一拼,再用点自己的线。验证码区分是否是机器和真人的方式就是在图片上加上一些干扰线,干扰机器的识别。

    示例图片:
    在这里插入图片描述
    这些杂线干扰了机器的识别,BAT提供的云服务ocr识别不了。我们需要进行格式化,通过代码的操作后生成的图片为
    在这里插入图片描述
    去掉了干扰线以后在使用orc识别准确率基本到80%~90%了。但是机器容易自动识别出一些空格,有的杂线没有完全去除,导致识别出"、"," ` "等各种字符(例如示例验证码R下的、),所以我加了字符的过滤,只留下字母和数字。也有一些J会识别成 ] ,所以在过滤之前加一下判断,这个需要自己来加,我没有加。

    ocr识别是引入的一个jar包,有防爬虫执行,识别几次后让你点击才能继续执行。针对这点可以把免费的jar包换位云服务的识别接口。

    首先引入pom依赖

    <!-- 获取并识别验证码-->
            <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.15</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.8.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/commons-httpclient/commons-httpclient -->
            <dependency>
                <groupId>commons-httpclient</groupId>
                <artifactId>commons-httpclient</artifactId>
                <version>3.1</version>
            </dependency>
            <dependency>
                <groupId>com.asprise.ocr</groupId>
                <artifactId>java-ocr-api</artifactId>
                <version>15.3.0.3</version>
            </dependency>
    

    然后是工具类,工具类有两个方法,

    package com.evaluation.train.common.util;
    
    
    import com.asprise.ocr.Ocr;
    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.HttpStatus;
    import org.apache.commons.httpclient.methods.GetMethod;
    import org.apache.commons.io.IOUtils;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.util.Date;
    
    public class OCRCodeUtil {
        /**
         *  根据接口地址识别
         * @param netPath http链接
         * @param savePath 验证码图片保存到本地的位置
         * @param destDir 验证码可识别操作后的保存位置
         * @return
         * @throws IOException
         */
        public static String DictCode(String netPath, String savePath, String destDir) throws IOException {
            //把文件保存到本地地址
            HttpClient httpClient = new HttpClient();
            GetMethod getMethod = new GetMethod(netPath);
            int statusCode = httpClient.executeMethod(getMethod);
            if (statusCode != HttpStatus.SC_OK) {
                System.err.println("Method failed: " + getMethod.getStatusLine());
                return "Method failed: " + getMethod.getStatusLine();
            }
            String picName = savePath;
            File filepic = new File(picName);
            if (!filepic.exists())
                filepic.mkdir();
            String fileName = picName + new Date().getTime() + ".jpg";
            File filepicF = new File(fileName);
            InputStream inputStream = getMethod.getResponseBodyAsStream();
            OutputStream outStream = new FileOutputStream(filepicF);
            IOUtils.copy(inputStream, outStream);
            outStream.close();
            filepicF = new File(fileName);
            cleanLinesInImage(filepicF, destDir);
            Ocr.setUp(); // one time setup
            Ocr ocr = new Ocr(); // create a new OCR engine
            ocr.startEngine("eng", Ocr.SPEED_FASTEST); // English
            String code = ocr.recognize(new File[]{filepicF}, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
    //        char[] chars = code.toCharArray();
    //        for (int i = 0; i < chars.length; i++) {
    //            switch (chars[i]) {
    //                case ']':
    //                    chars[i] = 'j';
    //                    break;
    //            }
    //        }
    //        code = chars.toString();
            code = code.replaceAll("[^0-9a-zA-Z]", "");
            ocr.stopEngine();
            return code;
    
        }
    
        /**
         * 根据本地路径识别
         *
         * @param sfile   识别的file
         * @param destDir 处理后放入的文件夹
         * @return
         * @throws IOException
         */
        public static String DictCode(File sfile, String destDir) throws IOException {
            cleanLinesInImage(sfile, destDir);
            File filepicF = new File(destDir + sfile.getName());
            Ocr.setUp(); // one time setup
            Ocr ocr = new Ocr(); // create a new OCR engine
            ocr.startEngine("eng", Ocr.SPEED_FASTEST); // English
            String code = ocr.recognize(new File[]{filepicF}, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
    //        char[] chars = code.toCharArray();
    //        for (int i = 0; i < chars.length; i++) {
    //            switch (chars[i]) {
    //                case ']':
    //                    chars[i] = 'j';
    //                    break;
    //            }
    //        }
    //        code = chars.toString();
            code = code.replaceAll("[^0-9a-zA-Z]", "");
            ocr.stopEngine();
            return code;
    
        }
    
        /**
         * @param sfile   需要去噪的图像
         * @param destDir 去噪后的图像保存地址
         * @throws IOException
         */
        public static void cleanLinesInImage(File sfile, String destDir) throws IOException {
            File destF = new File(destDir);
            if (!destF.exists()) {
                destF.mkdirs();
            }
    
            BufferedImage bufferedImage = ImageIO.read(sfile);
            int h = bufferedImage.getHeight();
            int w = bufferedImage.getWidth();
    
            // 灰度化
            int[][] gray = new int[w][h];
            for (int x = 0; x < w; x++) {
                for (int y = 0; y < h; y++) {
                    int argb = bufferedImage.getRGB(x, y);
                    // 图像加亮(调整亮度识别率非常高)
                    int r = (int) (((argb >> 16) & 0xFF) * 1.1 + 30);
                    int g = (int) (((argb >> 8) & 0xFF) * 1.1 + 30);
                    int b = (int) (((argb >> 0) & 0xFF) * 1.1 + 30);
                    if (r >= 255) {
                        r = 255;
                    }
                    if (g >= 255) {
                        g = 255;
                    }
                    if (b >= 255) {
                        b = 255;
                    }
                    gray[x][y] = (int) Math
                            .pow((Math.pow(r, 2.2) * 0.2973 + Math.pow(g, 2.2)
                                    * 0.6274 + Math.pow(b, 2.2) * 0.0753), 1 / 2.2);
                }
            }
    
            // 二值化
            int threshold = ostu(gray, w, h);
            BufferedImage binaryBufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
            for (int x = 0; x < w; x++) {
                for (int y = 0; y < h; y++) {
                    if (gray[x][y] > threshold) {
                        gray[x][y] |= 0x00FFFF;
                    } else {
                        gray[x][y] &= 0xFF0000;
                    }
                    binaryBufferedImage.setRGB(x, y, gray[x][y]);
                }
            }
    
            //去除干扰线条
            for (int y = 1; y < h - 1; y++) {
                for (int x = 1; x < w - 1; x++) {
                    boolean flag = false;
                    if (isBlack(binaryBufferedImage.getRGB(x, y))) {
                        //左右均为空时,去掉此点
                        if (isWhite(binaryBufferedImage.getRGB(x - 1, y)) && isWhite(binaryBufferedImage.getRGB(x + 1, y))) {
                            flag = true;
                        }
                        //上下均为空时,去掉此点
                        if (isWhite(binaryBufferedImage.getRGB(x, y + 1)) && isWhite(binaryBufferedImage.getRGB(x, y - 1))) {
                            flag = true;
                        }
                        //斜上下为空时,去掉此点
                        if (isWhite(binaryBufferedImage.getRGB(x - 1, y + 1)) && isWhite(binaryBufferedImage.getRGB(x + 1, y - 1))) {
                            flag = true;
                        }
                        if (isWhite(binaryBufferedImage.getRGB(x + 1, y + 1)) && isWhite(binaryBufferedImage.getRGB(x - 1, y - 1))) {
                            flag = true;
                        }
                        if (flag) {
                            binaryBufferedImage.setRGB(x, y, -1);
                        }
                    }
                }
            }
    
    
            // 矩阵打印
    //        for (int y = 0; y < h; y++) {
    //            for (int x = 0; x < w; x++) {
    //                if (isBlack(binaryBufferedImage.getRGB(x, y))) {
    //                    //System.out.print("*");
    //                } else {
    //                    //System.out.print(" ");
    //                }
    //            }
    //            //System.out.println();
    //        }
            ImageIO.write(binaryBufferedImage, "jpg", new File(destDir, sfile
                    .getName()));
        }
    
        public static boolean isBlack(int colorInt) {
            Color color = new Color(colorInt);
            if (color.getRed() + color.getGreen() + color.getBlue() <= 300) {
                return true;
            }
            return false;
        }
    
        public static boolean isWhite(int colorInt) {
            Color color = new Color(colorInt);
            if (color.getRed() + color.getGreen() + color.getBlue() > 300) {
                return true;
            }
            return false;
        }
    
        public static int isBlackOrWhite(int colorInt) {
            if (getColorBright(colorInt) < 30 || getColorBright(colorInt) > 730) {
                return 1;
            }
            return 0;
        }
    
        public static int getColorBright(int colorInt) {
            Color color = new Color(colorInt);
            return color.getRed() + color.getGreen() + color.getBlue();
        }
    
        public static int ostu(int[][] gray, int w, int h) {
            int[] histData = new int[w * h];
            // Calculate histogram
            for (int x = 0; x < w; x++) {
                for (int y = 0; y < h; y++) {
                    int red = 0xFF & gray[x][y];
                    histData[red]++;
                }
            }
    
            // Total number of pixels
            int total = w * h;
    
            float sum = 0;
            for (int t = 0; t < 256; t++)
                sum += t * histData[t];
    
            float sumB = 0;
            int wB = 0;
            int wF = 0;
    
            float varMax = 0;
            int threshold = 0;
    
            for (int t = 0; t < 256; t++) {
                wB += histData[t]; // Weight Background
                if (wB == 0)
                    continue;
    
                wF = total - wB; // Weight Foreground
                if (wF == 0)
                    break;
    
                sumB += (float) (t * histData[t]);
    
                float mB = sumB / wB; // Mean Background
                float mF = (sum - sumB) / wF; // Mean Foreground
    
                // Calculate Between Class Variance
                float varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF);
    
                // Check if new maximum found
                if (varBetween > varMax) {
                    varMax = varBetween;
                    threshold = t;
                }
            }
    
            return threshold;
        }
    }
    
    
    展开全文
  • Java识别图像、验证码

    2021-03-06 03:51:24
    前言这是一个学习案例,看最后一张图,识别率应该有90%以上吧!提高识别度代码处理,放大图像不清晰的图像,像素不好的,如果已经是最好效果了,建议不要处理(放大),就这样子直接识别。/** 对图片进行处理 - 提高...

    前言

    这是一个学习案例,看最后一张图,识别率应该有90%以上吧!

    提高识别度

    代码处理,放大图像

    不清晰的图像,像素不好的,如果已经是最好效果了,建议不要处理(放大),就这样子直接识别。

    /** 对图片进行处理 - 提高识别度 **/

    private static BufferedImage convertImage(BufferedImage image) throws Exception {

    //按指定宽高创建一个图像副本

    //image = ImageHelper.getSubImage(image, 0, 0, image.getWidth(), image.getHeight());

    //图像转换成灰度的简单方法 - 黑白处理

    image = ImageHelper.convertImageToGrayscale(image);

    //图像缩放 - 放大n倍图像

    image = ImageHelper.getScaledInstance(image, image.getWidth() * 3, image.getHeight() * 3);

    return image;

    }

    图片倾斜处理

    BufferedImage bi = ImageIO.read(imageFile);

    ImageDeskew id = new ImageDeskew(bi);

    double imageSkewAngle = id.getSkewAngle(); //获取倾斜角度

    if ((imageSkewAngle > 0.05d || imageSkewAngle < -(0.05d))) {

    bi = ImageHelper.rotateImage(bi, -imageSkewAngle); //纠偏图像

    }

    1.识别模糊图像

    /**

    * 模糊图像,像素不好,建议不放大。

    */

    testMHYzm();

    40394b3f7fab46a0f2403a45d4830845.png

    2.识别清晰图像

    /**

    * 清晰图像,建议放大,识别度更精准。

    */

    testConvertYzm();

    efbf94c4ad8cade183c11562f4833eeb.png

    3.识别英文图像

    /**

    * 识别英文图像

    */

    testConvertEn();

    a2c82dadde697607a66b25b9cb563c9e.png

    4.识别中文图像

    /**

    * 识别中文图像

    */

    testConvertZh();

    b4888934f7fb6ee2fe6b2cdc036677fc.png

    源代码地址

    展开全文
  • java验证码 工具

    2016-04-07 09:16:24
    这个方法直接生成验证码 前台只需要把地址写对就能直接用,可以当作工具类用,不需要访问 页面加载完成就可以了 package www.sshblank.util; import java.awt.Color; import java.awt.Font; import java.awt....

    这个方法直接生成验证码 前台只需要把地址写对就能直接用,可以当作工具类用,不需要访问 页面加载完成就可以了

    package www.sshblank.util;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.util.Random;
    
    import javax.imageio.ImageIO;
    
    public class ImageUtil {
    	private static final int WIDTH = 130;
    	private static final int HEIGHT = 30;
    
    	public static String outPutImage(OutputStream om) throws IOException {
    		//创建一幅图片
    		BufferedImage image=new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);
    		//得到gracphics对象
    		Graphics g=image.getGraphics();
    		//设置背景
    		g.setColor(Color.red);
    		g.setClip(0, 0, WIDTH, HEIGHT);
    		//设置边框
    		g.setColor(Color.blue);
    		g.setClip(1, 1, WIDTH-2, HEIGHT-2);
    		//向图片化干扰线
    		for(int i=0;i<8;i++){
    			g.setColor(Color.gray);
    			int x1=new Random().nextInt(WIDTH);
    			int x2=new Random().nextInt(HEIGHT);
    			int y1=new Random().nextInt(HEIGHT);
    			int y2=new Random().nextInt(WIDTH);
    			g.drawLine(x1, y1, x2, y2);
    		}
    		//向图片输出验证码
    		String base="0123456789abcdefghijklmnopqrstuvwxyz";
    		StringBuffer str=new StringBuffer();
    		for(int i=0;i<4;i++){
    			int ran=new Random().nextInt(base.length()-1);
    			str.append(base.charAt(ran));
    		}
    		g.setColor(Color.green);
    		g.setFont(new Font("宋体",Font.PLAIN,20));
    		//旋转
    		Graphics2D gg=(Graphics2D)g;
    		gg.rotate(0.05);
    		
    		g.drawString(str.toString(), 10, 20);
    	//发送到客户端
    		ImageIO.write(image, "jpeg", om);
    		return str.toString();
    	}
    }
    

    html

    我用的是jquery Easyui 的验证框,你也可以用普通的验证

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'index.jsp' starting page</title>
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<LINK rel="stylesheet" href="${pageContext.request.contextPath}/css/common/login.css" type="text/css">
    	<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery.js" ></script>
    	<script type="text/javascript">
    		function login(){
    			//获取用户名
    			var userName = $('#name').val();
    			//获取密码
    			var password = $('#password').val();
    			//获取验证码
    			var kaptchaCode = $('#check').val();
    			if(userName!=null&&userName!=""&&userName!=undefined){
    				if(password!=null&&password!=""&&password!=undefined){
    					if(kaptchaCode!=null&&kaptchaCode!=""&&kaptchaCode!=undefined){
    						$.ajax({
    							type : "post",
    							dataType :"json",
    							data : $("#form").serialize(),
    							url : "${pageContext.request.contextPath}/school/login",
    							success : function(data) {
    								if (data.success) {
    									window.location.href = "${pageContext.request.contextPath}/school/pass";
    								} else {
    									$("#error").text(data.msg);
    								}
    							},
    							error : function() {
    								$("#error").text('服务器开小差,赶紧联系管理员!');
    							}
    						});
    					}else{
    						$("#error").text("验证码不能为空");
    					}
    				}else{
    					$("#error").text("密码不能为空");
    				}
    			}else{
    				$("#error").text("用户名不能为空");
    			}
    		};
    		$(function(){
    			$("#huan").click(
    				function(){
    					// 生成验证码
    					$(this).hide().attr('src', '${pageContext.request.contextPath }/code+?ran=" + Math.random();
    			});             
    <span style="color:#ff0000;">                              注意<span style="font-family:Helvetica, Tahoma, Arial, sans-serif;line-height: 25px;">假如url相同的话,浏览器会从本地缓存先读 取,那么这样就刷新及木有用处</span></span><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;line-height: 25px;"><span style="color:#ff0000;"> 而加了随机数相当于每次url都不相同,会从服务器重新 取得。
                                                                 url就是你生成验证码的那个类                       
       </span></span> //设置焦点
    			$("#name,#password,#check").focus(
    				function(){
    				$("#error").text('');
    			});
    		});
    	</script>
      </head>
      
      <body>
      	<div class="container">
      		<div class="heading">
      			<img class="logo" src="images/login/logo.png" />
      			<span>学校管理平台</span>
      		</div>
      		<div class="main">
      			<div class="left">
      				<img class="login_bg" src="images/login/login_bg_02.png" />
    	  		</div>
    	  		<div class="right">
    	  			<form id="form">
    	  				<div class="login">
    	  					<div>用户登录</div>
    	  					<dl>
    								<dt>用户名</dt>
    								<dd>
    									<input type="text" id="name" name="userName" maxlength="16">
    								</dd>
    						</dl>
    		  				<dl>
    								<dt>密    码</dt>
    								<dd>
    									<input type="password" id="password" name="password" maxlength="16">
    								</dd>
    							</dl>
    							<dl>
    								<dt>验证码</dt>
    								<dd style="width: 120px;">
    									<input type="text" id="check" name="check" maxlength="16" style="width: 100px;">
    								</dd>
    								<dd style="width: 120px;">
    									<div class="kaptchaImg">
    										<img src="${pageContext.request.contextPath }/code" id="huan"  style="width: 140px;height: 30px"/>
    									</div>
    								</dd>
    							</dl>
    							<!--<dl>
    								<dd>
    									<div class="kaptchaImg">
    										<img src="${pageContext.request.contextPath}/CaptchaImageCreateController/captcha-image" id="kaptchaImage"  style="width: 200px;height: 30px"/>
    									</div>
    								</dd>
    							</dl>-->
    							<div class="login_btn">
    								<input type="button" name="imageField" id="imageField" style="background:#F90;width: 350px;height: 40px;" value="登  录" οnclick="login()" />
    							</div>
    							<div>
    								<font color="red" id="error"></font> 
    							</div>
    	  				</div>
    	  			</form>
    	  		</div>
      		</div>
      		<div class="footer">
      			<a href="${pageContext.request.contextPath}/school/teacherLogin">教师登陆</a>
      		</div>
      	</div>
      </body>
    </html>
    

    注意假如url相同的话,浏览器会从本地缓存先读 取,那么这样就刷新及木有用处 而加了随机数相当于每次url都不相同,会从服务器重新 取得。

    展开全文
  • Java实现验证码识别

    千次阅读 2019-07-17 11:40:35
    java识别验证码比较简单,使用的软件是tesseractocr,这个软件需要安装在本地中,傻瓜式安装(方便调用)。 github下载地址https://github.com/tesseract-ocr/tessdata 博主是在官网下载的。 该软件默认的识别...

    java中识别验证码比较简单,使用的软件是tesseractocr,这个软件需要安装在本地中,傻瓜式安装(方便调用) 。

    github下载地址 
    https://github.com/tesseract-ocr/tessdata

    博主是在官网下载的。

    该软件默认的识别的是英文。如果需要识别中文,需要将中文的训练文本chi_sim.traineddata存放到C:\Program Files (x86)\Tesseract-OCR\tessdata。

    简单的验证码识别 直接调用 Tesseract的 doOCR(image)方法即可。如果验证码的噪点多 并且有干扰线,这时候就需要对图像就行处理了。

    图片处理大致思路:做灰度然后二值化 然后去除干扰线。

    话不多说上代码。

    实现代码

    public static void main(String[] args) { 
    	String url = "验证图片地址";
            //验证码保存地址
            String path= "C:\\Users\\Administrator\\Desktop\\1.jpg"; 
            //下载验证码 
            downloadPicture(url,path);
    	Demo demo= new Demo(); 
    	String code= demo.FindOCR(path,false);
    	System.out.println(code); 
    }

    下载验证码很简单就是用HTTPClient获取验证图片的链接然后下载就可以了。我这里只放一个下载的代码。至于获取连接的每个网站的请求也不一样就不放出了。

        private static void downloadPicture(String urlList,String path) {
            URL url = null;
            try {
                url = new URL(urlList);
                DataInputStream dataInputStream = new DataInputStream(url.openStream());
                FileOutputStream fileOutputStream = new FileOutputStream(new File(path));
                ByteArrayOutputStream output = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int length;
     
                while ((length = dataInputStream.read(buffer)) > 0) {
                    output.write(buffer, 0, length);
                }
                fileOutputStream.write(output.toByteArray());
                dataInputStream.close();
                fileOutputStream.close();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    识别验证码的工具类

    public  String FindVCode(String srcImg, boolean language) {
            try {
                File imgFile = new File(srcImg);
                if (!srcImg.exists()) {
                    return "图片路径有误或不存在";
                }
                BufferedImage testImage = ImageIO.read(imgFile);
                Tesseract tesseract= new Tesseract();
                // 默认的图片库
                instance.setDatapath("/usr/local/share/tessdata/");
                if (language) {
                    tesseract.setLanguage("chi_sim");
                }
                String vCode= null;
                // 下面是去图像优化的过程 不需要的可以不用 直接 vCode =instance.doOCR(testImage) ;
                BufferedImage cleanedImg = cleanLinesInImage(testImage);
                vCode= tesseract.doOCR(cleanedBufferedImage);
                return vCode;
            } catch (Exception e) {
                e.printStackTrace();
                return "未知错误";
            }
        }

    图片处理过程

    private BufferedImage cleanLinesInImage(BufferedImage image) throws IOException{
    
            BufferedImage bufferedImage = oriBufferedImage;
            int h = bufferedImage.getHeight();
            int w = bufferedImage.getWidth();
    
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                     boolean c = true;
                     // 这个像素块上下左右是不是都是黑色的,如果是,这个像素当作黑色的
                     int roundWhiteCount = 0;
                     if (isBlackColor(bufferedImage , x + 1, y + 1)){
                         roundWhiteCount++;
                        }
                     if (isBlackColor(bufferedImage , x + 1, y - 1)){
                         roundWhiteCount++;
                        }
                     if (isBlackColor(bufferedImage , x - 1, y + 1)){
                         roundWhiteCount++;
                        }
                     if (isBlackColor(bufferedImage , x - 1, y - 1)){
                         roundWhiteCount++;
                        }
                     if (roundWhiteCount >= 4) {
                         c = false;
                        }
                     if (!isBlackColor(bufferedImage , x, y) && c) {
                         image.setRGB(x, y, 0xFFFFFFFF); //argb:AARRGGBB
                     }
            }
        }
        //把不是纯白色的像素块变成黑色的,用来做判断条件
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                // 不是纯白就填黑
                if ((bufferedImage .getRGB(x, y) & 0xFFFFFF) != (new Color(255, 255, 255).getRGB() & 0xFFFFFF)) {
                    bufferedImage .setRGB(x, y, 0xFF000000);
                }
            }
        }
            // 二值化
            int threshold = ostu(gray, w, h);
            BufferedImage binaryBufferedImage= new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
            for (int x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    if (gray[x][y] > threshold)
                    {
                        gray[x][y] |= 0x00FFFF;
                    } else
                    {
                        gray[x][y] &= 0xFF0000;
                    }
                    binaryBufferedImage.setRGB(x, y, gray[x][y]);
                }
            }
       cleanImage(binaryBufferedImage,h,w );
    
      return binaryBufferedImage;
    }
    private boolean isBlackColor(BufferedImage image, int x, int y) {
        // 检查这个像素块是不是边缘的
        if (x < 0 || y < 0 || x >= image.getWidth() || y >= image.getHeight()) {
            return false;
        }
    
        int pixel = image.getRGB(x, y);
    
        return
                // R
                (pixel & 0xFF0000) >> 16 < 30
                 // G
                 && (pixel & 0xFF00) >> 8 < 30
                 // B
                 && (pixel & 0xFF) < 30;
    }
    public void cleanImage(BufferedImage binaryBufferedImage,int h ,int w ){
            //去除干扰线条
            for(int y = 1; y < h-1; y++){
                for(int x = 1; x < w-1; x++){
                    boolean flag = false ;
                    if(isBlack(binaryBufferedImage.getRGB(x, y))){
                        //左右均为空时,去掉此点
                        if(isWhite(binaryBufferedImage.getRGB(x-1, y)) && isWhite(binaryBufferedImage.getRGB(x+1, y))){
                            flag = true;
                        }
                        //上下均为空时,去掉此点
                        if(isWhite(binaryBufferedImage.getRGB(x, y+1)) && isWhite(binaryBufferedImage.getRGB(x, y-1))){
                            flag = true;
                        }
                        //斜上下为空时,去掉此点
                        if(isWhite(binaryBufferedImage.getRGB(x-1, y+1)) && isWhite(binaryBufferedImage.getRGB(x+1, y-1))){
                            flag = true;
                        }
                        if(isWhite(binaryBufferedImage.getRGB(x+1, y+1)) && isWhite(binaryBufferedImage.getRGB(x-1, y-1))){
                            flag = true;
                        }
                        if(flag){
                            binaryBufferedImage.setRGB(x,y,-1);
                        }
                    }
                }
            }
        }
    
        public Mat bufferedImageToMat(BufferedImage bi) {
            Mat mat = new Mat(bi.getHeight(), bi.getWidth(), CvType.CV_8UC1);
    
            byte[] white = new byte[] { (byte) 255 };
            byte[] black = new byte[] { (byte) 0 };
    
            for (int x=0; x<bi.getWidth(); x++) {
                for (int y=0; y<bi.getHeight(); y++) {
                    if (bi.getRGB(x, y) == Color.BLACK.getRGB()) {
                        mat.put(y, x, black);
                    } else {
                        mat.put(y, x, white);
                    }
                }
            }
            return mat;
        }
    
        /**
         * Mat转换成BufferedImage
         *
         * @param matrix
         *            要转换的Mat
         * @param fileExtension
         *            格式为 ".jpg", ".png", etc
         * @return
         */
        public BufferedImage mat2BufImg (Mat matrix, String fileExtension) {
            // convert the matrix into a matrix of bytes appropriate for
            // this file extension
            MatOfByte mob = new MatOfByte();
            Imgcodecs.imencode(fileExtension, matrix, mob);
            // convert the "matrix of bytes" into a byte array
            byte[] byteArray = mob.toArray();
            BufferedImage bufImage = null;
            try {
                InputStream in = new ByteArrayInputStream(byteArray);
                bufImage = ImageIO.read(in);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return bufImage;
        }
    
        public boolean isBlack(int colorInt)
        {
            Color color = new Color(colorInt);
            if (color.getRed() + color.getGreen() + color.getBlue() <= 300)
            {
                return true;
            }
            return false;
        }
    
        public boolean isWhite(int colorInt)
        {
            Color color = new Color(colorInt);
            if (color.getRed() + color.getGreen() + color.getBlue() > 300)
            {
                return true;
            }
            return false;
        }
    
        public int isBlackOrWhite(int colorInt)
        {
            if (getColorBright(colorInt) < 30 || getColorBright(colorInt) > 730)
            {
                return 1;
            }
            return 0;
        }
    
        public int getColorBright(int colorInt)
        {
            Color color = new Color(colorInt);
            return color.getRed() + color.getGreen() + color.getBlue();
        }
    
        public int ostu(int[][] gray, int w, int h)
        {
            int[] histData = new int[w * h];
            // Calculate histogram
            for (int x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    int red = 0xFF & gray[x][y];
                    histData[red]++;
                }
            }
    
            // Total number of pixels
            int total = w * h;
    
            float sum = 0;
            for (int t = 0; t < 256; t++)
                sum += t * histData[t];
    
            float sumB = 0;
            int wB = 0;
            int wF = 0;
    
            float varMax = 0;
            int threshold = 0;
    
            for (int t = 0; t < 256; t++)
            {
                wB += histData[t]; // Weight Background
                if (wB == 0)
                    continue;
    
                wF = total - wB; // Weight Foreground
                if (wF == 0)
                    break;
    
                sumB += (float) (t * histData[t]);
    
                float mB = sumB / wB; // Mean Background
                float mF = (sum - sumB) / wF; // Mean Foreground
    
                // Calculate Between Class Variance
                float varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF);
    
                // Check if new maximum found
                if (varBetween > varMax)
                {
                    varMax = varBetween;
                    threshold = t;
                }
            }
    
            return threshold;
        }
    

    其中部分是借鉴网上的源代码。如果有编写不对,或者可以修改的更好的建议请指出。

     

     

    展开全文
  • Java实现超简单验证码识别

    万次阅读 2018-06-09 23:03:49
    闲来想实现程序模拟登陆一个系统,说白了,就是写个简单的爬虫,但是无奈,遇到了数字图片验证码,在查阅了一些方案以后,遂决定自己手写代码实现验证码识别,分享一下整个过程。 图片验证码是什么 图片验证码...
  • java 验证码识别 ocr

    2019-03-27 03:21:02
    NULL 博文链接:https://oma1989.iteye.com/blog/1168433
  • 图片验证码识别,简单写下,做个备忘。   一、注册百度账号及新增一个应用,获取百度API所需的AppID,API Key,Secret Key三个参数。 访问http://ai.baidu.com,使用百度账号登录后,出现如下界面 成功创建...
  • Java识别验证码和图像处理

    万次阅读 多人点赞 2018-06-07 12:07:47
    这里老样子先说几句无关的话,去年毕业的时候帮同学做了一个验证码识别系统,按部就班的参考了大神的操作,对于二值化这些操作都没有深入了解,最近做项目遇到了要实现机器登录的操作,验证码自然绕不过去所以就又翻...
  • JAVA验证码识别

    2015-08-11 09:17:37
    java验证码识别工具,不要用于非法用途
  • 目录 1、tesseract-ocr下载...1.1 java代码加载tesseract路径并识别 private static void getIdentifyPictrue(){ //验证码图片存储地址 File imageFile = new File(“E:\tessreact\pictrue\11.jpg”); if(!imageFile
  • 一个非常好用的验证码识别工具类api接口群发?批量操作?验证码?可能乖孩子对于这些单个有了解,但是对于合在一起就不知道其存在的意义。这个对于我们日常的生活可能是没有什么用处的,但是对于需要批量检测,顶贴...
  • 验证码识别-Java

    千次阅读 2021-01-20 10:36:56
    前段时间用Java写了个爬虫爬教务处网站,于是有朋友问我是怎么实现验证码识别的,在此将这个小方法分享出来!
  • java解析图片验证码

    热门讨论 2014-01-20 10:31:13
    java解析图片验证码
  • JAVA-简单实用生成图片验证码工具类如何快速生成图片验证码第三方依赖关系核心代码单元测试用例 如何快速生成图片验证码 生成图片验证码是每个B/S架构项目的必备工具,该博文介绍如果快速、简单、生成实用的图片...
  • 我们在性能测试中总会时不时地遭遇到来自于应用系统的各种阻碍,图片验证码就是一类最常见的束缚,登录或交易时需要按照图片中的内容输入正确的验证信息后,数据才可以提交成功,这使得许多性能测试工具只能望而却步...
  • JAVA识别复杂验证码+图像处理

    千次阅读 2019-06-14 11:44:00
    先对验证码进行简单的处理噪点和纯色 例未曾处理的图片 public static void main(String[] args) throws Exception { //源文件 String picName = "C:\\Users\\syxy101\\Desktop\\6.jpg"; File filepic=new File...
  • 1.完美验证码识别系统制作字库简单流程 2.支持多线程并发识别,识别无需加许可. 3.识别速度是某时代的10倍以上.制作字库也比某时代快多了.某时代可以做的码,本工具一定可以做,而本工具做得了的,某代不一定可以做 4...
  • 全自动图形图片验证码识别工具。 在以前的互联网是没有验证码的,后来随着一些自动程序的出现(如自动注册邮箱、自动发布信息等),对网络的正常使用产生越来越严重的影响,便产生了验证码。 使用验证码的目的是通过...
  • JAVA---获取图片验证码

    2021-03-04 00:12:06
    上网查找资料,参考改了一个工具类,并添加到程序中package com.guantong.seeing.common;import javax.imageio.ImageIO;import java.awt.*;import java.awt.image.BufferedImage;import java.io.ByteArrayOutputStream...
  • java识别验证码

    2019-12-10 14:48:27
    之前在做数据核对部分工作,需要获取厂商的...这里记录一下识别验证码的过程。 使用tess4j 1.下载tessdata和训练语言包  在tessract的github直接下载即可,下载地址戳我(只需要项目的 tessdata文件夹 )。这里,...
  • JAVA验证识别:基于jTessBoxEditorFX和Tesseract-OCR训练样本 工具准备: jTessBoxEditorFX下载:https://github.com/nguyenq/jTessBoxEditorFX Tesseract-OCR下载:...
  • 文章目录前言一丶解析验证码组成二丶分析出破解思路三丶具体操作步骤四丶结果展示五丶结果分析六丶结语 前言 本文详细介绍了破解极验滑动验证码的所有过程,包括破解思路,实现步骤以及测试结果,相信你看完之后也...
  • 2.通过验证码的坐标实现每次截验证码的图片的精准坐标,每次通过该坐标来截图,调用文字识别接口,实现验证码识别识别之后,复制到剪贴板。 3.截验证码提交表单的小图,再截整个电脑屏幕,通过大图找小图的方法...
  • 我用此项目把某网站的数字验证码都截了图做成了训练库,识别率95%以上,用browserTest简单实现了程序自动登录与各种操作功能。 测试类: TestDemo.java MyDemo.java MyDemo2.java Longan-master项目 此项目也是纯...
  • Java简单验证码识别

    2013-08-26 17:12:00
    1. 需求 因为项目需要,需要多次登录某网站抓取信息。所以学习了验证码的一些小知识。... 需要程序识别的验证码格式如图所示:,这个...验证码识别基本分四步,图片预处理,分割,训练,识别。为便于演示,我这里分...
  • 这是我在业余时间用java语言实现的验证码识别功能,其中用到OCR工具,这个需要提前下载安装,不懂的童鞋自行google之。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,792
精华内容 2,716
关键字:

java验证码识别工具

java 订阅