我国电力行业发展迅速,电表作为测电设备经历了普通电表、预付费电表和智能电表三个阶段的发展。虽然智能电表具有通信功能,但环境和设备使得智能电表具有不稳定性,非智能电表仍然无法实现自动采集。采集到的大量电表图片如果能够借助人工智能技术批量检测和识别,将会大幅提升效率和精度。
在本系列项目中,使用Paddle工具库实现一个OCR垂类场景。原始数据集是一系列电度表的照片,类型较多,需要完成电表的读数识别,对于有编号的电表,还要完成其编号的识别。
使用飞桨文字识别开发套件PaddleOCR,完成PP-OCR模型完成微调与优化,由于其检测部分基于DB的分割方法实现,对于数据中的倾斜问题能够良好解决。PP-OCR模型经过大量实验,其泛化性也足以支撑复杂垂类场景下的效果。
主线篇
番外篇
# 克隆项目
!git clone https://gitee.com/paddlepaddle/PaddleOCR.git
# 安装ppocr
!pip install fasttext==0.8.3
!pip install paddleocr --no-deps -r requirements.txt
%cd PaddleOCR/
(注:数据集稍后公开,尽请期待)
首先,我们来简单看一下数据集的情况。总的来说,这个场景面临几个比较大的问题:
在数据标注工具上,使用PPOCRLabel作为实现半自动标注,内嵌PP-OCR模型,一键实现机器自动标注,且具有便捷的修改体验。支持四点框、矩形框标注模式,导出格式可直接用于PaddleOCR训练。
标注文件格式如下所示:
" 图像文件名 json.dumps编码的图像标注信息"
ch4_test_images/img_61.jpg [{"transcription": "MASA", "points": [[310, 104], [416, 141], [418, 216], [312, 179]]}, {...}]
PaddleOCR包含丰富的文本检测、文本识别以及端到端算法。在PaddleOCR的全景图中,我们可以看到PaddleOCR支持的文本检测算法。
在标注数据的基础上,基于通用的文本检测算法finetune,我们就可以训练一个能将电表识别中的多余文本框自动去除,只留下目标的电表读数、编号的电表文本检测模型。
为节省训练时间,提供了一个效果不错的预训练模型以及配置文件,读者可以选择基于预训练模型finetune或是从头训练。
!pip install Polygon3 -i https://pypi.tuna.tsinghua.edu.cn/simple
!pip install lanms-nova
!pip install rapidfuzz
# 从头开始训练
!python tools/train.py -c configs/det/ch_PP-OCRv2/ch_PP-OCRv2_det_student.yml
通过上述代码训练好模型后,运行 tools/eval.py
, 指定配置文件和模型参数即可评估效果。
# 提供的预训练模型和配置文件
!tar -xvf ../my_exps.tar -C ./
# 查看提供的模型训练效果
!python tools/eval.py -c configs/det/ch_PP-OCRv2/ch_PP-OCRv2_det_student.yml -o Global.checkpoints="my_exps/det_dianbiao_size1600_copypaste/best_accuracy"
``
`
## 模型导出和串接
这里用了个比较取巧的方式,先将模型导出,然后把whl下预测用的检测模型用新训练的模型直接替换掉,就可以看到finetune后的检测效果了!
```python
# 模型导出
!python tools/export_model.py -c configs/det/ch_PP-OCRv2/ch_PP-OCRv2_det_student.yml -o Global.pretrained_model=./my_exps/det_dianbiao_size1600_copypaste/best_accuracy Global.save_inference_dir=./inference/det_db
from paddleocr import PaddleOCR, draw_ocr
# 模型路径下必须含有model和params文件
ocr = PaddleOCR(det_model_dir='./inference/det_db', use_angle_cls=True)
img_path = './M2021/test.jpg'
result = ocr.ocr(img_path, cls=True)
for line in result:
print(line)
# 显示结果
from PIL import Image
image = Image.open(img_path).convert('RGB')
boxes = [line[0] for line in result]
txts = [line[1][0] for line in result]
scores = [line[1][1] for line in result]
im_show = draw_ocr(image, boxes, txts, scores)
im_show = Image.fromarray(im_show)
im_show.save('result.jpg')
如果您想要进一步优化识别结果,可以通过以下两种思路:
重新训练识别模型
通过后处理解决,包括调整阈值、将非数字内容处理掉等。
如果您对本项目以及PaddleOCR应用有更深入的需求,欢迎扫码加群交流:
工业场景中对于文字的检测也可以算是目标的一种,因此我们也探索了通用目标检测的方法在该场景中的效果。
整体方案的流程首先将PPOCRLabel的标注文件格式转换为VOC格式,然后训练YOLOv3模型进行文本检测。 具体代码可参考 PPOCR+PPDET电表读数和编号识别。
最终预测效果如下:
(预测结果图片)
从上面的预测结果看来,我们发现直接用矩形框检测也存在问题。由于输入图片会存在歪斜,导致矩形框可能会框住多余的文字,进而影响文字识别效果。