pytesseract是基于Python的OCR工具, 底层使用的是Google的Tesseract-OCR 引擎,支持识别图片中的文字,支持jpeg, png, gif, bmp, tiff等图片格式。本文介绍如何使用pytesseract 实现图片文字识别。
引言
OCR(Optical character recognition,光学字符识别)是一种将图像中的手写字或者印刷文本转换为机器编码文本的技术。通过数字方式存储文本数据更容易保存和编辑,可以存储大量数据,比如1G的硬盘可以存储数百万本书。
OCR技术可以将图片,纸质文档中的文本转换为数字形式的文本。OCR过程一般包括以下步骤:
- 图像预处理
- 文本定位
- 字符分割
- 字符识别
- 后处理
最初由惠普开发,后来Google赞助的开源OCR引擎 tesseract 提供了比较精确的文字识别API,本文将要介绍的Python库Pytesseract就是基于Tesseract-OCR 引擎。
环境配置
环境要求:
- Python 3.6+
- 太平船务库
- 安装Google Tesseract OCR
- 系统:windows/mac/linux,我的系统是Windows10
1. 安装谷歌 Tesseract
Tesseract OCR github地址: GitHub - tesseract-ocr/tesseract: Tesseract Open Source OCR Engine (main repository)
Windows Tesseract下载地址: Index of /tesseract
Mac和Linux安装方法参考: Introduction | tessdoc
安装时可以选择需要的语言包:
![](https://img-blog.csdnimg.cn/img_convert/d77aca21e080a8b8f78eda70af431183.png)
安装完成后,添加到环境变量PATH中,我的安装路径是: 。C:\Program Files\Tesseract-OCR
命令行窗口输入: ,查看是否安装成功。tesseract
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">$ tesseract
Usage:
tesseract --<span style="color:#333333"><strong>help</strong></span> | --<span style="color:#333333"><strong>help</strong></span>-extra | --<span style="color:#333333"><strong>version</strong></span>
tesseract --<span style="color:#333333"><strong>list</strong></span>-langs
tesseract imagename outputbase [<span style="color:#333333"><strong>options</strong></span>...] [configfile...]
OCR option<span style="color:#bc6060">s:</span>
-<span style="color:#333333"><strong>l</strong></span> LANG[+LANG] Specify <span style="color:#333333"><strong>language</strong></span>(s) used <span style="color:#333333"><strong>for</strong></span> OCR.
NOTE: These <span style="color:#333333"><strong>options</strong></span> must occur before any configfile.
Single option<span style="color:#bc6060">s:</span>
--<span style="color:#333333"><strong>help</strong></span> Show this <span style="color:#333333"><strong>help</strong></span> message.
--<span style="color:#333333"><strong>help</strong></span>-extra Show extra <span style="color:#333333"><strong>help</strong></span> <span style="color:#333333"><strong>for</strong></span> advanced users.
--<span style="color:#333333"><strong>version</strong></span> Show <span style="color:#333333"><strong>version</strong></span> information.
--<span style="color:#333333"><strong>list</strong></span>-langs List available languages <span style="color:#333333"><strong>for</strong></span> tesseract engine.
</span></span></span></span>
2. 安装
Python tesseract: GitHub - madmaze/pytesseract: A Python wrapper for Google Tesseract
pip安装pytesseract
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6"><span style="color:#333333"><strong>pip</strong></span> install pytesseract
</span></span></span></span>
另外需要安装一下Pillow库,用于图像处理。
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6"><span style="color:#333333"><strong>pip</strong></span> install Pillow
</span></span></span></span>
文字识别小例子
先准备一张包含英文字符的图片,下面的代码实现提取图片中的中文和英文字符,并识别为字符串:
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6"><span style="color:#333333"><strong>import</strong></span> pytesseract
<span style="color:#333333"><strong>try</strong></span>:
<span style="color:#333333"><strong>from</strong></span> PIL <span style="color:#333333"><strong>import</strong></span> Image
<span style="color:#333333"><strong>except</strong></span> ImportError:
<span style="color:#333333"><strong>import</strong></span> Image
<span style="color:#888888"># 列出支持的语言</span>
print(pytesseract.get_languages(config=<span style="color:#880000">''</span>))
print(pytesseract.image_to_string(Image.open(<span style="color:#880000">'test.png'</span>), lang=<span style="color:#880000">'chi_sim+eng'</span>))
</span></span></span></span>
识别下面图片中的文字(test.png):
![](https://img-blog.csdnimg.cn/img_convert/9631c29aba20f5c2d636a3985536b580.png)
执行结果:
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">[<span style="color:#bc6060">'chi_sim</span>', <span style="color:#bc6060">'eng</span>', <span style="color:#bc6060">'osd</span>']
拳 列出支持的语言
print(<span style="color:#333333"><strong>pytesseract.get_languages</strong></span> (<span style="color:#333333"><strong>config=”</strong></span>))
print(<span style="color:#333333"><strong>pytesseract.image_to_string</strong></span>(<span style="color:#333333"><strong>Image.open</strong></span>(<span style="color:#bc6060">'test.png</span>'), lang=<span style="color:#bc6060">'chi_sim+eng</span>'))
</span></span></span></span>
获取文字位置信息
image_to_boxes()
方法返回识别到的字符及字符边框信息。 返回单词及单词位置信息。下面来看看这两种方法的执行效果,识别下图中的中文字符:image_to_data()
![](https://img-blog.csdnimg.cn/img_convert/fbd3b6c8f3aa5e0373395bf7e618f6ff.png)
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">img = Image.<span style="color:#333333"><strong>open</strong></span>(<span style="color:#880000">'testimg2.png'</span>)
<span style="color:#333333"><strong>print</strong></span>(pytesseract.image_to_boxes(img, output_type=Output.STRING, lang=<span style="color:#880000">'chi_sim'</span>))
<span style="color:#333333"><strong>print</strong></span>(<span style="color:#880000">"#"</span>*<span style="color:#880000">30</span>)
<span style="color:#333333"><strong>print</strong></span>(pytesseract.image_to_data(img, output_type=Output.STRING, lang=<span style="color:#880000">'chi_sim'</span>))
</span></span></span></span>
执行结果:
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">生 63 211 80 227 0
存 81 209 118 227 0
是 122 211 139 226 0
文 126 200 154 231 0
明 142 210 157 226 0
的 162 209 197 227 0
第 200 217 218 219 0
一 221 209 236 226 0
需 217 200 253 231 0
要 239 209 259 226 0
。 260 211 266 216 0
猜 325 64 364 82 0
疑 364 64 481 82 0
链 373 54 393 86 0
和 383 54 403 86 0
技 403 54 435 86 0
术 419 54 451 86 0
爆 441 54 477 86 0
炸 469 54 485 86 0
##############################
level page_num block_num par_num line_num word_num <span style="color:#333333"><strong>left</strong></span> <span style="color:#333333"><strong>top</strong></span> <span style="color:#333333"><strong>width</strong></span> <span style="color:#333333"><strong>height</strong></span> conf text
1 1 0 0 0 0 0 0 566 279 -1
2 1 1 0 0 0 63 52 203 18 -1
3 1 1 1 0 0 63 52 203 18 -1
4 1 1 1 1 0 63 52 203 18 -1
5 1 1 1 1 1 63 52 55 18 96 生存
5 1 1 1 1 2 122 53 17 15 96 是
5 1 1 1 1 3 126 48 31 31 96 文明
5 1 1 1 1 4 162 52 35 18 96 的
5 1 1 1 1 5 200 60 18 2 91 第
5 1 1 1 1 6 221 53 15 17 93 一
5 1 1 1 1 7 217 48 42 31 93 需要
5 1 1 1 1 8 260 63 6 5 91 。
2 1 2 0 0 0 325 197 156 18 -1
3 1 2 1 0 0 325 197 156 18 -1
4 1 2 1 1 0 325 197 156 18 -1
5 1 2 1 1 1 325 197 156 18 94 猜疑
5 1 2 1 1 2 373 193 20 32 77 链
5 1 2 1 1 3 383 193 20 32 92 和
5 1 2 1 1 4 403 193 48 32 96 技术
5 1 2 1 1 5 441 193 44 32 94 爆炸
</span></span></span></span>
根据 方法返回的位置信息,下面来标出识别出的词语位置。image_to_data()
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6"><span style="color:#333333"><strong>import</strong></span> numpy <span style="color:#333333"><strong>as</strong></span> np
<span style="color:#333333"><strong>import</strong></span> pytesseract
<span style="color:#333333"><strong>from</strong></span> pytesseract <span style="color:#333333"><strong>import</strong></span> Output
<span style="color:#333333"><strong>import</strong></span> cv2
<span style="color:#333333"><strong>try</strong></span>:
<span style="color:#333333"><strong>from</strong></span> PIL <span style="color:#333333"><strong>import</strong></span> Image
<span style="color:#333333"><strong>from</strong></span> PIL <span style="color:#333333"><strong>import</strong></span> ImageDraw
<span style="color:#333333"><strong>from</strong></span> PIL <span style="color:#333333"><strong>import</strong></span> ImageFont
<span style="color:#333333"><strong>except</strong></span> ImportError:
<span style="color:#333333"><strong>import</strong></span> Image
img = cv2.imread(<span style="color:#880000">'testimg2.png'</span>)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, <span style="color:#880000">0</span>, <span style="color:#880000">255</span>, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[<span style="color:#880000">1</span>]
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[<span style="color:#880000">0</span>] <span style="color:#333333"><strong>if</strong></span> len(cnts) == <span style="color:#880000">2</span> <span style="color:#333333"><strong>else</strong></span> cnts[<span style="color:#880000">1</span>]
width_list = []
<span style="color:#333333"><strong>for</strong></span> c <span style="color:#333333"><strong>in</strong></span> cnts:
_, _, w, _ = cv2.boundingRect(c)
width_list.append(w)
wm = np.median(width_list)
tess_text = pytesseract.image_to_data(img, output_type=Output.DICT, lang=<span style="color:#880000">'chi_sim'</span>)
<span style="color:#333333"><strong>for</strong></span> i <span style="color:#333333"><strong>in</strong></span> range(len(tess_text[<span style="color:#880000">'text'</span>])):
word_len = len(tess_text[<span style="color:#880000">'text'</span>][i])
<span style="color:#333333"><strong>if</strong></span> word_len > <span style="color:#880000">1</span>:
world_w = int(wm * word_len)
(x, y, w, h) = (tess_text[<span style="color:#880000">'left'</span>][i], tess_text[<span style="color:#880000">'top'</span>][i], tess_text[<span style="color:#880000">'width'</span>][i], tess_text[<span style="color:#880000">'height'</span>][i])
cv2.rectangle(img, (x, y), (x + world_w, y + h), (<span style="color:#880000">255</span>, <span style="color:#880000">0</span>, <span style="color:#880000">0</span>), <span style="color:#880000">1</span>)
im = Image.fromarray(img)
draw = ImageDraw.Draw(im)
font = ImageFont.truetype(font=<span style="color:#880000">"simsun.ttc"</span>, size=<span style="color:#880000">18</span>, encoding=<span style="color:#880000">"utf-8"</span>)
draw.text((x, y - <span style="color:#880000">20</span>), tess_text[<span style="color:#880000">'text'</span>][i], (<span style="color:#880000">255</span>, <span style="color:#880000">0</span>, <span style="color:#880000">0</span>), font=font)
img = cv2.cvtColor(np.array(im), cv2.COLOR_RGB2BGR)
cv2.imshow(<span style="color:#880000">"TextBoundingBoxes"</span>, img)
cv2.waitKey(<span style="color:#880000">0</span>)
</span></span></span></span>
执行结果:
![](https://img-blog.csdnimg.cn/img_convert/92101456649789e50acb49fa474168c5.png)
另外说明一下, 用于设置字体及编码格式,原因是 默认使用ISO-8859-1(latin-1)编码,中文需要使用UTF-8编码。Windows中,字体存放路径一般为 ,已经添加到了环境变量,直接写字体名称就可以了, 表示宋体。 ImageFont.truetype(font="simsun.ttc", size=18, encoding="utf-8")
draw.text()
C:\Windows\Fonts
simsun.ttc
如果不知道字体对应名称可以进入注册表查看:运行窗口或者命令行窗口输入 打开注册表,进入如下路径: ,可以查看对应字体文件名称。 regedit
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts
![](https://img-blog.csdnimg.cn/img_convert/5ac10a721c5ddb92df180ea572096c1c.png)
多语言识别
使用方法
图片中可能包含了多种语言,比如在上面的例子中,图片包含了中文和英文, 表示识别简体中文和英文。lang='chi_sim+eng'
简体中文chi_sim是在安装tesseract时勾选的, 方法列出了支持的语言,也可以在命令行窗口执行 查看支持的语言:get_languages()
tesseract --list-langs
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">$ tesseract --<span style="color:#333333"><strong>list</strong></span>-langs
<span style="color:#333333"><strong>List</strong></span> of available languages (<span style="color:#880000">3</span>):
chi_sim
eng
osd
</span></span></span></span>
除了使用 方式指定语言外,也可以使用 形式:lang='chi_sim+eng'
config='-l chi_sim+eng'
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">img = Image.open(<span style="color:#880000">'test.png'</span>)
config = <span style="color:#880000">r'-l chi_sim+eng --psm 6'</span>
print(pytesseract.image_to_string(img, config=config))
</span></span></span></span>
执行结果和前面一样。
训练数据
如果需要下载其它语言包,可以到这里Traineddata Files for Version 4.00 + | tessdoc下载。
Tesseract 提供了三种训练数据:
训练数据 | 训练模型 | 识别速度 | 正确率 |
---|
tessdata_fast | 断续器 | 最快 | 最低 |
tessdata_best | 断续器 | 最慢 | 最高 |
tessdata | 传统 + LSTM | 中等 | 略低于特斯数据 -最好 |
根据自己的需要下载需要的模型文件,将traineddata文件放在 目录(Tesseract安装目录)下就可以了。C:\Program Files\Tesseract-OCR\tessdata
tessdata_best可用来再训练字库,训练方法参考文档: How to use the tools provided to train Tesseract 4.00 | tessdoc 。
OCR选项
多语言识别中使用了 和 选项,tesseract还支持更多的OCR选项。-l
--psm
OCR选项:
<span style="color:#444444"><span style="background-color:#f6f6f6"><span style="color:#880000">--tessdata-dir PATH</span>
<span style="color:#880000">--user-words PATH</span>
<span style="color:#880000">--user-patterns PATH</span>
<span style="color:#880000">--dpi VALUE</span>
<span style="color:#880000">-l LANG[+LANG]</span>
<span style="color:#880000">-c VAR=VALUE</span>
<span style="color:#880000">--psm NUM</span>
<span style="color:#880000">--oem NUM</span>
</span></span>
在pytesseract中的使用方法是添加config参数:config='--psm 0 -c min_characters_to_try=5'
下面介绍一下psm和oem这两个选项。
图片分割模式(PSM)
tesseract有13种图片分割模式(页面分割模式,psm):
- 0 — 仅限方向和脚本检测 (OSD)。方向及语言检测(定向和脚本检测,OSD)
- 1 — 使用 OSD 自动分页。自动图片分割
- 2 — 自动分页,但没有 OSD 或 OCR。自动图片分割,没有OSD和OCR
- 3 — 全自动页面分割,但没有 OSD。(Default) 完全的自动图片分割,没有OSD
- 4 — 假定为大小可变的单列文本。假设有一列不同大小的文本
- 5 — 假定有一个垂直对齐的文本的统一块。假设有一个垂直对齐的文本块
- 6 — 假设只有一个统一的文本块。假设有一个对齐的文本块
- 7 — 将图像视为单个文本行。图片为单行文本
- 8 — 将图像视为单个单词。图片为单词
- 9 — 将图像视为圆圈中的单个单词。图片为圆形的单词
- 10 — 将图像视为单个字符。图片为单个字符
- 11 — 稀疏文本。以不特定顺序查找尽可能多的文本。稀疏文本。查找尽可能多的文本,没有特定的顺序。
- 12 — 带 OSD 的稀疏文本。OSD稀疏文本
- 13 — 原始行。将图像视为单个文本行,绕过特定于 Tesseract 的黑客攻击。原始行。将图像视为单个文本行。
OCR引擎模式(OEM)
有4种OCR引擎模式:
- 0 — 仅限旧版引擎。
- 1 — 仅限神经网络 LSTM 引擎。
- 2 — 传统 + LSTM 引擎。
- 3 — 默认值,基于可用内容。
方向及语言检测OSD
Tesseract支持方向及语言检测(Orientation and script detection,OSD) ,比如检测下面的图片:
![](https://img-blog.csdnimg.cn/img_convert/9d3b8e9e30a9596a33d8c9ab371494a4.png)
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">osd = pytesseract.image_to_osd(<span style="color:#880000">'osd-example.png'</span>,config=<span style="color:#880000">'--psm 0 -c min_characters_to_try=5'</span>)
<span style="color:#397300">print</span>(osd)
</span></span></span></span>
其中 表示设置最小字符数,默认为50。min_characters_to_try
执行结果:
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">Page <span style="color:#880000">number:</span> <span style="color:#880000">0</span>
Orientation <span style="color:#333333"><strong>in</strong></span> <span style="color:#880000">degrees:</span> <span style="color:#880000">90</span>
<span style="color:#880000">Rotate:</span> <span style="color:#880000">270</span>
Orientation <span style="color:#880000">confidence:</span> <span style="color:#880000">0.74</span>
<span style="color:#880000">Script:</span> Han
Script <span style="color:#880000">confidence:</span> <span style="color:#880000">0.83</span>
</span></span></span></span>
结果是旋转了270度,识别到的语言为中文Han。
提取数字
只提取下面图片中的数字:
![](https://img-blog.csdnimg.cn/img_convert/51ce2b29831e12c1d4908465c1dd2f5b.png)
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">img = Image.open(<span style="color:#880000">'number-example.png'</span>)
config = <span style="color:#880000">r'--oem 3 --psm 6 outputbase digits'</span>
osd = pytesseract.image_to_string(img, config=config)
print(osd)
</span></span></span></span>
执行结果:
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6"><span style="color:#880000">1200</span>-.<span style="color:#880000">41194</span>-.
<span style="color:#880000">4</span>-.
<span style="color:#880000">12000000</span>
<span style="color:#880000">11994933</span>.
-119940218
119932207
1199251
119915241
119907238
-119853209
1119450495
.-<span style="color:#880000">11941637</span>
</span></span></span></span>
字符白名单
只检测特定的字符:只检测数字
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">img = Image.open(<span style="color:#880000">'number-example.png'</span>)
config = <span style="color:#880000">r'-c tessedit_char_whitelist=0123456789 --psm 6'</span>
print(pytesseract.image_to_string(img, config=config))
</span></span></span></span>
执行结果:
发现识别精度比 方法更加准确。outputbase digits
字符黑名单
不检测数字:
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">img = Image.open(<span style="color:#880000">'number-example.png'</span>)
config = <span style="color:#880000">r'-c tessedit_char_blacklist=0123456789 --psm 6'</span>
print(pytesseract.image_to_string(img, config=config, lang=<span style="color:#880000">'chi_sim'</span>))
</span></span></span></span>
执行结果:
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">胶片很快冲出来了,他开始查看哪张值得放大洗成照片,
在第一张就发现了一件离奇的事。一个倒计时。倒计时从
小时开始,到现在还剩余 小时。
这张拍的是一个大商场外的一小片草地,他看到底片正中
有一行白色的东西,
细看是一排数字: : :
第二张底片上也有数字: l]: : -。
第三张: <span style="color:#880000">l :</span> : lg,
第四张: : : ,
第五张: ] : : l;
第六张: : : l,
第七张: <span style="color:#880000">l :</span> <span style="color:#880000">o :</span> g ;
第八张: <span style="color:#880000">lg :</span> : ;
第三十四张: : :
第三十六张,也是最后一张: : :
</span></span></span></span>
格式转换
pytesseract 支持将图片转换为PDF、HOCR以及ALTO XML格式。
<span style="color:#333333"><span style="background-color:#fefefe"><span style="color:#444444"><span style="background-color:#f6f6f6">pdf = pytesseract.image_to_pdf_or_hocr(<span style="color:#880000">'testimg2.png'</span>, extension=<span style="color:#880000">'pdf'</span>)
<span style="color:#333333"><strong>with</strong></span> open(<span style="color:#880000">'test.pdf'</span>, <span style="color:#880000">'w+b'</span>) <span style="color:#333333"><strong>as</strong></span> f:
f.<span style="color:#333333"><strong>write</strong></span>(pdf)
hocr = pytesseract.image_to_pdf_or_hocr(<span style="color:#880000">'testimg2.png'</span>, extension=<span style="color:#880000">'hocr'</span>)
xml = pytesseract.image_to_alto_xml(<span style="color:#880000">'testimg2.png'</span>)
</span></span></span></span>
--完--
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)