Tess4J:基于 Java 的 OCR 解决方案

在现代软件开发中,图像识别与文本提取已成为许多应用场景中的关键环节。OCR(Optical Character Recognition) 技术使得从图像中提取文字成为可能。Tess4J 是一个基于 Java 的 OCR 开发库,它封装了 Google Tesseract OCR 引擎的本地调用接口,使得 Java 开发者能够轻松地在项目中集成图像文字识别功能。

Tess4J 的核心优势在于其对原生 Tesseract 库的封装,不仅简化了 API 调用流程,还支持跨平台使用(Windows、Linux、MacOS 等),是 Java 图像识别领域的重要工具之一。

1. OCR 介绍

OCR(Optical Character Recognition,光学字符识别) 是一种将图像中的文字内容转换为可编辑、可搜索的文本格式的技术。它广泛应用于从扫描文档、照片、PDF 文件等图像中提取文字信息,实现自动化数据处理和分析。其核心是通过图像处理与模式识别算法来检测图像中的字符区域,并将其识别为计算机可理解的文本格式(如 ASCII 或 Unicode)。其主要流程包括:

  1. 图像预处理:去噪、二值化、灰度处理等,提高识别准确性。
  2. 文字区域检测:定位图像中包含文字的区域。
  3. 字符分割:将连在一起的文字或单词拆分为单个字符。
  4. 字符识别:使用机器学习模型或模板匹配技术识别每个字符。
  5. 后处理与输出:优化识别结果并输出为文本格式。

常见的 OCR 工具与服务:

|---------------------------------|-------------------------------|-----------------------------------|----------|----------------------------|
| 工具/服务名称 | 平台/语言支持 | 支持语言 | 是否付费 | 特点说明 |
| Tesseract OCR | 跨平台(C/C++),支持 Java(Tess4J)等封装 | 英文为主,支持几十种语言(需加载对应 tessdata 文件) | 否 | 开源免费,适合本地部署,精度中等 |
| Google Vision API | 云端 REST API | 多语言支持:英文、中文、日文、韩文、法语等(共约 50+ 种语言) | 是 | 高精度识别,支持表格、手写体、复杂排版,需网络连接 |
| 百度 OCR | 云端 API / SDK | 中文、英文、数字、车牌、身份证、护照等特定场景 | 部分免费 | 中文识别强,适合国内应用场景,有免费额度限制 |
| ABBYY FineReader | Windows / macOS | 支持 190+ 种语言 | 是 | 商业软件,识别准确率高,界面友好,价格较高 |
| Microsoft Azure Computer Vision | 云端 API | 英文、中文、西班牙语、法语、德语、日语等主流语言 | 是 | 支持多语言和表格识别,集成于 Azure 生态 |
| Amazon Textract | AWS 云端服务 | 英文、中文、西班牙语等 | 是 | 提取文档中的文本、表格、表单结构,适合企业级文档处理 |
| OpenCV + 深度学习模型 | 自定义开发(Python、Java 等) | 取决于训练模型(可定制化) | 否 | 灵活但开发门槛高,适合有 AI 能力的团队 |
| MyScript | Web / SDK | 英文、中文、日文、阿拉伯语等 | 是 | 手写识别能力强,适合教育、笔记类应用 |
| PaddleOCR(百度飞桨) | Python / C++ / Java | 支持中英文、数字、符号、多种字体 | 否 | 开源项目,轻量级,适合本地部署或自定义训练 |

2. 简单验证码识别(无干扰项)使用步骤

1. 添加依赖

XML 复制代码
<dependency>
  <groupId>net.java.dev.jna</groupId>
  <artifactId>jna</artifactId>
  <version>4.2.1</version>
</dependency>
<dependency>
  <groupId>net.sourceforge.tess4j</groupId>
  <artifactId>tess4j</artifactId>
  <version>4.5.1</version>
</dependency>

2. 下载 Tesseract 数据

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

这里以放在 resources/tessdata 目录为例:

