前言 Tesseract-Ocr 是我在编写爬虫项目中,用来识别图片(不是验证码)的本地解决方案(因为客户不想使用API识别,太贵),识别率目前达到了100%,可以说是相当了得,当然了,这取决于使用的traineddata
。
简介
Tesseract最初是在1985年至1994年间在Hewlett-Packard Laboratories Bristol和Greeley Colorado的Hewlett-Packard Co开发的,1996年进行了一些更改,移植到Windows,并且随着C++在1998年兴起。2005年Tesseract由惠普开源,然后从2006年至今,由谷歌继续开发。
Tesseract-Ocr并不是一个软件,它是一个软件包,包含了一个OCR引擎【libtesseract】和一个命令行程序 【tesseract】。Tesseract 4增加了一个基于OCR引擎的新神经网络(LSTM),该引擎专注于行级识别,但仍然支持Tesseract 3的传统Tesseract OCR引擎,该引擎通过识别字符模式来工作。
要启用与Tesseract 3的兼容性,你需要使用Legacy OCR Engine模式(–oem 0)。它还需要支持传统引擎的traineddata(训练好的数据文件),这些文件可以从tessdata存储库 的文件获取。
Tesseract支持识别unicode(UTF-8),可以“开箱即用”识别100多种语言。
Tesseract支持多种输出格式:纯文本,hOCR(HTML),PDF,TSV。主分支还具有ALTO(XML)输出的实验支持。
⭐️⭐️⭐️ 具体介绍可以上tesseract-wiki 查看。
在Java上使用 创建项目,并引入Jar包 Maven 1 2 3 4 5 6 <dependency > <groupId > net.sourceforge.tess4j</groupId > <artifactId > tess4j</artifactId > <version > 4.3.1</version > </dependency >
Gradle 1 compile 'net.sourceforge.tess4j:tess4j:4.3.1'
导入traineddata traineddata
是使用Tesseract-Ocr
训练好的数据文件,可以直接使用。这些文件你可以去tessdata存储库 查找,也可以去谷歌搜索,当然了,你也可以自己训练😂。
traineddata
通常以*.traineddata
命名,其中*指的是支持的语言类型。在这里 你可以看到4.0.0版本支持的语言以及traineddata
列表。
这次,我们选择eng.traineddata
进行测试。下载eng.traineddata 放入/resources/traineddata
目录,如下图所示。
编写测试代码 初始化Tesseract引擎 1 2 3 4 5 6 7 8 9 10 11 public class TesseractTest { private ITesseract tesseract; @Before public void init () { tesseract = new Tesseract(); System.out.println("tesseract init done..." ); } }
实际上,上面的代码是无法正常运行的,因为找不到指定语言版本的traineddata
文件。
net.sourceforge.tess4j:tess4j:4.1.1
提供的API并不好,在Tesseract
构造函数中,没有提供可选参数的构造器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public class Tesseract implements ITesseract { private String language = "eng" ; private String datapath; public Tesseract () { try { datapath = System.getenv("TESSDATA_PREFIX" ); } catch (Exception e) { } finally { if (datapath == null ) { datapath = "./" ; } } } @Override public void setLanguage (String language) { this .language = language; } @Override public void setDatapath (String datapath) { this .datapath = datapath; } }
所以,我们可以选择设置环境变量TESSDATA_PREFIX
为数据目录,或者通过Java编码的方式来设置。
1 2 tesseract.setLanguage("eng" ); tesseract.setDatapath(TesseractTest.class.getResource("/traineddata" ).getPath().substring(1 ));
OCR识别测试 tesseract
提供了一系列doOcr
方法的重载,我们可以方便的进行OCR识别。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 String doOCR (File imageFile) throws TesseractException ;String doOCR (File imageFile, Rectangle rect) throws TesseractException ;String doOCR (BufferedImage bi) throws TesseractException ;String doOCR (BufferedImage bi, Rectangle rect) throws TesseractException ;String doOCR (List<IIOImage> imageList, Rectangle rect) throws TesseractException ;String doOCR (List<IIOImage> imageList, String filename, Rectangle rect) throws TesseractException ;String doOCR (int xsize, int ysize, ByteBuffer buf, Rectangle rect, int bpp) throws TesseractException ;String doOCR (int xsize, int ysize, ByteBuffer buf, String filename, Rectangle rect, int bpp) throws TesseractException ;
可以看出,doOcr
方法支持多种图片识别方式,如图片文件、多个图片文件、图片文件局部处理等等方式。
为了方便测试,我们选取最简单的图片文件方式测试。
图片 是个URL链接,如下所示
1 2 3 4 5 6 @Test public void testOcr () throws IOException, TesseractException { BufferedImage image = ImageIO.read(new URL("http://static8.ziroom.com/phoenix/pc/images/price/aacd14fbc53a106c7f0f0d667535683as.png" )); String ocr = tesseract.doOCR(image); System.out.println("ocr result : " + ocr); }
控制台输出:
1 2 tesseract init done... ocr result : 2710386495
识别准确率,主要在于你选择的训练数据文件 ,我使用的是数据文件是这个 ,对于数字的准确率基本上是100%。
异常 如果你遭遇Invalid memory access
异常,这是由于找不到对应lang的*.traineddata
文件,请修改language
和datapath
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Invalid memory access java.lang.Error: Invalid memory access at com.sun.jna.Native.invokePointer(Native Method) at com.sun.jna.Function.invokePointer(Function.java:470) at com.sun.jna.Function.invoke(Function.java:404) at com.sun.jna.Function.invoke(Function.java:315) at com.sun.jna.Library$Handler .invoke(Library.java:212) at com.sun.proxy.$Proxy9 .TessBaseAPIGetUTF8Text(Unknown Source) at net.sourceforge.tess4j.Tesseract.getOCRText(Tesseract.java:495) at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:321) at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:293) at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:274) at net.sourceforge.tess4j.Tesseract.doOCR(Tesseract.java:258) ...
训练工具 https://github.com/tesseract-ocr/tesseract/wiki/AddOns
训练数据仓库
推荐使用tessdata_best ,虽然识别速度相对于tessdata_fast 稍慢,但是准确率可以保证。
参考 tesseract-ocr-wiki