在现代软件开发中,图像识别与文本提取已成为许多应用场景中的关键环节。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)。其主要流程包括:
- 图像预处理:去噪、二值化、灰度处理等,提高识别准确性。
- 文字区域检测:定位图像中包含文字的区域。
- 字符分割:将连在一起的文字或单词拆分为单个字符。
- 字符识别:使用机器学习模型或模板匹配技术识别每个字符。
- 后处理与输出:优化识别结果并输出为文本格式。
常见的 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. 添加依赖
<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. 编写识别代码
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依赖
<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 常量:
2. 点击 getNativeLibraryName() 方法:
这个就是要找的 dll 文件,即 opencv 的版本。这个常量根据 opencv 版本的不同,常量也随之变化。
3. 带干扰项验证码处理(灰度化、二值化等操作)
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 之前启动项目会报如下错误:
2. 点击 ClassLoader.java:1863
从该图可以看出,他读取 java.library.path 和 sun.boot.library.path 这两个路径。所以说 -Djava.library.path 可以替换为 -Dsun.boot.library.path。
4. 执行测试
以下面这个图片为例:
原图片经过去噪、二值化等操作处理后:
识别结果为: