1.Tess4j& Tesseract OCR简介
Tess4J 是一个基于 Tesseract OCR 引擎的 Java 接口,可以用来识别图像中的文本。Tesseract 是一个由 Google 开发的开源 OCR 引擎,可以识别多种语言的文本。Tess4J 将 Tesseract 引擎的优势和简单性与 Java 的可移植性和易用性相结合,是一个非常强大的 OCR 解决方案。
Tess4J 提供了丰富的 API,可以很方便地进行图像处理和文本识别。它支持多种格式的图像文件,包括 BMP、PNG、JPEG、GIF 和 TIFF 等格式。Tess4J 还可以进行图像预处理,例如裁剪、缩放和二值化等,以提高文本识别的准确性。
Tess4j官网:https://tess4j.sourceforge.net/usage.html
Tesseract OCR代码库:https://github.com/tesseract-ocr/
2.Tess4j的简单案例
引入依赖
首先引入maven依赖:
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>4.0.0</version>
</dependency>
代码案例
下面是一段简单的代码案例:
// 新建工具对象
ITesseract iTesseract = new Tesseract();
// 设置语言 这里设置简体中文
iTesseract.setLanguage("chi_sim");
// 设置训练数据路径
iTesseract.setDatapath("D:\\tessdata");
// 提取图片中的文字
String result = iTesseract.doOCR(new File("D:\\test.png"));
上面设置了语言是简体中文,需要去tesseract-ocr语言库中下载预训练数据。
下载语言库
语言库下载地址:https://github.com/tesseract-ocr/tessdata
这里下载简体中文(chi_sim.traineddata)预训练数据。
3.Windows上运行ITesseract类
经过上面步骤后,可以在Windows上直接运行代码案例,因为Tess4J在Windows上是开箱即用的。下面看一下原因。
代码调用链分析
首先,看一下OCR识别的核心代码调用链路:
String result = iTesseract.doOCR(new File("D:\\test.png"));
下面是Tesseractl类的方法:
public String doOCR(File imageFile) throws TesseractException {
return doOCR(imageFile, null);
}
public String doOCR(File imageFile, Rectangle rect) throws TesseractException {
try {
return doOCR(ImageIOHelper.getIIOImageList(imageFile), imageFile.getPath(), rect);
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new TesseractException(e);
}
}
下面doOCR方法里面通过init方法初始化TessAPI对象:
public String doOCR(List<IIOImage> imageList, String filename, Rectangle rect) throws TesseractException {
init();
setTessVariables();
......
}
TessAPI对象初始化:
protected void init() {
api = TessAPI.INSTANCE;
handle = api.TessBaseAPICreate();
StringArray sarray = new StringArray(configList.toArray(new String[0]));
PointerByReference configs = new PointerByReference();
configs.setPointer(sarray);
api.TessBaseAPIInit1(handle, datapath, language, ocrEngineMode, configs, configList.size());
if (psm > -1) {
api.TessBaseAPISetPageSegMode(handle, psm);
}
}
通过Native方法通过库名称从本地依赖库中加载TessAPI对象:
public static final TessAPI INSTANCE = LoadLibs.getTessAPIInstance();
public static TessAPI getTessAPIInstance() {
return (TessAPI) Native.loadLibrary(getTesseractLibName(), TessAPI.class);
}
下面是的getTesseractLibName方法的处理逻辑:
public static final String LIB_NAME = "libtesseract400";
public static final String LIB_NAME_NON_WIN = "tesseract";
public static String getTesseractLibName() {
return Platform.isWindows() ? LIB_NAME : LIB_NAME_NON_WIN;
}
上面的代码表明,Windows系统通过libtesseract400这个name从本地依赖库获取TessAPI对象,其它系统通过tesseract这个name来获取TessAPI对象。
下面是Native类中的方法:
public static Object loadLibrary(String name, Class interfaceClass) {
return loadLibrary(name, interfaceClass, Collections.EMPTY_MAP);
}
public static Object loadLibrary(String name,Class interfaceClass,Map options) {
Library.Handler handler =new Library.Handler(name, interfaceClass, options);
ClassLoader loader = interfaceClass.getClassLoader();
Library proxy = (Library)Proxy.newProxyInstance(loader, new Class[] {interfaceClass}, handler);
cacheOptions(interfaceClass, options, proxy);
return proxy;
}
上面代码通过JDK动态代理来生成interfaceClass的对象。
为什么Windows能开箱即用
通过上面的代码调用链分析,可以知道代码运行需要调用path路径中名称为libtesseract400的本地库,上面我们引入了下面的依赖:
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>4.0.0</version>
</dependency>
打开本地maven仓库(我的是D:\m2\repository),找到tess4j的jar包:
将上面tess4j-4.0.0.jar解压:
进入win32-x86-64目录:
可以看到tess4j-4.0.0.jar中已经包含了Windows系统需要的dll库,所以可以在Windows系统开箱即用。
4.linux上运行ITesseract类
安装tesserac
在linux系统上运行Tess4j的代码,首先需要安装leptonica和tesserac,具体安装过程参考:
https://blog.csdn.net/weixin_47914635/article/details/128715110《linux安装tesseract支持tess4j图片识别》
安装目录为:/usr/local,进入tesserac的lib目录:
可以看到tesserac的so文件。
配置环境变量
如果运行代码,报如下错误:
表示path中找不到tesserac的so文件。从上面的代码调用链分析中可以知道,是下面这段代码出了问题:
protected void init() {
api = TessAPI.INSTANCE;
handle = api.TessBaseAPICreate();
StringArray sarray = new StringArray(configList.toArray(new String[0]));
PointerByReference configs = new PointerByReference();
configs.setPointer(sarray);
api.TessBaseAPIInit1(handle, datapath, language, ocrEngineMode, configs, configList.size());
if (psm > -1) {
api.TessBaseAPISetPageSegMode(handle, psm);
}
}
即系统无法初始化TessAPI对象,TessAPI对象是通过下面的代码完成的:
public static final String LIB_NAME = "libtesseract400";
public static final String LIB_NAME_NON_WIN = "tesseract";
public static final TessAPI INSTANCE = LoadLibs.getTessAPIInstance();
public static TessAPI getTessAPIInstance() {
return (TessAPI) Native.loadLibrary(getTesseractLibName(), TessAPI.class);
}
public static String getTesseractLibName() {
return Platform.isWindows() ? LIB_NAME : LIB_NAME_NON_WIN;
}
也就是说,需要从path路径中加载tesseract的so文件,需要将tesseract的so文件路径添加到path中。
修改环境变量(vim /etc/profile):
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/leptonica/lib:/usr/local/tesseract/lib
export LD_LIBRARY_PATH
LIBRARY_PATH=$LIBRARY_PATH:/usr/local/leptonica/lib:/usr/local/tesseract/lib
export LIBRARY_PATH
LIBLEPT_HEADERSDIR=/usr/local/leptonica/include/leptonica
export LIBLEPT_HEADERSDIR
PATH=$PATH:/usr/local/tesseract/bin
export PATH
export TESSDATA_PREFIX=/usr/local/tesseract/share/tessdata
export PATH=$PATH:$TESSDATA_PREFIX
让环境变量生效:
source /etc/profile
然后重新运行Tess4j代码。