利用Tess4J进行验证码识别

前言

最近爬虫兴起,为了避免被爬,很多网站会加入随机图像验证码来设下防线,这时候就需要我们进行图像识别再进行登录操作了。另外,项目中也可能多多少少的用到图像识别功能。所以,今天我们来讲解一下Java的图像识别。

正文

我在网上搜了一下,Java的图像识别开源免费的就Tess4J做得还不错。
① 首先,我们直接引入maven依赖:

        <!--图像识别tess4j-->
        <dependency>
            <groupId>net.sourceforge.tess4j</groupId>
            <artifactId>tess4j</artifactId>
            <version>4.5.1</version>
        </dependency>

此时,如果是刚配maven的小伙伴可能会报:Dependency 'net.sourceforge.tess4j:tess4j:4.5.1' not found
这时候我们就要看一下是不是你的maven库中加载不了这个包了。国内的话,有一个比较好的解决办法:就是在maven的setting.xml文件中加入阿里的镜像

	<mirror>
		<id>alimaven</id>
		<name>aliyun maven</name>
		<!-- https://maven.aliyun.com/repository/public/ -->
		<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
		<mirrorOf>central</mirrorOf>
	</mirror>

具体的maven setting.xml详解请参考:【转】Maven全局配置文件settings.xml详解
实在不行,我们还可以通过下载包加入到本地库的形式:
【转】maven私服没有依赖对应的版本,手动将jar包添加到本地仓库

Tess4J包下载地址

② 下载别人训练好的语言库:语言库github地址
在这里插入图片描述
但是官网的地址貌似下不下来的,大家可以去我的GitHub下载我的项目下来,然后取tessdata文件下面的就可以了。

③ 写Demo代码

public static void main(String[] args) {
        // 识别图片的文件(修改为自己的图片路径)
        String imagePath = ClassLoader.getSystemResource("image/num.jpg").getPath();
        if (imagePath.length()>0){
            imagePath = imagePath.substring(1);
        }
        System.out.println("imagePath:"+imagePath);
        File file = new File(imagePath);
        ITesseract instance = new Tesseract();
        //设置训练库的位置
        String path = ClassLoader.getSystemResource("tessdata").getPath();
        if (path.length()>0){
            path = path.substring(1);
        }
        //打印一下路径,看有没有问题
        System.out.println("tessdata:"+path);
        instance.setDatapath(path);
        //chi_sim :简体中文, eng    根据需求选择语言库
        instance.setLanguage("chi_sim");
        String result = null;
        try {
            long startTime = System.currentTimeMillis();
            result =  instance.doOCR(file);
            long endTime = System.currentTimeMillis();
            System.out.println("Time is:" + (endTime - startTime) + " 毫秒");
        } catch (TesseractException e) {
            e.printStackTrace();
        }

        System.out.println("result: "+result);
    }

这里必须得说明一下,ITesseract 是基于语言库的,如果第二步的语言库没有下载下来的话,是找不到这个类的

④ 执行后,部分小伙伴可能会报:java.lang.UnsatisfiedLinkError: 找不到指定的模块
然后,我们再看回官网:
利用Tess4J进行验证码识别_第1张图片
看到这,可能大家应该明白了,我们缺了 Visual C++ 2019 Redistributable Packages,点进去下载安装即可。
利用Tess4J进行验证码识别_第2张图片

⑤ 再次执行,结果却是闻者伤心,听者流泪啊
利用Tess4J进行验证码识别_第3张图片
然后,再测几次发现,将语言设为eng是可以读取到容易识别的数字:instance.setLanguage("eng");

⑥ 基于图片识别的识别率不高,所以我们一般先做图片的处理再进行识别。这个时候我们可以用到Tess4J专门提供的ImageHelper。里面分别有如下方法:

getScaledInstance 放大图片
getSubImage 截取图片
convertImageToBinary 转二进制
convertImageToGrayscale 将图像转换为灰度
invertImageColor 反转图像颜色
rotateImage 旋转影像

所以我们这里可以加上这一段

        //图片转图片流
        BufferedImage img = ImageIO.read(file);
        // 这里对图片黑白处理,增强识别率.这里先通过截图,截取图片中需要识别的部分
        img = ImageHelper.convertImageToGrayscale(img);
        // 图片锐化,自己使用中影响识别率的主要因素是针式打印机字迹不连贯,所以锐化反而降低识别率
//        img = ImageHelper.convertImageToBinary(img);
        // 图片放大5倍,增强识别率(很多图片本身无法识别,放大7倍时就可以轻易识,但是考滤到客户电脑配置低,针式打印机打印不连贯的问题,这里就放大7倍)
        img = ImageHelper.getScaledInstance(img, img.getWidth() * 7, img.getHeight() * 7);

最后,通过调整图片处理的方法,成功的识别到了我Demo中的三个验证码。(手动开心)
在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

附github传送门:https://github.com/a81579261/demo

你可能感兴趣的:(Java)