JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别

419 阅读6分钟

JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码

  • 场景
    
  • JAVA用tess4j识别文本 MAVEN依赖 traineddata文件下载 识别英文 识别中文
  • JAVA用tess4j识别验证码 常见验证码的类型 识别
  • 自定义字库,提高识别率 下载jTessBoxEditor 解压 添加环境变量 运行 准备素材 合并PNG为tif文件 生成box文件 使用jTessBoxEditor工具对tif文件进行校准 校正 生成tr文件 生成生成字符集文件unicharset文件 生成font_properties文件(不需要扩展名,切记;calculation-question为font) 生成shape文件 生成聚字符特征文件 生成字符正常化特征文件 把inttemp、pffmtable、shapetable、normproto四个文件命名为[lang].xxx 合并训练文件成成traineddata文件
  • 使用自定义的字库进行识别 用脚本引擎识别计算出结果
  • 其他注意事项 场景 在爬虫爬取数据的过程中可能会遇到各种验证码,导致爬虫无法继续。本文讲解如果在java中如何使用tess4j识别图片中的文本、自定义模型。

JAVA用tess4j识别文本 MAVEN依赖

<dependency>
    <groupId>net.sourceforge.tess4j</groupId>
    <artifactId>tess4j</artifactId>
    <version>5.6.0</version>
</dependency>

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.15</version>
</dependency>

等下需要用到脚本引擎计算表达式

traineddata文件下载 github下载地址:github.com/tesseract-o…

常用的语言及其traineddata文件对照表

语言文件
简体中文chi_sim.traineddata
Englisheng.traineddata

识别英文 代码

package com.beiyoufamily;

import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;

import java.io.File;

/**
 * @author Yi Dai 484201132@qq.com
 * @since 2023/6/3 15:25
 */

public class EnglishIdentification {

    public static void main(String[] args) throws TesseractException {
        //要是别的验证码图片
        File captchaImageFile = new File("C:/Files/images/captcha/test/English.png");
        //创建tesseract对象
        Tesseract tesseract = new Tesseract();
        //设置traineddata文件目录
        tesseract.setDatapath("C:/Files/images/captcha/traineddata");
        //设置语言(不需要写扩展名)
        tesseract.setLanguage("eng");
        String result = tesseract.doOCR(captchaImageFile);
        System.out.println(result);
    }

}

运行结果:

image.png

标准的英文字符识别率非常高

识别中文

代码

package com.beiyoufamily;

import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;

import java.io.File;

/**
 * @author Yi Dai 484201132@qq.com
 * @since 2023/6/3 15:25
 */

public class ChineseIdentification {

    public static void main(String[] args) throws TesseractException {
        //要是别的验证码图片
        File captchaImageFile = new File("C:/Files/images/captcha/test/Chinese.png");
        //创建tesseract对象
        Tesseract tesseract = new Tesseract();
        //设置traineddata文件目录
        tesseract.setDatapath("C:/Files/images/captcha/traineddata");
        //设置语言(不需要写扩展名)
        tesseract.setLanguage("chi_sim");
        String result = tesseract.doOCR(captchaImageFile);
        System.out.println(result);
    }

}

运行结果

无图

看了一下识别结果,不能说不太准确,只能说是非常糟糕。总所周知tess4j除了对中文不太友好以外,其他语言都挺准确的。

JAVA用tess4j识别验证码

常见验证码的类型

  • 数字类型

image.png

  • 滑块验证码

image.png

  • 计算题

image.png

识别

上述验证码中,第一种数字类型的比较简单,只需要对图像做二值化之后进行识别,准确率还是很高的,第二种滑块的验证码比较恶心,今天暂时不讨论它;今天讨论的是第三种,计算题验证码(方法同样适用于第一种验证码)。

代码

package com.beiyoufamily;

import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;

import java.io.File;

/**
 * @author Yi Dai 484201132@qq.com
 * @since 2023/6/3 15:09
 */

public class CaptchaIdentification {

    public static void main(String[] args) throws TesseractException {
        //要是别的验证码图片
        File captchaImageFile = new File("C:/Files/images/captcha/test/captcha.png");
        //创建tesseract对象
        Tesseract tesseract = new Tesseract();
        //设置traineddata文件目录
        tesseract.setDatapath("C:/Files/images/captcha/traineddata");
        //设置语言(不需要写扩展名)
        tesseract.setLanguage("eng");
        String result = tesseract.doOCR(captchaImageFile);
        System.out.println(result);
    }


}

运行结果

很尴尬,除了两个数字被正确识别之外,符号一个没识别出来,换成中文识别率更低,有兴趣的小伙伴可以试试其他语言。很显然这不是我们想要的效果,所以引出今天的重点——自定义字库

自定义字库,提高识别率

下载jTessBoxEditor 官网下载:udomain.dl.sourceforge.net/project/vie…

解压

image.png

添加环境变量

image.png

操作步骤:右键此电脑-属性-高级系统设置-环境变量-Path-添加-输入JTessBoxEditor的tesseract-ocr目录

运行

双击jTessBoxEditor.jar运行

image.png

image.png

准备素材

素材当然是越多越好,这样训练出来之后识别率会更高

image.png

