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
image.png
这里下载简体中文(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包:
image.png
将上面tess4j-4.0.0.jar解压:
image.png
进入win32-x86-64目录:
image.png
可以看到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目录:
image.png
可以看到tesserac的so文件。

配置环境变量

如果运行代码,报如下错误:
image.png
表示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代码。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