Tess4J学习

因为学院里的项目要求我们做一些OCR的工作,分工的时候分到了做文字识别这方面的活,于是就学习了一些tesseract、tess-two以及最主要的tess4J方面的东西。不得不说这个库对于中文真的是不怎么友好。。

Tess4J的导入

为了使用Tess4J,我们首先要去下载Tesseract。因为Tess4J实质上是对Tesseract在java中通过jni本地库之类的进行的封装。

  1. 下载Tesseract

    • Mac上可以直接通过

      1
      brew install tesseract

      就可以安装;

    • Windows上可以通过一个非官方的安装包安装下载链接
  2. Windows下需要配置环境变量;
  3. 下载Tess4J库Github地址
  4. 在IDE中配置好Library以及Modules。

Tess4J的使用

由于项目的识别要求比较低(大部分锅都交过了切图的大佬),所以也只是使用一小部分方法。大致就总结下列一些东西。

Tesseract的基本知识

  1. Tesseract的字典:在Tesseract的根目录下我们可以看到一个tessdata文件,里面有很多.traineddata文件,这些就是Tesseract的字典,这些文件是它识别各类文字的关键数据。同时也有一些常用词、生偏词的文件(感觉和中文没有什么关系。。),它们共同作用就可以进行识别。若想要识别其他语言,可以从github上面下载谷歌已经训练好的文件。下载链接
  2. 一些基本配置:在tessdata文件中我们也能看见一个config文件夹,打开里面可以看见几个文件。点开之后可以添加各种配置,比如说可以添加黑白名单(我也只用了白名单黑名单。。)。详情参见文档。
  3. 直接在命令行里面使用tesseract:
1
tesseract image.png image.txt -psm 6

原图:

原图

效果图

识别文件

TessAPI类

这个类我估计是一个单例模式,因为只提供了

1
TessAPI api = TessAPI.INSTANCE;

这个东西来创建一个实例。在我看来这个类即是一个Manager,它管理着几乎所有的方法的调用。

几个常用的方法:

TessBaseAPICreate

1
ITessAPI.TessBaseAPI handler = api.TessBaseAPICreate();

这个方法将会创建一个TessBaseAPI类的实例,这个实例就是真正在处理各个任务的类。

TessBaseAPIInit3

1
api.TessBaseAPIInit3(TessBaseAPI handler, String dataPath, String language);

该方法将会进行OCR的初始化。dataPath指的是存放了tessData(存放了所有字典的文件夹)这个文件夹的目录,可以是绝对或者相对地址。language就是所需要识别的语言,其必须与tessData中的字典文件前缀名相符。例如chi_sim.traineddata,前缀就是chi_sim。

TessBaseAPISetPageSegMode

1
api.TessBaseAPISetPageSegMode(TessBaseAPI handler, ITessAPI.TessPageSegMode.*);

对分析页面的分页模式,这也是提高识别率的最关键的一个方法。后面的Mode一共有11种,下面只选取我认为比较有用的几个:

  1. PSM_SINGLE_BLOCK

    Assume a single uniform block of text.

    这段英文真的看的不是很懂,字面意思似乎在说是一块文字。我认为可能是针对拉丁语系的文字中,一段一段之间要分开的那种形式。不过该模式识别率比较高。

  1. PSM_SINGLE_CHAR

    Treat the image as a single character.

    将整张图片都视为一个字母(单字)来识别。这是识别率最高的一种方法,同时也是我们做这次项目的时候采用的方法,如果文字不是很清晰的话,可以考虑使用这种模式。

  2. PSM_SINGLE_LINE

    Treat the image as a single text line.

    没什么好说的。

  3. PSM_SPARESE_TEXT

    Find as much text as possible in no particular order.

    奇奇怪怪的模式,会将所有的东西尽可能的识别。有些时候就会发生把一个字拆成了两部分之类的问题。

TessBaseAPISetImage2

1
api.TessBaseAPISetImage2(ITessAPI.TessBaseAPI handler, Pix pix);

设置将要处理的图片,这里的Pix类并不是很懂。

TessBaseAPIGetUTF8Text

1
Pointer pointer = api.TessBaseAPIGetUTF8Text(handle);

识别并且获取识别到的数据,这个数据是以jna中的指针传回来的。这个是为了与本地库中的指针向接,最后只需要对pointer调用getString就可以获得想要的结果了。

PIX类和PIXA类

两个完全不明所以的类。。。他们是另一个叫做Leptonica的依赖库的两个类,大致功能是负责图像的存储,由于Leptonica的文档全是C的,又多又杂都不知道怎么去看。。所以基本不懂,大致按照test来做。不过可以知道PIXA是PIX的array。

本次项目中只是用到了它们与BuffererdImage的转换,以直接传入图片数据,不必再去获取image的数据来初始化。。(好像没见过除了Tesseract之外的库或者项目用过这个库。。)

提高识别率

写下了以上的代码之后,可以发现的是,识别率依旧是非常感人的,基本不能看,所以我们必须要提高识别率。

官方提供的方法

  1. Binarisation:二值化
  2. Noise Removal:祛除噪点
  3. Rotation:把图片转正
  4. Border Removal:除去所有边框

以上所有工作显然是OpenCV可以完成的。

其他的办法

  1. 文字的尺寸不能低于10px,尽量在20px左右;
  2. 文字的周围要有一定的空间留白,不要定格;
  3. 图片一定是灰度的,不能是RGB格式的图片;
  4. 添加黑白名单,过滤掉所有的特殊符号(包括明显不可能出现的日语等);
  5. 识别数字的时候,必须使用英文的字典,中文的字典对数字的识别效果会很不好。
  6. 宋体的识别率相对要高一些;
  7. 网上有人说Tesseract的分类器是自学习的,所以一次初始化之后要多次使用,效果会越来越好。甚至可以在前面先加入一大段文字,然后再识别正文。(加段文字这个方法有些情况是有效的,有些时候没效果,酌情使用)

没有用的一些处理

  1. 调高图片的dip;(虽然官方说有用,但实际上确实没发现效果)
  2. 反色;
  3. 让文字变粗或者变细;
  4. 让文字之间的空隙变大;(在很多情况下还是会将一个字拆成两个,Tesseract并没有发现字与字之间的空隙)
  5. 在字与字之间加上明显的线来区分每一个字。(在有些情况却是可行的。。。)

实验中的处理方法

对最后的文字进行分词及语法分析,找出其中明显的错字,然后再字典中寻找对应正确的词。
目前lucene库似乎可以满足要求。。

Tesseract的训练

网上有太多的资料可以查询,但是要注意的是:

  1. 应该不能再目前已有的字典上再次进行训练;
  2. 图片一定要是灰度或者二值化的,否则大量图片无法识别;
  3. 创建一个汉字字典将需要极大的时间(我反正10个小时没能弄完3500个汉字)。

Powered by Hexo and Hexo-theme-hiker

Copyright © 2013 - 2018 Alex's Blog All Rights Reserved.

Yifeng Tang hält Urheberrechtsansprüche.