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

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.tess4jgroupId>
    <artifactId>tess4jartifactId>
    <version>5.6.0version>
dependency>

<dependency>
    <groupId>cn.hutoolgroupId>
    <artifactId>hutool-allartifactId>
    <version>5.8.15version>
dependency>

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

traineddata文件下载

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

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

语言 文件
简体中文 chi_sim.traineddata
English eng.traineddata

识别英文

代码

package com.beiyoufamily;

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

import java.io.File;

/**
 * @author Yi Dai [email protected]
 * @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);
    }

}

运行结果:JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第1张图片

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

识别中文

代码

package com.beiyoufamily;

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

import java.io.File;

/**
 * @author Yi Dai [email protected]
 * @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);
    }

}

运行结果
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第2张图片

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

JAVA用tess4j识别验证码

常见验证码的类型

  • 数字类型
    JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第3张图片

  • 滑块验证码
    JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第4张图片

  • 计算题
    请添加图片描述

识别

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

代码

package com.beiyoufamily;

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

import java.io.File;

/**
 * @author Yi Dai [email protected]
 * @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);
    }


}

运行结果
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第5张图片
很尴尬,除了两个数字被正确识别之外,符号一个没识别出来,换成中文识别率更低,有兴趣的小伙伴可以试试其他语言。很显然这不是我们想要的效果,所以引出今天的重点——自定义字库

自定义字库,提高识别率

下载jTessBoxEditor

官网下载:https://udomain.dl.sourceforge.net/project/vietocr/jTessBoxEditor/jTessBoxEditor-2.4.1.zip

解压

JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第6张图片

添加环境变量

JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第7张图片
操作步骤:右键此电脑-属性-高级系统设置-环境变量-Path-添加-输入JTessBoxEditor的tesseract-ocr目录

运行

双击jTessBoxEditor.jar运行
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第8张图片
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第9张图片

准备素材

素材当然是越多越好,这样训练出来之后识别率会更高
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第10张图片

合并PNG为tif文件

依次点击Tools - Merge TIFF...
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第11张图片
文件类型选为png(根据实际类型选择),不然看不到你的文件,全选素材,然后点击打开
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第12张图片

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

JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第13张图片
tif文件命名格式需规范,格式为[lang].[fontname].exp[num].tif,lang为语言名称,fontname为字体名称,num为序号。例如上图所示的:verification-code.calculation-question.exp0.tif(扩展名可以自动加,只要文件类型选对的)

JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第14张图片
点击确定,即可合并完成

生成box文件

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

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

执行结果:
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第15张图片

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

依次点击Box Editor - Open 然后选择刚才生成的tif文件,选择之后他会自动关联上对应的box文件
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第16张图片
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第17张图片

校正

JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第18张图片
示例:
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第19张图片
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第20张图片
以此类推,把后面的字符和位置全部校正,这个过程有点枯燥

生成tr文件

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

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

执行结果:
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第21张图片

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

同样的目录中执行命令:

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

执行结果:
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第22张图片

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

执行命令:

echo calculation-question 0 0 0 0 0 > font_properties

执行结果:
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第23张图片

生成shape文件

执行命令:

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

执行结果:
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第24张图片

生成聚字符特征文件

执行命令:

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

执行结果:
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第25张图片

生成字符正常化特征文件

执行命令:

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

执行结果:
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第26张图片

把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

执行结果:
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第27张图片

合并训练文件成成traineddata文件

执行命令:

combine_tessdata verification-code

执行结果:
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第28张图片
自此,训练完成!

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

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

package com.beiyoufamily;

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

import java.io.File;

/**
 * @author Yi Dai [email protected]
 * @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);
    }


}

运行结果:
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第29张图片
非常完美,精确的识别出了表达式!

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

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 [email protected]
 * @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));
                }
            }
        }
    }
}

计算结果:
JAVA用tess4j识别复杂的验证码,自定义字库,计算题验证码,jTessBoxEditor,tess4j,验证码识别_第30张图片

其他注意事项

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

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

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

你可能感兴趣的:(java,tess4j,jTessBoxEditor,验证码识别,计算题验证码识别)