Java使用Tesseract-Ocr识别数字
作者:gcdd1993 发布时间:2022-12-30 05:15:44
目录
前言
简介
在Java上使用
创建项目,并引入Jar包
导入traineddata
编写测试代码
训练工具
训练数据仓库
参考
前言
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
<!-- https://mvnrepository.com/artifact/net.sourceforge.tess4j/tess4j -->
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>4.3.1</version>
</dependency>
Gradle
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引擎
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构造函数中,没有提供可选参数的构造器。
public class Tesseract implements ITesseract {
// Tesseract使用的语言版本,用以选择traineddata
private String language = "eng";
// traineddata目录,里面放*.traineddata数据文件
private String datapath;
// 省略其他代码 ...
public Tesseract() {
try {
// 默认从系统环境变量获取traineddata目录
datapath = System.getenv("TESSDATA_PREFIX");
} catch (Exception e) {
// ignore
} finally {
if (datapath == null) {
datapath = "./";
}
}
}
/**
* Sets language for OCR.
*
* @param language the language code, which follows ISO 639-3 standard.
*/
@Override
public void setLanguage(String language) {
this.language = language;
}
/**
* Sets path to <code>tessdata</code>.
*
* @param datapath the tessdata path to set
*/
@Override
public void setDatapath(String datapath) {
this.datapath = datapath;
}
// 省略其他代码 ...
}
所以,我们可以选择设置环境变量TESSDATA_PREFIX为数据目录,或者通过Java编码的方式来设置。
tesseract.setLanguage("eng"); // 默认就是eng,你可以选择其他lang
tesseract.setDatapath(TesseractTest.class.getResource("/traineddata").getPath().substring(1));
OCR识别测试
tesseract提供了一系列doOcr方法的重载,我们可以方便的进行OCR识别。
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链接,如下所示
@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);
}
控制台输出:
tesseract init done...
ocr result : 2710386495
识别准确率,主要在于你选择的训练数据文件,我使用的是数据文件是这个,对于数字的准确率基本上是100%。
异常
如果你遭遇Invalid memory access异常,这是由于找不到对应lang的*.traineddata文件,请修改language和datapath。
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:基于LSTM引擎的训练数据,最佳最准确的
tessdata_fast:基于LSTM引擎的训练数据,快速(精简)版本
tessdata:支持双引擎(LSTM和传统引擎),但LSTM训练数据不是最新的版本
推荐使用tessdata_best,虽然识别速度相对于tessdata_fast稍慢,但是准确率可以保证。
参考
tesseract-ocr-wiki
来源:https://www.cnblogs.com/gcdd1993/p/12292455.html
猜你喜欢
- FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写FreeMarker被设计用来生成HTML Web
- 一 . 得到这个对象的实例Connection con ;con = DriverManager.getConnection(url,use
- 1. Mybatis的@param注解自定义对象也用@param注解注:使用@param注解,mapper.xml 不加parameterT
- 实例如下:using System;using System.Linq.Expressions;class DynamicPredicate
- 问题:startTime = DateTime.Now;
- using System;using System.Collections.Generic;using System.Text;namesp
- 为什么要优雅的处理异常如果我们不统一的处理异常,经常会在controller层有大量的异常处理的代码, 比如:@Slf4j@Api(valu
- 目录一、首先导入生成二维码和微信支付环境二、在application.yml文件配置微信所有需的基本配置1.导入2.创建MyWXPayCon
- 本文实例讲述了Java模拟死锁发生之演绎哲学家进餐问题。分享给大家供大家参考,具体如下:一 点睛常见的死锁形式:当线程1已经占据资源R1,并
- Spring Boot中可以在配置文件中直接进行数据库配置,spring.datasource.username= rootspring.d
- 在讲述这个模式之前,我们先看一个案例:游戏回档游戏的某个场景,一游戏角色有生命力、攻击力、防御力等数据,在打Boss前和后会不一样,我们允许
- 用java来打包文件生成压缩文件,有两个地方会出现乱码:内容的中文乱码问题:修改sun的源码。使用开源的类库org.apache.tools
- 本文实例讲述了Spring实战之Bean定义中的SpEL表达式语言支持操作。分享给大家供大家参考,具体如下:一 配置<?xml ver
- 异步,说到异步需要首先将以下同步。同步就是代码按照顺序执行,当前面的代码的请求没有正常返回结果的情况下,后面的代码是不能运行。而异步正好和这
- PDF文件和图片文件,这是两种完全不一样的格式,可是有的时候这两种格式却是有相互转换的需要,大家在工作中遇到PDF文件转图片文件的问题时是怎
- 这篇文章主要介绍了Java解析json报文实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可
- 咱们废话不多说进入主题、系统主页展示:用户登录后进行系统首页:主要功能模块如下、分角色管理、超级管理员拥有最高权限、可以进行菜单灵活控制、用
- 一、Lombok从上一篇博客可看出,DAO接口类的编写变得简单,反过来看模型,编写还需要(私有属性、setter...getter...方法
- 使用filter设置要排除的URL@WebFilter(urlPatterns = "/*")@Order(value
- 本文实例为大家分享了Java实现简单贪吃蛇游戏的具体代码,供大家参考,具体内容如下贪吃蛇小游戏制作方法首先需要的准备有:1、掌握Java基础