寒假期间在bilibili中找到一个学python的视频,现将从中学到的几个工程搬运到本论坛中以供广大博友学习借鉴。原版视频是 Murtaza Hassan讲解的,讲的是英语而且没有字幕,博主的英语很烂,英语四级都是大四六月份才过的,所以看起来非常痛苦😫。所以海绵将视频中的内容在博客中复现,博友们不用观看视频,仅仅通过阅读本系列博客即可学到文本检测的内容。
0 废话不多说,先看一下效果图
经过处理后,可以明显地看出图片上的文字均被识别并显示在原文字上方。程序代码不长,不到100行就可以实现,可以说是非常简单啦。有些人可能要问了,为什么能使用这么短的代码实现对文字的识别,这就不得不介绍本文标题中的Tesseract了。Tesseract是一款可以识别100多种语言的开源软件,可以训练自己的文字识别模型、识别各国语言的文字结果输出为txt等格式,不但可以使用在windows、ios等系统,还可以在ubuntu系统中使用,说明树莓派等微型实时操作系统也可以借助该软件实现OCR文字识别。
以下是一篇在Ubuntu18.04安装Tesseract库的博客,需要的请跳转。
开源OCR识别库-Tesseract介绍 - 平凡的编程者 - 博客园 (cnblogs.com)
1 准备阶段
(1)windows系统安装Tesseract软件
Tesseract的安装不算难,我是参考下方的博客安装完成的,步骤很少一般不会出错。记住软件安装位置,我的安装位置是D:\\program file\\setup\\OCR。
Tesseract-OCR5.0软件安装和语言包安装(Windows系统)_桔子code 的博客-CSDN博客
在python环境里运行“import pytesseract”没有显示错误即为安装成功
(2)待测图片设计
我是使用PPT制作的,打开PPT后插入三个输入框,然后键入文字。由于博主没有安装Tesseract的汉语库,所以文字为英语和数字。图片如下图所示,为了检验Tesseract-OCR的鲁棒性,图片中的3行文字采用了不同的字体格式和大小,其他的颜色也可以。
2 程序代码讲解
(1)pytesseract库介绍
erpytesseract提供以下14个识别api,可以满足大多数用户的需求。视频中使用到的有image_to_string、image_to_boxes、image_to_data等,下面会具体讲解。
# flake8: noqa: F401 from .pytesseract import ALTONotSupported from .pytesseract import get_languages #输出识别出文字的语言 from .pytesseract import get_tesseract_version from .pytesseract import image_to_alto_xml from .pytesseract import image_to_boxes from .pytesseract import image_to_data from .pytesseract import image_to_osd from .pytesseract import image_to_pdf_or_hocr from .pytesseract import image_to_string from .pytesseract import Output from .pytesseract import run_and_get_output from .pytesseract import TesseractError from .pytesseract import TesseractNotFoundError from .pytesseract import TSVNotSupported __version__ = '0.3.8'
(2)关键API的使用
①image_to_string
从名字上可以推出是将图片转换为字符串形式,具体是转换结果是什么呢,我们借助下方代码理解。
测试程序如下图所示,前两行导入必要库cv2和pytesseract;第四行第五行加载Tesseract软件和待检测图片,路径中的'\'为转义标识符不可单独使用,可使用'\\'或'/'代替;接下来是将图片转化为灰度图,几乎所有对图片识别方面的程序都会有这一步,从三通道图片降维到两通道图片,减少了图片处理时间但不影响结果;第六行调用image_to_string函数处理灰度化图片;后两行输出image_to_string的结果和变量类型。
import cv2 import pytesseract pytesseract.pytesseract.tesseract_cmd = "D:\\program file\\setup\\OCR\\tesseract.exe" img = cv2.imread('picture_mqa\\test.bmp') img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) string = pytesseract.image_to_string(img) print(string) print (type(string))
输出结果如下图所示,输出的结果是将图片上的文字按行输出,变量类型为字符串。
②image_to_boxes
从名字上很难理解是将图片转换为什么格式,boxes 是box的复数形式,有箱子、盒子等翻译,我的理解是将图片输出为一组打包的数据格式,实际结果是如何咱们往下看。
测试程序依然是8行代码,仅仅是①中代码部分的string改为boxes。
import cv2 import pytesseract pytesseract.pytesseract.tesseract_cmd = "D:\\program file\\setup\\OCR\\tesseract.exe" img = cv2.imread('picture_mqa\\test6.bmp') img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) boxes = pytesseract.image_to_boxes(img) print (boxes) print (type(boxes))
结果如下图所示,很长本来想截图的,一页都放不下。image_to_boxes将每一个字符都单独一行输出,每一行有6个元素,第一个为识别到的字符,后面4个元素像是该字符的坐标(具体是不是,下篇博客介绍,这里你就把它们当成坐标就行),第六个元素都是0(盲猜是判断是否存在字符)。输出的变量依旧是字符串类型。
runfile('G:/spyder_project/0.1 OCR_detect.py', wdir='G:/spyder_project') S 211 486 329 580 0 p 331 429 407 565 0 o 422 480 480 563 0 n 498 485 596 559 0 g 601 440 681 568 0 e 701 479 753 570 0 ' 770 545 794 586 0 s 797 485 865 566 0 T 917 482 1031 579 0 e 1024 479 1077 570 0 s 1081 485 1149 566 0 t 1153 486 1218 589 0 O 314 250 348 288 0 C 354 250 382 288 0 R 388 251 411 287 0 d 430 250 454 288 0 e 445 250 469 288 0 t 460 250 482 278 0 e 485 250 526 283 0 c 515 250 539 288 0 t 530 250 567 283 0 E 587 251 607 287 0 n 612 251 633 278 0 g 639 241 663 278 0 l 671 251 674 288 0 i 683 251 686 288 0 s 691 250 710 278 0 h 715 251 736 288 0 w 755 251 790 277 0 o 793 250 818 278 0 r 824 251 837 278 0 d 840 250 864 288 0 s 869 250 887 278 0 & 906 251 941 287 0 n 960 251 981 278 0 u 989 250 1010 277 0 m 1018 251 1054 278 0 b 1062 250 1085 288 0 e 1075 250 1099 288 0 r 1090 250 1113 278 0 s 1118 250 1152 278 0 1 515 102 529 133 0 2 549 102 570 133 0 3 587 102 606 133 0 4 622 102 645 133 0 5 661 102 680 133 0 6 697 102 719 133 0 7 734 102 755 133 0 8 770 102 792 133 0 9 807 102 829 133 0 1 847 102 860 133 0 0 869 102 891 133 0 1 890 102 916 133 0 1 909 102 947 133 0 <class 'str'>
③image_to_data
data的翻译是数据,将图片转换为数据是什么意思呢。前两个API从某种意义上说也是将图片转换为数据,又为何要单独出一个image_to_data函数呢,让我们往下看。
测试程序依然是8行代码,仅仅是①中代码部分的string改为data。
import cv2 import pytesseract pytesseract.pytesseract.tesseract_cmd = "D:\\program file\\setup\\OCR\\tesseract.exe" img = cv2.imread('picture_mqa\\test6.bmp') img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) data = pytesseract.image_to_data(img) print (data) print (type(data))
结果如下图所示,image_to_data的输出结果像是表格形式,输出变量的类型依旧是字符串。行数不算多,单列数比前两个函数的输出都多,有12行,而且首行为列名称这是上述两种API没有的。现在对首行元素解释:
level,当前项的层级;
page_num,当前项所属页,一般情况下,单张图片的内容均会被分在同一个页;
block_num ,当前项所属块,Tesseract会将图像分割为多个不同的block,block会出现1,2,3……等等值;
par_num,当前图像中文字的段落分类;
line_num,当前项所属行;
word_num,为同一行中当前项所属的单词序号;
left\ top\ width\ height,分别为当前项所在矩形区域的左上角坐标、宽度和高度;
conf,当前检测字符的置信度,表示项无文字,值为-1,若Tesseract认为当前区域有文字,则其值得范围为0~100;
text,即为当前项的文本,若无文字此项为空。
image_to_data的输出参数描述借用了以下博文。
pytesseract image_to_data检测并定位图片中的文字 - LiveZingy
其中,需要重点关注的参数是left\ top\ width\ height 、conf 和text,conf不为-1时表示识别项有文本,然后借助left\ top\ width\ height框出文本,最后在矩形框上方标注识别到的文本text。
runfile('G:/spyder_project/0.1 OCR_detect.py', wdir='G:/spyder_project') level page_num block_num par_num line_num word_num left top width height conf text 1 1 0 0 0 0 0 0 1465 737 -1 2 1 1 0 0 0 211 148 1007 160 -1 3 1 1 1 0 0 211 148 1007 160 -1 4 1 1 1 1 0 211 148 1007 160 -1 5 1 1 1 1 1 211 151 654 157 67.974083 Sponge's 5 1 1 1 1 2 917 148 301 110 95.559837 Test 2 1 2 0 0 0 314 449 838 47 -1 3 1 2 1 0 0 314 449 838 47 -1 4 1 2 1 1 0 314 449 838 47 -1 5 1 2 1 1 1 314 449 97 38 96.262711 OCR 5 1 2 1 1 2 430 449 137 38 96.262711 detect 5 1 2 1 1 3 587 449 149 47 96.666985 English 5 1 2 1 1 4 755 449 132 38 93.289680 words 5 1 2 1 1 5 906 450 35 36 92.383614 & 5 1 2 1 1 6 960 449 192 38 96.667770 numbers 2 1 3 0 0 0 515 604 432 31 -1 3 1 3 1 0 0 515 604 432 31 -1 4 1 3 1 1 0 515 604 432 31 -1 5 1 3 1 1 1 515 604 432 31 95.548973 1234567891011 <class 'str'>
未完待续,下一篇讲解通过本将讲解的三个API实现在原图上框出文本并标注的步骤。
吃水不忘挖井人,以下是bilibil中的学习视频链接和视频讲解人的github链接,感谢🙇
ccc终于有人把OpenCV讲清楚了,2022B站最好的OpenCV从入门到实战 全套课程(附带课程课件资料+课件笔记)_哔哩哔哩_bilibili