合并PNG为tif文件 依次点击Tools - Merge TIFF...

image.png

文件类型选为png(根据实际类型选择),不然看不到你的文件,全选素材,然后点击打开

image.png

注意!!! 这一步的文件名是有讲究的,不能随意命名!

image.png

tif文件命名格式需规范,格式为[lang].[fontname].exp[num].tif,lang为语言名称,fontname为字体名称,num为序号。例如上图所示的:verification-code.calculation-question.exp0.tif(扩展名可以自动加,只要文件类型选对的)

image.png

点击确定,即可合并完成

生成box文件

在刚才tif文件生成的目录执行命令:

tesseract verification-code.calculation-question.exp0.tif verification-code.calculation-question.exp0 batch.nochop makebox

执行结果:

image.png

使用jTessBoxEditor工具对tif文件进行校准

依次点击Box Editor - Open 然后选择刚才生成的tif文件,选择之后他会自动关联上对应的box文件

image.png

image.png

校正

image.png

示例:

image.png

image.png

以此类推,把后面的字符和位置全部校正,这个过程有点枯燥

生成tr文件

在刚刚的tif文件所在目录执行命令:

tesseract verification-code.calculation-question.exp0.tif verification-code.calculation-question.exp0 nobatch box.train

执行结果:

image.png

生成生成字符集文件unicharset文件

同样的目录中执行命令:

unicharset_extractor verification-code.calculation-question.exp0.box

执行结果:

image.png

生成font_properties文件(不需要扩展名,切记;calculation-question为font)

执行命令:

echo calculation-question 0 0 0 0 0 > font_properties

执行结果:

image.png

生成shape文件

执行命令:

shapeclustering -F font_properties -U unicharset -O verification-code.unicharset verification-code.calculation-question.exp0.tr

执行结果:

image.png

生成聚字符特征文件

执行命令:

mftraining -F font_properties -U unicharset -O unicharset verification-code.calculation-question.exp0.tr

执行结果:

image.png

生成字符正常化特征文件

执行命令:

cntraining verification-code.calculation-question.exp0.tr

执行结果:

image.png

把inttemp、pffmtable、shapetable、normproto四个文件命名为[lang].xxx

分别执行下面四个重命名命令:

rename normproto verification-code.normproto

rename inttemp verification-code.inttemp

rename pffmtable verification-code.pffmtable

rename shapetable verification-code.shapetable

执行结果:

image.png

合并训练文件成成traineddata文件

执行命令:

combine_tessdata verification-code

执行结果:

image.png

自此,训练完成!

使用自定义的字库进行识别

代码:(verification-code为刚才训练所得的)

package com.beiyoufamily;

import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;

import java.io.File;

/**
 * @author Yi Dai 484201132@qq.com
 * @since 2023/6/3 15:09
 */

public class CaptchaIdentification {

    public static void main(String[] args) throws TesseractException {
        //要是别的验证码图片
        File captchaImageFile = new File("C:/Files/images/captcha/test/captcha.png");
        //创建tesseract对象
        Tesseract tesseract = new Tesseract();
        //设置traineddata文件目录
        tesseract.setDatapath("C:/Files/images/captcha/traineddata");
        //设置语言(不需要写扩展名)
        tesseract.setLanguage("verification-code");
        String result = tesseract.doOCR(captchaImageFile);
        System.out.println(result);
    }


}

运行结果:

image.png

非常完美,精确的识别出了表达式!

用脚本引擎识别计算出结果

package com.beiyoufamily;

import cn.hutool.script.ScriptUtil;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;

import java.io.File;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Yi Dai 484201132@qq.com
 * @since 2023/6/3 15:09
 */

public class CaptchaIdentification {

    public static void main(String[] args) throws TesseractException {
        //要是别的验证码图片
        File captchaImageFile = new File("C:/Files/images/captcha/test/captcha.png");
        //创建tesseract对象
        Tesseract tesseract = new Tesseract();
        //设置traineddata文件目录
        tesseract.setDatapath("C:/Files/images/captcha/traineddata");
        //设置语言(不需要写扩展名)
        tesseract.setLanguage("verification-code");
        String result = tesseract.doOCR(captchaImageFile);

        if (Objects.nonNull(result)) {
            //去除所有的空白字符
            result = result.replaceAll("\\s*", "").trim();

            String pattern = "\\d+[+\\-*/]\\d+=\\?";
            
            //判断识别出来的表达式是否合法
            if (Pattern.matches(pattern, result)) {
                //提取表达式
                Matcher matcher = Pattern.compile("\\d+[+\\-*/]\\d+").matcher(result);
                if (matcher.find()) {
                    String expression = matcher.group();
                    System.out.println(expression);
                    System.out.println(ScriptUtil.eval(expression));
                }
            }
        }
    }
}

计算结果:

image.png

其他注意事项

本演示示例是在Java8环境中运行的,高版本的Java环境可能会没有脚本引擎,会报错。

训练的过程中由于命令众多,参数复杂,博主封装了一个小工具,可以直接运行,省去输入命令,下载地址: download.csdn.net/download/da…

下载之后直接点击run.bat运行即可,根据提示操作。

———————————————— 版权声明:本文为CSDN博主「june-YiDai」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/daiyi666/ar…