Tesseract识别图片提取文字&字库训练
文中测试了3.0和4.0两个版本。发现3.0识别效率不准确,需要训练词库。4.0识别效率就比较高了,而且支持结果生成pdf、txt等格式。所以推荐使用4.0版本。
这个工具可以用在爬虫的时候获取验证码进行识别且自动输入验证码的功能。
git地址:https://github.com/tesseract-ocr/tesseract
下载地址:https://digi.bib.uni-mannheim.de/tesseract/
1.下载安装
我下载的是 3.05.01,自带了中文词库。
下载完成后目录结构:
2.测试识别
0.准备一张文字图片
1.添加环境变量到path中,可以直接使用tesseract命令。检查是否配置成功
C:\Users\Administrator\Desktop\新建文件夹>tesseract -v
tesseract 3.05.
leptonica-1.74.
libgif 4.1.(?) : libjpeg 8d (libjpeg-turbo 1.5.) : libpng 1.6. : libtiff 4.0. : zlib 1.2. : libwebp 0.4. : libopenjp2 2.1.
查看命令可以携带的参数:
PS C:\Users\Administrator\Desktop\新建文件夹> tesseract
Usage:
E:\tesseract\Tesseract-OCR\tesseract.exe --help | --help-psm | --help-oem | --version
E:\tesseract\Tesseract-OCR\tesseract.exe --list-langs [--tessdata-dir PATH]
E:\tesseract\Tesseract-OCR\tesseract.exe --print-parameters [options...] [configfile...]
E:\tesseract\Tesseract-OCR\tesseract.exe imagename|stdin outputbase|stdout [options...] [configfile...] OCR options:
--tessdata-dir PATH Specify the location of tessdata path.
--user-words PATH Specify the location of user words file.
--user-patterns PATH Specify the location of user patterns file.
-l LANG[+LANG] Specify language(s) used for OCR.
-c VAR=VALUE Set value for config variables.
Multiple -c arguments are allowed.
--psm NUM Specify page segmentation mode.
--oem NUM Specify OCR Engine mode.
NOTE: These options must occur before any configfile. Page segmentation modes:
Orientation and script detection (OSD) only.
Automatic page segmentation with OSD.
Automatic page segmentation, but no OSD, or OCR.
Fully automatic page segmentation, but no OSD. (Default)
Assume a single column of text of variable sizes.
Assume a single uniform block of vertically aligned text.
Assume a single uniform block of text.
Treat the image as a single text line.
Treat the image as a single word.
Treat the image as a single word in a circle.
Treat the image as a single character.
Sparse text. Find as much text as possible in no particular order.
Sparse text with OSD.
Raw line. Treat the image as a single text line,
bypassing hacks that are Tesseract-specific.
OCR Engine modes:
Original Tesseract only.
Cube only.
Tesseract + cube.
Default, based on what is available. Single options:
-h, --help Show this help message.
--help-psm Show page segmentation modes.
--help-oem Show OCR Engine modes.
-v, --version Show version information.
--list-langs List available languages for tesseract engine.
--print-parameters Print tesseract parameters to stdout.
2.进入cmd,进入到要识别的图片的路径下。
C:\Users\Administrator\Desktop\新建文件夹>tesseract ./.jpg re
Error opening data file \tesseract\Tesseract-OCR\tessdata/eng.traineddata
Please make sure the TESSDATA_PREFIX environment variable is set to the parent directory of your "tessdata" directory.
Failed loading language 'eng'
Tesseract couldn't load any languages!
Could not initialize tesseract.
发现报错没有语言,解决办法: 将 tesseract 安装目录下的 tessdata 文件夹配置到环境变量 TESSDATA_PREFIX
C:\Users\Administrator>set TESSDATA_PREFIX
TESSDATA_PREFIX=E:\tesseract\Tesseract-OCR\tessdata
3.再次测试
C:\Users\Administrator\Desktop\新建文件夹>tesseract ./.png re
Tesseract Open Source OCR Engine v3.05.01 with Leptonica
会生成一个re.txt文件,内容如下:(发现中文乱码)
4.解决中文乱码问题:加 -l 参数指定语言即可
(1)查看支持的语言
C:\Users\Administrator\Desktop\新建文件夹>tesseract --list-langs
List of available languages ():
afr
amh
ara
。。。
(2)使用 chi_sim 识别图片
C:\Users\Administrator\Desktop\新建文件夹>tesseract -l chi_sim ./.png re
Tesseract Open Source OCR Engine v3.05.01 with Leptonica
3.测试复杂的中文识别---词库训练
1.原来图片如下
2. 识别之后的内容如下
3.解决上面的问题---利用jTessBoxEditor工具进行Tesseract3.02.02样本训练
此工具基于java运行,所以需要安装java环境。
1.下载 jTessBoxEditor :http://tenet.dl.sourceforge.net/project/vietocr/jTessBoxEditor/jTessBoxEditor-1.5.zip
2.解压运行
$ java -jar jTessBoxEditor.jar
3. 将上面的图片转换成tif格式,用于后面生成box文件。可以通过画图,然后另存为tif即可
tif文面命名格式[lang].[fontname].exp[num].tif
lang是语言 fontname是字体
比如我们要训练自定义字库 mylan 字体名normal
那么我们把图片文件重命名 mylan.normal.exp0.jpg在转tif。(画图工具中另存为就可以)
4.生成box文件。
tesseract mylan.normal.exp0.jpg mylan.normal.exp0 -l chi_sim batch.nochop makebox
box文件和对应的tif一定要在相同的目录下,不然后面打不开。会生产一个box文件。
5.打开jTessBoxEditor矫正错误并训练
打开train.bat
找到tif图,打开,并校正。(校正完保存即可)
6、训练。
(1) 只要在命令行输入命令即可。(执行第一条命令会生产.tr文件,也可以先执行一次然后删掉tr测试是否可以训练)
tesseract mylan.normal.exp0.jpg mylan.normal.exp0 nobatch box.train unicharset_extractor mylan.normal.exp0.box
或者输入两个合并执行的命令:
tesseract mylan.normal.exp0.jpg mylan.normal.exp0 nobatch box.train && unicharset_extractor mylan.normal.exp0.box
如下证明全部识别完毕:
(2)新建一个font_properties文件
里面内容写入 normal 0 0 0 0 0 表示默认普通字体 (要求normal与上面的字体名称必须一致),下面是命令直接重定向(注意重定向>和>>的区别是>是覆盖模式,>>是追加模式):
echo normal >> font_properties
(3)继续敲命令:
shapeclustering -F font_properties -U unicharset mylan.normal.exp0.tr mftraining -F font_properties -U unicharset -O unicharset mylan.normal.exp0.tr cntraining mylan.normal.exp0.tr
或者一次性执行下面命令:
shapeclustering -F font_properties -U unicharset mylan.normal.exp0.tr && mftraining -F font_properties -U unicharset -O unicharset mylan.normal.exp0.tr && cntraining mylan.normal.exp0.tr
最后会生成五个文件,把目录下的unicharset、inttemp、pffmtable、shapetable、normproto这五个文件前面都加上normal.
如图:
或者执行如下命令进行重命名:
mv ./unicharset ./normal.unicharset && mv ./inttemp ./normal.inttemp && mv ./pffmtable ./normal.pffmtable && mv ./shapetable ./normal.shapetable && mv ./normproto ./normal.normproto
(4)命令行输入,合并五个文件:
combine_tessdata normal.
得到训练好的字库。
(5)把 normal.traineddata 复制到Tesseract-OCR 安装目录下的tessdata文件夹中
或者执行以下命令即可:( TESSDATA_PREFIX 是配置的环境变量)
mv ./normal.traineddata $TESSDATA_PREFIX
或者执行复制命令:
cp ./normal.traineddata $TESSDATA_PREFIX
7.测试:
识别命令:(可以使用两种语言,也可以使用一种语言)
Administrator@MicroWin10-1535 MINGW64 ~/Desktop/新建文件夹
$ tesseract mylan.normal.exp0.jpg result -l normal
Tesseract Open Source OCR Engine v3.05.01 with Leptonica Administrator@MicroWin10-1535 MINGW64 ~/Desktop/新建文件夹
$ tesseract mylan.normal.exp0.jpg result2 -l normal+chi_sim
Tesseract Open Source OCR Engine v3.05.01 with Leptonica
结果:(上面的 result 是指定生成的txt文件的前缀 )
补充:用notepad++打开之后会发现有换行:
这个需要大量的训练词库。不知道是否有更好的解决办法。
补充:一个Java程序调用runtime执行本地命令,并读取生成的文件内容:
package cn.xm.exam.test; import java.io.File;
import java.io.IOException;
import java.io.InputStream; import org.apache.commons.io.FileUtils;
import org.apache.xmlbeans.impl.common.IOUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.ibm.wsdl.util.IOUtils; @SuppressWarnings("all")
public class PlainTest {
private static final Logger logger = LoggerFactory.getLogger(Test.class); public static void main(String[] args) throws IOException {
// 执行命令生成文件
String cmd = "E:/tesseract/Tesseract-OCR/tesseract.exe G://test.jpg G://tmp -l normal+chi_sim";
boolean exec = exec(cmd);
if (exec) {
String readFileToString = FileUtils.readFileToString(new File("G://tmp.txt"));
System.out.println(readFileToString);
}
} public static boolean exec(String command) {
Process process;// Process可以控制该子进程的执行或获取该子进程的信息
try {
logger.debug("exec cmd : {}", command);
process = Runtime.getRuntime().exec(command);// exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。
// 下面两个可以获取输入输出流
InputStream errorStream = process.getErrorStream();
InputStream inputStream = process.getInputStream();
} catch (IOException e) {
logger.error(" exec {} error", command, e);
return false;
} int exitStatus = 0;
try {
exitStatus = process.waitFor();// 等待子进程完成再往下执行,返回值是子线程执行完毕的返回值
// 第二种接受返回值的方法
int i = process.exitValue(); // 接收执行完毕的返回值
logger.debug("i----" + i);
} catch (InterruptedException e) {
logger.error("InterruptedException exec {}", command, e);
return false;
} if (exitStatus != 0) {
logger.error("exec cmd exitStatus {}", exitStatus);
} else {
logger.debug("exec cmd exitStatus {}", exitStatus);
} process.destroy(); // 销毁子进程
process = null; return true;
}
}
结果:(会将换行也读取出来)
1 23456
这是一告测试中文
不能告诉@154856.text
电话:1 8434391 711
=====下面研究 Tesseract 4.0版本的使用(推荐使用这个版本)=========
官方对 Tesseract4.0 版本做了很多的改进,而且自带的语言库也增加了很多。下面研究在4.0版本的识别。经过研究,4.0版本是可以直接拿来就用的,都不用训练词。识别为pdf的准确率更加高,所以在实际中可以识别为pdf然后用apache-tika提取pdf的内容。这样识别率更加的高效。
1. 下载安装
2.修改环境变量为最新的4.0版本并测试
$ tesseract --version
tesseract v4.0.0.20181030
leptonica-1.76.0
libgif 5.1.4 : libjpeg 8d (libjpeg-turbo 1.5.3) : libpng 1.6.34 : libtiff 4.0.9 : zlib 1.2.11 : libwebp 0.6.1 : libopenjp2 2.2.0
3.接下来还是对上面的带中文的进行识别
tesseract ./1.jpg result -l chi_sim
结果:(识别率已经非常准确了)
4.测试将识别结果直接提取为字符串、存储为pdf(双层pdf)或者xml
(1)直接提取为文本
$ tesseract ./1.jpg stdout -l chi_sim
123456
这是一个测试中文 不能告诉@154856 .text
电话:18434391711
(2)提取为pdf
在4.0之后可以自动将识别结果提取为pdf\txt\xml等格式的数据。
Administrator@MicroWin10-1535 MINGW64 ~/Desktop/新建文件夹
$ tesseract ./1.jpg result -l chi_sim pdf
Tesseract Open Source OCR Engine v4.0.0.20181030 with Leptonica
结果:
(3)当然可以一次性提取为多个文件,只需要在后面空格分割就可以了
tesseract ./0101.jpg result -l chi_sim pdf txt
结果会生成三个文件
5.测试识别复杂的中文图片
图片内容如下:
(1)直接提取内容到输出控制台
$ tesseract ./0101.jpg stdout -l chi_sim 一个车者对禅师说: “我放不下一-些事放不下一些人。” 禅师说没有什么东西是真正放不下的。苦者说: 可我就信信放不下. 禅师递给他一个水杯然后就入里面侠 -直例到水溢出来。贡者被通到马_上松开了手,水杯掉在
地上摔坏了。 禅师说:其实,这个世界_上没有什么事是放不下的,痛了,你自然就会放下 土者说到“我能换个水杯吗? 禅师微微一笑道:“可以”他从包里拿出一一个水杯 ,说到再试试吧 , 禅师又往水杯里倒水,水溢出
来 , 这次他没有放手 祥岳问道:“不汤吗”?苦者说“和” 禅师又问“为何不放手?”葫者说道“这水杯是她送的。禅师回头叹“番狗是真的牛通
(2)查看提取tx和pdf的效率
$ tesseract ./0101.jpg result -l chi_sim pdf txt
txt和控制台的结果一样:
pdf识别结果更加准确:(接近百分之百)
经过上面的实验发现啊,pdf的识别是识别的双层pdf,我自己的一种思路就是:将识别结果存到pdf,然后用ApacheTika提取pdf的内容,这样识别效率应该会更加准确。
6. java中调用runtime获取识别结果和提取为pdf之后用ApacheTika提取pdf内容
(1)读取内容到字符串中
package zd.dms.utils.ebuy; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import org.apache.tika.exception.TikaException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException; @SuppressWarnings("all")
public class PlainTest {
private static final Logger logger = LoggerFactory.getLogger(PlainTest.class); public static void main(String[] args) throws IOException, SAXException, TikaException {
// 执行命令生成文件
String cmd = "E:/tesseract4/Tesseract-OCR/tesseract.exe G://0101.jpg stdout -l chi_sim";
boolean exec = exec(cmd);
} public static boolean exec(String command) {
Process process;// Process可以控制该子进程的执行或获取该子进程的信息
String result = "";
try {
logger.debug("exec cmd : {}", command);
process = Runtime.getRuntime().exec(command);// exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。
// 下面两个可以获取输入输出流
InputStream errorStream = process.getErrorStream(); // 获取其正常的输出流
InputStream inputStream = process.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(inputStreamReader);
String line = null;
while ((line = br.readLine()) != null) {
result += line;
} } catch (IOException e) {
logger.error(" exec {} error", command, e);
return false;
} int exitStatus = 0;
try {
exitStatus = process.waitFor();// 等待子进程完成再往下执行,返回值是子线程执行完毕的返回值
// 第二种接受返回值的方法
int i = process.exitValue(); // 接收执行完毕的返回值
logger.debug("i----" + i);
} catch (InterruptedException e) {
logger.error("InterruptedException exec {}", command, e);
return false;
} if (exitStatus != 0) {
logger.error("exec cmd exitStatus {}", exitStatus);
} else {
logger.debug("exec cmd exitStatus {}", exitStatus);
} process.destroy(); // 销毁子进程
process = null; // result就是获取到的结果
System.out.println(result);
return true;
}
}
结果:
一个车者对禅师说: “我放不下一-些事放不下一些人。”禅师说没有什么东西是真正放不下的。苦者说: 可我就信信放不下.禅师递给他一个水杯然后就入里面侠 -直例到水溢出来。贡者被通到马_上松开了手,水杯掉在地上摔坏了。禅师说:其实,这个世界_上没有什么事是放不下的,痛了,你自然就会放下土者说到“我能换个水杯吗?禅师微微一笑道:“可以”他从包里拿出一一个水杯 ,说到再试试吧 , 禅师又往水杯里倒水,水溢出来 , 这次他没有放手祥岳问道:“不汤吗”?苦者说“和”禅师又问“为何不放手?”葫者说道“这水杯是她送的。禅师回头叹“番狗是真的牛通
(2)读取内容到pdf中然后tika读取pdf
package zd.dms.utils.ebuy; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream; import org.apache.commons.io.FileUtils;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.pdf.PDFParser;
import org.apache.tika.sax.BodyContentHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException; @SuppressWarnings("all")
public class PlainTest {
private static final Logger logger = LoggerFactory.getLogger(PlainTest.class); public static void main(String[] args) throws IOException, SAXException, TikaException {
// 执行命令生成文件
String cmd = "E:/tesseract4/Tesseract-OCR/tesseract.exe G://0101.jpg G://result -l chi_sim pdf";
boolean exec = exec(cmd);
if (exec) {
BodyContentHandler handler = new BodyContentHandler();
Metadata metadata = new Metadata();
FileInputStream inputstream = new FileInputStream(new File("G://result.pdf"));
ParseContext pcontext = new ParseContext(); // parsing the document using PDF parser
PDFParser pdfparser = new PDFParser();
pdfparser.parse(inputstream, handler, metadata, pcontext); // getting the content of the document
System.out.println("Contents of the PDF :" + handler.toString());
}
} public static boolean exec(String command) {
Process process;// Process可以控制该子进程的执行或获取该子进程的信息
try {
logger.debug("exec cmd : {}", command);
process = Runtime.getRuntime().exec(command);// exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。
// 下面两个可以获取输入输出流
InputStream errorStream = process.getErrorStream();
InputStream inputStream = process.getInputStream();
} catch (IOException e) {
logger.error(" exec {} error", command, e);
return false;
} int exitStatus = 0;
try {
exitStatus = process.waitFor();// 等待子进程完成再往下执行,返回值是子线程执行完毕的返回值
// 第二种接受返回值的方法
int i = process.exitValue(); // 接收执行完毕的返回值
logger.debug("i----" + i);
} catch (InterruptedException e) {
logger.error("InterruptedException exec {}", command, e);
return false;
} if (exitStatus != 0) {
logger.error("exec cmd exitStatus {}", exitStatus);
} else {
logger.debug("exec cmd exitStatus {}", exitStatus);
} process.destroy(); // 销毁子进程
process = null; return true;
}
}
结果:
个对禅师说 “我放 不 一-些事放不一 。”
禅师说没有什么东西是真正不下的 者可我信不.
禅师递给一水杯然后入里面侠 -直例到水溢出来 者通到马上松了手,水掉
摔了。
禅师 :其,这个世界上没有什么事是不下 , 痛了 , 你自然就放下
者到 “我能换个水杯?
禅师微微笑 :“可以”他里拿出一水,说到再试试吧 , 禅师又往水杯里倒水 ,水溢出
来 , 这次他没有放手
祥岳 问 不汤”? 者 “和”
禅师又 何不放手?”者 “这水杯她送的 禅师回头 “番真牛通
git上面的文档对4.0最新的每个命令都有介绍,参照git上的doc文件夹下面对每个文件的介绍:https://github.com/tesseract-ocr/tesseract/tree/master/doc
Tesseract识别图片提取文字&字库训练的更多相关文章
- C# 10分钟完成百度图片提取文字(文字识别)——入门篇
现在图片文字识别已经很成熟了,比如qq长按图片,点击图片识别就可以识别图片的文字,将不认识的.文字数量大的.或者不能赋值的值进行二次可复制功能. 我们现在就基于百度Ai开放平台进行个人文字识别,dem ...
- python tesseract 识别图片中的文字的乱码问题(ubuntu系统下)
OCR(Optical Character Recognition):光学字符识别,是指对图片文件中的文字进行分析识别,获取的过程. 首先,需要安装 tesseract-ocr(tesseract O ...
- 【Windows】免费图片提取文字的方法
今天意外的看到一个可以提取图片中文字的网站,自己试了下,提取效果还不错 网址为: https://zhcn.109876543210.com/ 现在有图片如下 我想从中提取的文字 1.打开网址,上传图 ...
- python下以api形式调用tesseract识别图片验证码
一.背景 之前在博文中介绍在python中如何调用tesseract ocr引擎,当时主要介绍了shell模式,shell模式需要安装tesseract程序,并且效率相对略低. 今天介绍api形式的调 ...
- 使用ORC识别图片的文字
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- Windows下 训练Tesseract实现识别图片中的文字
介绍 Tesseract是一个基于Apache2.0协议开源的跨平台ocr引擎,支持多种语言的识别,在Windows和Linux上都有良好的支持. 源代码在这: 源码地址 有一个编译打包好的Windo ...
- 使用 Python 识别并提取图像中的文字
1. 介绍 介绍使用 python 进行图像的文字识别,将图像中的文字提取出来,可以帮助我们完成很多有趣的事情. 2. 必备工具 tesseract-ocr 下载地址: https://github. ...
- linux tesseract识别名片
用tesseract识别名片,无任何训练 数字,字母识别的准确率比较高,没有错误,规范的汉字识别的还可以,比如名片背面,正面的就错误比较多了: 没有任何训练,识别的还算可以了:我们主要要的电话和QQ ...
- 基于Tesseract实现图片文字识别
一.简介 Tesseract是一个开源的文本识别[OCR]引擎,可通过Apache 2.0许可获得.它可以直接使用,或者使用API从图像中提取打印的文本,支持多种语言.该软件包包含一个ORC引擎[l ...
随机推荐
- 我眼中的正则化(Regularization)
警告:本文为小白入门学习笔记 在机器学习的过程中我们常常会遇到过拟合和欠拟合的现象,就如西瓜书中一个例子: 如果训练样本是带有锯齿的树叶,过拟合会认为树叶一定要带有锯齿,否则就不是树叶.而欠拟合则认为 ...
- BZOJ3531 树剖 + 动态开点线段树
https://www.lydsy.com/JudgeOnline/problem.php?id=3531 首先这题意要求树链上的最大值以及求和,其树链剖分的做法已经昭然若揭 问题在于这次的信息有宗教 ...
- 购物demo
这段时间从一个模板网站上拷了个购物系统的demo,试着写了一下,发现div+css布局还真是精妙无穷呢.设置好了布局,加上动态效果也只是锦上添花而已.所以,接下来的重点就是布局了! 我把网址粘上去:h ...
- Django REST Framework限速
官方文档:http://www.django-rest-framework.org/api-guide/throttling/#throttling settings.py配置 REST_FRAMEW ...
- 人工神经网络入门(4) —— AFORGE.NET简介
范例程序下载:http://files.cnblogs.com/gpcuster/ANN3.rar如果您有疑问,可以先参考 FAQ 如果您未找到满意的答案,可以在下面留言:) 0 目录人工神经网络入门 ...
- RelativeLayout中include 控件覆盖重叠的问题
RelativeLayout直接include另一个layout是会把include中的控件与当前layout中的控件覆盖重叠,经过查资料 其中的include标签一定要加上(因为include中不指 ...
- CSS常用选择器的认识
---恢复内容开始--- 前言:在CSS中选择器的种类有很多很多,但是在实际的工作中,我们经常会用到的分为两大类:基础选择器和复合选择器这两个大类,学习选择器的目的就是为了在复杂的页面中能够快速定位到 ...
- linux xargs【转】
-i -I 参数区别 http://man.linuxde.net/xargs 它们都是用来作参数扩展替换的,以下两句代码其实效果一样 cat arg.txt|xargs -i sh sk.sh -p ...
- golang os包使用笔记
zhangsan os.Stidn 标准输入 os.Stdout 标准输出 os.Stderr 标准错误输出
- POJ 3070(求斐波那契数 矩阵快速幂)
题意就是求第 n 个斐波那契数. 由于时间和内存限制,显然不能直接暴力解或者打表,想到用矩阵快速幂的做法. 代码如下: #include <cstdio> using namespace ...