赞
踩
在之前的电表系列项目开展过程中,用户提出了这样一个需求:
给一批图片,希望有一个前端操作界面,应用训练的电表检测识别模型,实现批量预测待识别图片,并将识别后的电表编号、电表读数、文件名匹配,以表格形式导出。
基于这个命题,之前AI达人训练营的几位同学各显身手,实现了多种Windows端部署方案:
(众人拾柴——应用篇)
应该说,单独做部署这件事,上面的几位同学的解决方案对于Windows端有相关需求的用户已经绰绰有余了。
而在本文中,我们试图进一步挖掘部署方案的其它潜力……
(主线篇)
在实际业务过程中,我们会发现电表检测识别效果其实比较一般,连带着部署模型应用的时候,数据的矫正量其实一点也不少。
原因是数据量不够!因为demo的示例模型只是基于几百张标注图片训练的,在个别没训练到的场景上,表现捉襟见肘。
比如下面这张图,检测框就一个都没能识别出来(训练的图片多是单电表):
要使电表检测的精度进一步提高,除了在网络结构上下功夫(如:鸟枪换炮!基于PP-OCRv3的电表检测识别),最终还是逃不了下笨功夫——标注数据。
因为,众所周知,深度学习的最大瓶颈就是数据,企业落地深度学习技术的最大难题就是——没【标注】数据!
如果继续刨根究底,根本原因就变成了——没人!对于很多传统企业,压根不会有数据标注这个岗位,而这些企业可能由于各种经费短缺或数据敏感的原因,又不能把数据标注任务进行外包,于是整个技术应用就陷入了死循环。
我们知道,电力行业就是典型的【传统】行业之一,虽然笔者不在这个行业,但是大胆猜测,很多相关企业应该是没有专职的数据标注人员的。所以,电表检测识别模型的补充数据谁来标呢?
本文就提出一个【欠打】的解决方案——让要汇总导出抄表数据的业务员们标数据!
换句话说,就是将数据标注和用户【批量预测待识别图片,并将识别后的电表编号、电表读数、文件名匹配,以表格形式导出】的需求相结合,把两件事合并成一件事做,减少重复劳动,让业务人员在完成本职工作的同时,顺便帮企业把数据标注的活一起干了。
实现效果如下:
PPOCRLabel界面改造效果
导出识别文件示例
PPOCRLabel是一款适用于OCR领域的半自动化图形标注工具,内置PP-OCR模型对数据自动标注和重新识别。使用Python3和PyQT5编写,支持矩形框标注、表格标注、不规则文本标注、关键信息标注模式,导出格式可直接用于PaddleOCR检测和识别模型的训练。
本场景中,读者需要在本地环境安装PPOCRLabel,然后通过Python脚本运行PPOCRLabel
我们将会对PPOCRLabel文件有所更改(指定新的内置模型、增加按钮和函数),因此需要通过Python脚本运行。
首先需要git clone
PaddleOCR项目:
git clone https://gitee.com/paddlepaddle/PaddleOCR.git
然后切换到PPOCRLabel目录就可以启动应用了:
cd ./PPOCRLabel
python PPOCRLabel.py --lang ch
依据基于PP-OCRv3的电表检测识别项目完成训练后,可以这样导出模型:
python tools/export_model.py -c ../dianbiao/ch_PP-OCRv3_det_student.yml -o Global.pretrained_model=../dianbiao/train_log_model/det_ppocrv3_1600/best_accuracy Global.save_inference_dir=./inference/infer_det
python tools/export_model.py -c ../dianbiao/rec_en_ppocrv3.yml -o Global.pretrained_model=../dianbiao/en_PP-OCRv3_rec_train/best_accuracy Global.save_inference_dir=./inference/infer_rec
本项目直接提供了训练后导出的模型,读者可以解压后放到本地PPOCRLabel目录下:
在PPOCRLabel的文档中,关于自定义模型是这样说的:
自定义模型:如果用户想将内置模型更换为自己的推理模型,可根据自定义模型代码使用,通过修改
PPOCRLabel.py
中针对PaddleOCR类的实例化 实现,例如指定检测模型:self.ocr = PaddleOCR(det=True, cls=True, use_gpu=gpu, lang=lang)
,在det_model_dir
中传入 自己的模型即可。
具体地,就是在原项目的97行代码处,这样配置:
self.ocr = PaddleOCR(use_pdserving=False,
use_angle_cls=True,
det=True,
cls=True,
det_model_dir='inference/infer_det',
rec_model_dir='inference/infer_rec',
use_gpu=gpu,
lang=lang,
show_log=False)
增加导出按钮是改造点最多的地方,这时候,我们又要祭出“依样画葫芦”大法了。
在PPOCRLabel原项目中,其实已经提供了几种类似的导出功能:
PPOCRLabel支持三种导出方式:
自动导出:点击“文件 - 自动导出标记结果”后,用户每确认过一张图片,程序自动将标记结果写入Label.txt中。若未开启此选项,则检测到用户手动确认过5张图片后进行自动导出。 默认情况下自动导出功能为关闭状态
手动导出:点击“文件 - 导出标记结果”手动导出标记。
关闭应用程序导出
测试后我们会发现,【导出部分识别结果】这个功能和我们的需求相似度比较高。
所以,在动手写代码之前,我们首先需要仔细观察,这个作为“参照系”的导出按钮是如何实现的。
在PPOCRLabel中,最核心的无疑是PPOCRLabel.py
函数,而导出按钮的绝大多数设置正是来源于此。
saveRec = action(getStr('saveRec'), self.saveRecResult,
'', 'save', getStr('saveRec'), enabled=False)
552行,定义全部按钮动作
603行,增加动作到菜单
addActions(self.menus.file,
(opendir, open_dataset_dir, None, saveLabel, saveRec, exportJSON, self.autoSaveOption, None, resetAll, deleteImg,
quit))
self.actions.saveRec.setEnabled(True)
在PPOCRLabel中,界面按钮的GUI文字显示是通过遍历resources\strings\strings-en.properties
(英文)或resources\strings\strings-zh-CN.properties
(中文)这两个配置文件实现的。
saveRec=Export Recognition Result
或者
saveRec=导出识别结果
我们其实有两种操作,一种是新增一个按钮,这就需要参考上面的分析,与“参照系”一一对应在下面新增。
另一种改动量比较小的做法,比较适合“懒人”,直接复用原有的【导出识别结果】,然后把绑定的具体动作函数改成Excel导出就行。
本项目中,我们使用openpyxl
库来进行Excel文件的创建和写入,操作如下:
import openpyxl def saveExcel(self): if {} in [self.PPlabelpath, self.PPlabel, self.fileStatedict]: QMessageBox.information(self, "Information", "Check the image first") return excel_path = os.path.dirname(self.PPlabelpath) + '/export.xlsx' ques_img = [] data = openpyxl.Workbook() # 新建工作簿 data.create_sheet('Sheet1') # 添加页 table = data.get_sheet_by_name('Sheet1') # 获得指定名称页 table = data.active cell_list=[['图片名称','电表编号','电表读数']] for key in self.fileStatedict: idx = self.getImglabelidx(key) try: img = cv2.imread(key) index = '' metric = '' for i, label in enumerate(self.PPlabel[idx]): if label['difficult']: continue # 根据字符串长度规则,确定识别结果是编号还是电表读数 elif len(label['transcription']) > 8: index = label['transcription'] else: metric = label['transcription'] img_name = os.path.splitext(os.path.basename(idx))[0] # 把图片名、编号、电表读数拼接起来 rec_result = [img_name, index, metric] cell_list.append(rec_result) except Exception as e: ques_img.append(key) print("Can not read image ", e) for row in cell_list: table.append(row) data.save(excel_path) # 保存Excel文件 if ques_img: QMessageBox.information(self, "Information", "The following images can not be saved, please check the image path and labels.\n" + "".join(str(i) + '\n' for i in ques_img)) QMessageBox.information(self, "Information", "Finish")
改造后的PPOCRLabel
项目完整版已上传到本项目中,读者可以自行下载到本地,启动后就得到改造的标注工具了。
本项目以电表垂类场景为例,可同时实现数据标注和格式化数据批量导出,提供了一种根据自定义需求,在PPOCRLabel中,将OCR数据标注和Excel数据导出这类特定业务应用相结合的解决方案。
这下,再也不愁数据没人标注啦!
此文仅为搬运,原作链接:https://aistudio.baidu.com/aistudio/projectdetail/4355934?contributionType=1
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。