点击左上方蓝字关注我们
【飞桨开发者说】张明,视觉算法工程师,主要研究方向:目标检测、人脸检测、图像分类。
小张是一名研二的学生,专业课学的一塌糊涂,马上要考试了他准备突击一下。于是向比他高一届的师姐求教,问有没有内部资料。师姐看了看她会心一笑,马上发给他个压缩包。小张打开压缩包,发现里面是一张张整理好的图片资料,这显然是师姐拿手机在之前的课堂上偷偷拍的图片呀。小张心里美滋滋,不过他并不满足,就问师姐有没有电子档的呢,图片真的不好修改。师姐却撅着嘴,用手指在小张脑袋上敲了下说道:“有图片版的就不错啦,很多人想要还没有呢。”
小张忽然想到前几天飞桨公众号上推送的一篇文章,马上找到了一个开源软件(https://github.com/zhangming8/Dango-ocr),根据提示很快把图片中的文本资料导出为电子档了。小张小心翼翼地把电子档发给了暗恋已久的小红同学,小红收到后对小张竖起了大拇指。小张看到后偷偷地笑了。而此刻师姐也偷偷瞟了小张一眼。
小张想着这个工具还有点作用啊,自己要好好研究一下。他了解到这属于OCR文字识别技术,OCR实现了对图片中的文字进行提取、识别。这个软件是在飞桨开源的PaddleOCR文字识别套件基础上开发的,同时还发现这个工具还有这些功能:
支持汉语, 日语, 英语, 韩语, 德语, 法语的文字识别
支持截图, 加载本地图片进行识别。还可以自动截屏并进行识别
支持识别结果的可视化, 可以手动修正识别结果, 并导出文件(.docx, .txt)及对应图片
支持翻译为汉语
支持文字发音
小张越研究越感兴趣,想更加深入地分析实现的原理,他根据软件里面的信息很快找到了作者。
OCR算法
根据作者的介绍小张了解到,整个OCR文字识别算法主要包括两部分:文字检测算法,文字识别算法。不过也有一些end to end的OCR算法。一般来说训练一个文字检测的数据量和训练识别的数据量是不一样的,文字识别需要更多的数据,所以端到端的文字算法需要更多的数据量,目前先检测后识别还是主流方法。
文字检测算法
通过阅读作者推荐的几篇论文,小张发现,文字检测算法可以分为:基于分割的方式(如DBNet、PSENet)和基于回归的方式(如SegLink、RRPN)。不过文字检测也属于目标检测中的一个分支,也可以直接拿目前的目标检测模型用来做文字检测,只是效果可能不太好。所以也可以根据目标检测的方法划分为anchor-free类型(如CornerNet、CenterNet)和anchor-based类型(如SSD、YOLOv3),不过目前大家还是按照前者划分。目前目标检测anchor-free的方法比较流行,其中CenterNet由于结构简单被大家所熟知。同样地,在文字检测中,DBNet也是一个很整洁的基于分割的文字检测模型,也是PaddleOCR主要推荐的。所以这个项目中的文字检测采用DBNet。
小张读了一下DBNet的论文(https://arxiv.org/pdf/1911.08947.pdf),简单进行了总结。下图为整个DBNet的网络结构,输入的图片首先经过ResNet骨干网络分别下采样2倍、4倍、8倍、16倍、32倍,之后借用特征金字塔FPN的思想抽取了下采样为4、8、16、32的feature map进行特征融合,统一上采样为原图尺寸的1/4后并进行拼接得到feature map,然后基于此feature map预测出2个分支,probability图和threshold图。最后通过后处理得到文字位置。
小张想了一下,文字检测有了,后面用什么识别呢。又进一步地研究发现,文字识别算法采用的是PaddleOCR推荐的CRNN(https://arxiv.org/abs/1507.05717)。他看了下论文,下图为CRNN的网络结构。整个网络分为三个阶段,首先输入的图片经过骨干网络卷积层得到feature map,之后经过双向LSTM也就是图片中的Recurrent层进一步抽取特征,最后经过Transcription预测序列结果。
OCR算法服务
看到这里,小张对OCR算法有个整体的了解啦。他想着理论有了,怎么实践呢?作者告诉他,可以自己搭一个OCR识别服务加深理解。
小张发现,其实PaddleHub里面有自带的服务部署工具,但本软件使用的模型较多,包括了汉语、汉语高精度、日语、韩语、德语、法语识别模型,所以作者这里使用flask自己搭建的服务(OCR服务地址:https://github.com/zhangming8/ocr_algo_server)。
小张发现作者使用的模型挺重,如果直接在自己没有GPU的破电脑上跑,运行速度还是较慢的。作者表示后续也会考虑轻量化模型,支持在本地的CPU机器上运行,但目前推荐在有GPU的电脑上起服务。当然也可以直接下载作者已经打包好的软件,在使用的时候会调用他搭好的OCR服务。
小张看了一下代码结构,如下图所示。通过阅读代码发现,ppocr文件夹里面包括了模型的定义、前处理和后处理,主要来自PaddleOCR。
1. 配置文件
小张首先发现config.py为配置文件,里面包括了模型路径及后处理参数设置。下面的代码为配置文件部分参数,里面有DBnet的检测模型,RCNN日语、英语、韩语、汉语、汉语高精度、法语、德语的识别模型。需要修改里面的检测(det_model_dir)和识别模型(rec_model_dir)路径。他还发现,所有语言共用一个检测模型,每个语言有一个自己的识别模型,目前所有模型都采用的是PaddleOCR公开模型。
共用的检测模型:
det_model_dir = “./inference/det_db/ch_ppocr_server_v1.1_det_infer/”
日语、英语、韩语、汉语、汉语高精度、法语、德语的识别模型:
self.rec_model_dir = "./inference/rec_crnn/japan_ppocr_mobile_v1.1_rec_infer/"
self.rec_model_dir = "./inference/rec_crnn/en_ppocr_mobile_v1.1_rec_infer/"
self.rec_model_dir = "./inference/rec_crnn/korean_ppocr_mobile_v1.1_rec_infer/"
self.rec_model_dir = "./inference/rec_crnn/ch_ppocr_mobile_v1.1_rec_infer/"
self.rec_model_dir = "./inference/rec_crnn/ch_ppocr_server_v1.1_rec_infer/"
self.rec_model_dir = "./inference/rec_crnn/french_ppocr_mobile_v1.1_rec_infer/"
self.rec_model_dir = “./inference/rec_crnn/german_ppocr_mobile_v1.1_rec_infer/“
2. 服务入口
ocr_server.py是服务的主文件,下面的do_work函数对模型进行了初始化。ocr_server包括了接收base64格式的图片,调用ocr识别算法,返回结果。
def do_work(gpu, port):
global logger, g_port, ocr
try:
os.environ["CUDA_VISIBLE_DEVICES"] = "{}".format(gpu)
logger = logger_.get_logger("./log/ocr_{}.log".format(port))
g_port = port
logger.info("===>>> 初始化模型到gpu:{}, port: {}".format(gpu, port))
ocr = OCR(config, logger, language_list)
logger.info("==>> 启动成功")
app.run(host=config.host, port=port, threaded=True)
except BaseException as e:
logger.error('错误,启动flask异常{}'.format(e))
logger.info(traceback.format_exc())
3. 启动服务
小张执行了一下prod_deploy.sh发现可以启动服务。开始了解里面的启动命令,启动的时候一个检测模型,后面并联多个不同的语言识别模型。下面的代码中reco_language为文字检测后面跟的识别模型,模型之间用英文逗号“,”分割。所以下面的reco_language表示一个模型后面并联了汉语、日语、英语、韩语、汉语高精度、法语、德语的识别模型。port=8811可以设置服务的端口。
reco_language="ch,japan,en,korean,ch_h,french,german"
port="8811"
gpu=0
ps aux |grep "ocr_server_${port}_${reco_language}" |awk -F ' ' '{print $2}' |xargs -i kill -9 {}
nohup python ocr_server.py --gpu ${gpu} --port ${port} --rec ${reco_language} >/dev/null 2>&1 &
4. 测试服务
小张想着我怎么知道服务有没有启动成功呢?作者告诉他,启动服务后会自动创建log文件夹,会保存相关请求的日志,便于调试。test.py可以向服务端口请求demo文件夹中的图片,主要用于进行测试服务有没有错误。识别结果会保存在demo_result文件夹中,请求方式可以参考代码。小张试着执行了一下test.py发现真的成功了。下面是请求成功后保存的结果。识别的置信度、结果画在了文字上面。
这个是汉语识别结果:
汉语+英语识别:
这个是日语识别结果:
这个是英语识别结果:
对于其他语言的小张也找图进行一一测试。
软件部分
到这里小张已经有了一定的理论基础及核心的OCR算法服务,就差一个界面了。所以他又看了下作者的界面部分代码(项目地址为https://github.com/zhangming8/Dango-ocr)他发现界面部分采用Pyqt5进行开发,这个界面也参考了其他开源项目,最后的“参考”部分里面有。小张看到代码结构如下图。config文件夹包括了软件的默认配置。src文件夹包括了主要的源码。
同样地,小张发现configs.py为配置文件。在执行前需要修改”configs.py”中的ocr_request_url为上一步搭好的服务地址。
如:
ocr_request_url = “http://0.0.0.0:8811/dango/algo/ocr/server"
另外,main.py 为程序的入口,整个软件由不同部件组成,小张看到里面有挺多注释的,他计划后面研究一下具体的细节,今天暂时跳过这里。
小张又开始思考,执行main.py可以运行软件,但是之前我是双击一个文件名为”DangoOCR.exe”启动的呀。作者是怎么把这些脚本变成可执行文件的?
他又发现项目里面有个deploy文件,看了下里面的内容后恍然大悟,原来作者是用pyinstaller打包成的可执行文件。deploy.sh为Ubuntu下的打包,deploy.bat为Windows下的打包。由于Mac下界面和Windows不太一样,作者单独拉了一个“MacOS”分支,参考里面的deploy.sh进行打包。
小张的电脑是Windows系统,之前已经使用过了。这次他准备试一下MacOS,于是他把师姐Mac笔记本借了过来。他下载了作者打包好的软件并找到DangoOCR文件,根据下图的提示,点击右键->打开方式->终端(Windows和Ubuntu系统可以直接双击执行)发现可以执行。不过师姐的电脑系统是MacOS 10.13,小张还不确定其他版本的系统有没有问题。
此时,小张看到了下面的初始界面。
除了汉语外,这个软件还支持其他语种的文字识别,需要点击“设置”,设置一下“待识别的语言类型”。
小张要识别的是汉语,所以没有切换语言。他在师姐的电脑桌面上发现了一张师姐漂亮的自拍图片,不过由于里面没有文字小张并没有使用,而是在桌面上找了一张护发素的图片,准备拿这个做测试。他点击第一个“截屏按钮“,截取了这张图片发现很快返回了识别结果。
小张想如果我不想截屏呢?他还发现点击第3个”文件夹按钮“,导入图片后也可以显示结果,原来也支持导入本地的图片进行识别呀。
小张在使用的过程中发现,文字识别准确率不一定是100%。那可不可以人工修正呢?后来他发现如果在“设置”界面勾选了“可视化识别结果”,那么就可以把识别结果显示出来,如果识别有错误可以进行修改,修改后还能导出为txt/docx呢。
小张测试了一下,中文识别的挺不错,那其他语言能用嘛?他想测试一下英语识别效果,所以设置了待识别语言为英语。他在PaddleOCR首页保存了一张图,然后导入到软件中马上得到识别结果啦。他又开始思考,自己的英语水平很菜,很多单词都不会发音,这可怎么办。咦,第五个按钮有个“音乐”图标,莫非,可以播放?抱着试试看的态度点击了它,然后一句流利的发音出现在耳边。
到目前为止小张还不满足,他想把外文翻译为中文。经过琢磨之后,他点开设置界面,勾选了设置界面的”是否翻译为汉语“。当他再次识别刚刚的那个图片的时候,下面果然出现了翻译后的结果。
小张想,这玩意儿竟然还支持翻译为中文。他忽然灵光一闪,立即把“待识别的语言类型”设置为日语。并把浏览器地址栏的github中的git替换为p**n,按下了回车。而这一幕恰好被刚刚路过的大师兄发现了。。。
参考链接:
本项目:
https://github.com/zhangming8/Dango-ocr
OCR服务:
https://github.com/zhangming8/ocr_algo_server
界面代码:
https://github.com/PantsuDango/Dango-Translator
检测DBNet:
https://arxiv.org/pdf/1911.08947.pdf
识别CRNN:
https://arxiv.org/abs/1507.05717
如在使用过程中有问题,可微信扫描二维码加入PaddleOCR官方交流群,获得更高效的问题答疑,并与各行各业开发者充分交流。
如果您想详细了解更多飞桨的相关内容,请参阅以下文档。
·飞桨官网地址·
https://www.paddlepaddle.org.cn/
·飞桨开源框架项目地址·
GitHub: https://github.com/PaddlePaddle/Paddle
Gitee: https://gitee.com/paddlepaddle/Paddle
·PaddleOCR项目&文档地址·
https://github.com/PaddlePaddle/PaddleOCR
飞桨(PaddlePaddle)以百度多年的深度学习技术研究和业务应用为基础,是中国首个开源开放、技术领先、功能完备的产业级深度学习平台,包括飞桨开源平台和飞桨企业版。飞桨开源平台包含核心框架、基础模型库、端到端开发套件与工具组件,持续开源核心能力,为产业、学术、科研创新提供基础底座。飞桨企业版基于飞桨开源平台,针对企业级需求增强了相应特性,包含零门槛AI开发平台EasyDL和全功能AI开发平台BML。EasyDL主要面向中小企业,提供零门槛、预置丰富网络和模型、便捷高效的开发平台;BML是为大型企业提供的功能全面、可灵活定制和被深度集成的开发平台。
END