常见语言包列表及用途说明:

参考文档:Traineddata Files for Version 4.00 + | tessdoc

|--------------------------|---------------------------------------|---------------|
| 文件名 | 语言 | 备注 |
| afr.traineddata | 南非语 (Afrikaans) | ------ |
| amh.traineddata | 阿姆哈拉语 (Amharic) | ------ |
| ara.traineddata | 阿拉伯语 (Arabic) | ------ |
| asm.traineddata | 阿萨姆语 (Assamese) | ------ |
| aze.traineddata | 阿塞拜疆语 (Azerbaijani) | ------ |
| aze_cyrl.traineddata | 阿塞拜疆语(西里尔字母) | Cyrillic 字符集 |
| bel.traineddata | 白俄罗斯语 (Belarusian) | ------ |
| ben.traineddata | 孟加拉语 (Bengali) | ------ |
| bod.traineddata | 藏语 (Tibetan) | ------ |
| bos.traineddata | 波斯尼亚语 (Bosnian) | ------ |
| bre.traineddata | 布列塔尼语 (Breton) | ------ |
| bul.traineddata | 保加利亚语 (Bulgarian) | ------ |
| cat.traineddata | 加泰罗尼亚语 (Catalan; Valencian) | ------ |
| ceb.traineddata | 宿务语 (Cebuano) | ------ |
| ces.traineddata | 捷克语 (Czech) | ------ |
| chi_sim.traineddata | 中文简体 (Chinese - Simplified) | 常用字识别 |
| chi_sim_vert.traineddata | 中文简体竖排 | 竖排文字识别 |
| chi_tra.traineddata | 中文繁体 (Chinese - Traditional) | ------ |
| chi_tra_vert.traineddata | 中文繁体竖排 | ------ |
| chr.traineddata | 切罗基语 (Cherokee) | ------ |
| cym.traineddata | 威尔士语 (Welsh) | ------ |
| dan.traineddata | 丹麦语 (Danish) | ------ |
| dan_frak.traineddata | 丹麦语(Fraktur 字体) | 古德语字体风格 |
| deu.traineddata | 德语 (German) | ------ |
| deu_frak.traineddata | 德语(Fraktur 字体) | ------ |
| div.traineddata | 迪维希语 (Dhivehi) | ------ |
| dzo.traineddata | 不丹语 (Dzongkha) | ------ |
| ell.traineddata | 希腊语 (Greek, Modern) | ------ |
| eng.traineddata | 英语 (English) | 推荐使用 |
| enm.traineddata | 中古英语 (Middle English) | 古英语识别 |
| epo.traineddata | 世界语 (Esperanto) | ------ |
| est.traineddata | 爱沙尼亚语 (Estonian) | ------ |
| eus.traineddata | 巴斯克语 (Basque) | ------ |
| fas.traineddata | 波斯语 (Persian) | ------ |
| fao.traineddata | 法罗语 (Faroese) | ------ |
| fra.traineddata | 法语 (French) | ------ |
| frm.traineddata | 中古法语 (Middle French) | ------ |
| fry.traineddata | 弗里斯兰语 (Western Frisian) | ------ |
| gla.traineddata | 苏格兰盖尔语 (Scottish Gaelic) | ------ |
| gle.traineddata | 爱尔兰语 (Irish) | ------ |
| glg.traineddata | 加利西亚语 (Galician) | ------ |
| grc.traineddata | 古希腊语 (Ancient Greek) | ------ |
| guj.traineddata | 古吉拉特语 (Gujarati) | ------ |
| hat.traineddata | 海地克里奥尔语 (Haitian; Haitian Creole) | ------ |
| heb.traineddata | 希伯来语 (Hebrew) | ------ |
| hin.traineddata | 印地语 (Hindi) | ------ |
| hrv.traineddata | 克罗地亚语 (Croatian) | ------ |
| hun.traineddata | 匈牙利语 (Hungarian) | ------ |
| hye.traineddata | 亚美尼亚语 (Armenian) | ------ |
| iku.traineddata | 因纽特语 (Inuktitut) | ------ |
| ind.traineddata | 印度尼西亚语 (Indonesian) | ------ |
| isl.traineddata | 冰岛语 (Icelandic) | ------ |
| ita.traineddata | 意大利语 (Italian) | ------ |
| ita_old.traineddata | 意大利语(旧字体) | ------ |
| jav.traineddata | 爪哇语 (Javanese) | ------ |
| jpn.traineddata | 日语 (Japanese) | 含平假名、片假名和常用汉字 |
| jpn_vert.traineddata | 日语竖排 | ------ |
| kan.traineddata | 卡纳达语 (Kannada) | ------ |
| kas.traineddata | 克什米尔语 (Kashmiri) | ------ |
| kat.traineddata | 格鲁吉亚语 (Georgian) | ------ |
| kat_old.traineddata | 格鲁吉亚语(旧字体) | ------ |
| kaz.traineddata | 哈萨克语 (Kazakh) | ------ |
| khm.traineddata | 高棉语 (Central Khmer) | ------ |
| kir.traineddata | 吉尔吉斯语 (Kyrgyz) | ------ |
| kmr.traineddata | 库尔德语北部方言 (Northern Kurdish) | ------ |
| kor.traineddata | 韩语 (Korean) | ------ |
| kor_vert.traineddata | 韩语竖排 | ------ |
| lao.traineddata | 老挝语 (Lao) | ------ |
| lat.traineddata | 拉丁语 (Latin) | ------ |
| lav.traineddata | 拉脱维亚语 (Latvian) | ------ |
| lit.traineddata | 立陶宛语 (Lithuanian) | ------ |
| ltz.traineddata | 卢森堡语 (Luxembourgish) | ------ |
| mal.traineddata | 马拉雅拉姆语 (Malayalam) | ------ |
| mar.traineddata | 马拉地语 (Marathi) | ------ |
| mkd.traineddata | 马其顿语 (Macedonian) | ------ |
| mlt.traineddata | 马耳他语 (Maltese) | ------ |
| mon.traineddata | 蒙古语 (Mongolian) | ------ |
| mri.traineddata | 毛利语 (Maori) | ------ |
| msa.traineddata | 马来语 (Malay) | ------ |
| mya.traineddata | 缅甸语 (Burmese) | ------ |
| nep.traineddata | 尼泊尔语 (Nepali) | ------ |
| nld.traineddata | 荷兰语 (Dutch; Flemish) | ------ |
| nor.traineddata | 挪威语 (Norwegian) | ------ |
| oci.traineddata | 奥克西坦语 (Occitan) | ------ |
| ori.traineddata | 奥里亚语 (Oriya) | ------ |
| osd.traineddata | 方向与段落检测 | ------ |
| pan.traineddata | 旁遮普语 (Eastern Punjabi) | ------ |
| pap.traineddata | 帕皮阿门托语 (Papiamento) | ------ |
| pol.traineddata | 波兰语 (Polish) | ------ |
| por.traineddata | 葡萄牙语 (Portuguese) | ------ |
| pus.traineddata | 普什图语 (Pashto) | ------ |
| que.traineddata | 克丘亚语 (Quechua) | ------ |
| ron.traineddata | 罗马尼亚语 (Romanian; Moldavian; Moldovan) | ------ |
| rus.traineddata | 俄语 (Russian) | ------ |
| san.traineddata | 梵语 (Sanskrit) | ------ |
| sin.traineddata | 僧伽罗语 (Sinhala) | ------ |
| slk.traineddata | 斯洛伐克语 (Slovak) | ------ |
| slv.traineddata | 斯洛文尼亚语 (Slovenian) | ------ |
| snd.traineddata | 信德语 (Sindhi) | ------ |
| spa.traineddata | 西班牙语 (Spanish; Castilian) | ------ |
| spa_old.traineddata | 西班牙语(旧字体) | ------ |
| sqi.traineddata | 阿尔巴尼亚语 (Albanian) | ------ |
| srp.traineddata | 塞尔维亚语 (Serbian) | ------ |
| srp_latn.traineddata | 塞尔维亚语(拉丁字母) | ------ |
| sun.traineddata | 巽他语 (Sundanese) | ------ |
| swa.traineddata | 斯瓦希里语 (Swahili) | ------ |
| swe.traineddata | 瑞典语 (Swedish) | ------ |
| syr.traineddata | 叙利亚语 (Syriac) | ------ |
| tam.traineddata | 泰米尔语 (Tamil) | ------ |
| tat.traineddata | 鞑靼语 (Tatar) | ------ |
| tel.traineddata | 泰卢固语 (Telugu) | ------ |
| tgk.traineddata | 塔吉克语 (Tajik) | ------ |
| tgl.traineddata | 他加禄语 (Tagalog) | ------ |
| tha.traineddata | 泰语 (Thai) | ------ |
| tir.traineddata | 提格利尼亚语 (Tigrinya) | ------ |
| ton.traineddata | 汤加语 (Tonga) | ------ |
| tur.traineddata | 土耳其语 (Turkish) | ------ |
| uig.traineddata | 维吾尔语 (Uighur; Uyghur) | ------ |
| ukr.traineddata | 乌克兰语 (Ukrainian) | ------ |
| urd.traineddata | 乌尔都语 (Urdu) | ------ |
| uzb.traineddata | 乌兹别克语 (Uzbek) | ------ |
| uzb_cyrl.traineddata | 乌兹别克语(西里尔字母) | ------ |
| vie.traineddata | 越南语 (Vietnamese) | ------ |
| yid.traineddata | 意第绪语 (Yiddish) | ------ |
| yor.traineddata | 约鲁巴语 (Yoruba) | ------ |

3. 编写识别代码

java 复制代码
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;

import java.io.File;

public static void main(String[] args) {
    String dataPath = "src/main/resources/tessdata";
    String imagePath = "src/main/resources/image/img.png";
    try {
        // 获取本地图片
        File file = new File(imagePath);
        // 创建Tesseract对象
        ITesseract tesseract = new Tesseract();
        // 设置字体库路径
        tesseract.setDatapath(dataPath);
        // 设置识别语言
        tesseract.setLanguage("eng");
        // 执行ocr识别
        String result = tesseract.doOCR(file);
        System.out.println("识别的结果为:" + result);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

3. 复杂验证码识别(带干扰项)使用步骤

1. 加入maven依赖

java 复制代码
<dependency>
    <groupId>org.openpnp</groupId>
    <artifactId>opencv</artifactId>
    <version>4.9.0-0</version>
</dependency>

2. 选择和 maven 依赖相同版本的 opencv下载

下载地址:https://sourceforge.net/projects/opencvlibrary/files/

以该示例为例,Windows 版本下载如下图所示:

选择下载位置后点击安装即可。

选择版本说明:

  1. 点击 Core.NATIVE_LIBRARY_NAME 常量:
  1. 点击 getNativeLibraryName() 方法:

这个就是要找的 dll 文件,即 opencv 的版本。这个常量根据 opencv 版本的不同,常量也随之变化。

3. 带干扰项验证码处理(灰度化、二值化等操作)

java 复制代码
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.io.File;
import java.io.IOException;

public class CaptchaPreprocessor {
    static {
        //在使用OpenCV前必须加载Core.NATIVE_LIBRARY_NAME类,否则会报错
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    public static void main(String[] args) throws IOException {
        String imagePath = "src/main/resources/img.png";
        String outputImagePath = "src/main/resources/img/img.png";
        String tessDataPath = "src/main/resources/tessdata";

        try {
            // 1. 使用 OpenCV 预处理图像
            Mat src = Imgcodecs.imread(imagePath, Imgcodecs.IMREAD_COLOR);
            if (src.empty()) {
                System.err.println("无法加载图像,请检查路径是否正确:" + imagePath);
                return;
            }
            Mat processed = new Mat();

            // 灰度化
            Mat gray = new Mat();
            Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);

            // 对比度增强(CLAHE)
            Mat clahe = new Mat();
            Imgproc.createCLAHE(2.0, new org.opencv.core.Size(8, 8)).apply(gray, clahe);

            // 自适应二值化
            Mat binary = new Mat();
            Imgproc.adaptiveThreshold(clahe, binary, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,
                    Imgproc.THRESH_BINARY, 11, 2);

            // 形态学操作去干扰线
            Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new org.opencv.core.Size(1, 3));
            Imgproc.morphologyEx(binary, processed, Imgproc.MORPH_OPEN, kernel);

            // 保存处理后的图像
            File destF = new File(outputImagePath).getParentFile();
            if (!destF.exists()) {
                destF.mkdirs();
            }
            boolean success = Imgcodecs.imwrite(outputImagePath, processed);
            if (!success) {
                System.err.println("图像保存失败,请检查路径或 Mat 是否为空");
            }

            // 2. 使用 Tess4J 进行 OCR 识别
            ITesseract tesseract = new Tesseract();
            tesseract.setDatapath(tessDataPath); // 设置 tessdata 路径
            tesseract.setLanguage("eng");         // 英文识别
            tesseract.setPageSegMode(7);          // 单行文本识别

            File imageFile = new File(imagePath);
            String result = tesseract.doOCR(imageFile);

            // 输出识别结果
            System.out.println("识别结果: " + result.trim());

        } catch (Exception e) {
            System.err.println("识别失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

4. 配置 VM options,添加 -Djava.library.path=安装位置\opencv\build\java\x64。(如果 java -jar 启动的话,可以直接添加 -Djava.library.path=安装位置\opencv\build\java\x64 或 --java.library.path=安装位置\opencv\build\java\x64)

以配置 VM options 为例,具体操作流程如下图所示:

关于配置 java.library.path 说明:

  1. 在未配置 -Djava.library.path 之前启动项目会报如下错误:
  1. 点击 ClassLoader.java:1863

从该图可以看出,他读取 java.library.path 和 sun.boot.library.path 这两个路径。所以说 -Djava.library.path 可以替换为 -Dsun.boot.library.path。

4. 执行测试

以下面这个图片为例:

原图片经过去噪、二值化等操作处理后:

识别结果为:

相关推荐
家庭云计算专家15 小时前
ONLYOFFICE 的AI技巧-1.集成OCR、文本转图像、电子表格集成等新功能
人工智能·ocr·onlyoffice·协作空间
扫地的小何尚1 天前
全新NVIDIA Llama Nemotron Nano视觉语言模型在OCR基准测试中准确率夺冠
c++·人工智能·语言模型·机器人·ocr·llama·gpu
Secede.1 天前
TrOCR模型微调
python·深度学习·ocr
Listennnn4 天前
OCR & MLLM & Evaluation
人工智能·ocr
野生技术架构师4 天前
SpringBoot集成Tess4j :低成本解锁OCR 图片识别能力
spring boot·后端·ocr
天天代码码天天5 天前
PP-OCRv5 ubuntu20.04 OCR识别服务
ocr·pp-ocrv5·ubuntu20.04 ocr
沉到海底去吧Go6 天前
【PDF识别改名】PDF指定区域OCR识别重命名工具使用教程和注意事项
python·pdf·ocr
沉到海底去吧Go6 天前
【图片自动识别改名】识别图片中的文字并批量改名的工具,根据文字对图片批量改名,基于QT和腾讯OCR识别的实现方案
数据库·qt·ocr·图片识别自动改名·图片区域识别改名·pdf识别改名
开开心心就好7 天前
高效Excel合并拆分软件
开发语言·javascript·c#·ocr·排序算法·excel·最小二乘法