基于深度学习的多类别电表读数识别方案详解

基于深度学习的多类别电表读数识别方案详解

  • 多类别电表读数识别方案详解
    • 项目背景
      • 项目难点
      • 最终项目方案
      • 系列项目全集:
    • 安装说明
      • 环境要求
    • 数据集简介
    • 数据标注
    • 模型选型
      • 明确目标,开始下一步的操作
    • 检测模型训练
    • 模型评估与推理
    • 番外篇:基于目标检测方案的探索

多类别电表读数识别方案详解

项目背景

我国电力行业发展迅速,电表作为测电设备经历了普通电表、预付费电表和智能电表三个阶段的发展。虽然智能电表具有通信功能,但环境和设备使得智能电表具有不稳定性,非智能电表仍然无法实现自动采集。采集到的大量电表图片如果能够借助人工智能技术批量检测和识别,将会大幅提升效率和精度。

在本系列项目中,使用Paddle工具库实现一个OCR垂类场景。原始数据集是一系列电度表的照片,类型较多,需要完成电表的读数识别,对于有编号的电表,还要完成其编号的识别。
在这里插入图片描述

项目难点

  • 数据方面:电表种类多、数据少,拍摄角度多样且部分数据反光严重。
  • 电表数据没有开源数据集,如何从零标注数据应当选择何种标注软件能够最快速度构建数据集?
  • 在技术路线选择也面临多方面的问题,例如是通过文字检测来反向微调,还是通过目标检测从零训练?

最终项目方案

使用飞桨文字识别开发套件PaddleOCR,完成PP-OCR模型完成微调与优化,由于其检测部分基于DB的分割方法实现,对于数据中的倾斜问题能够良好解决。PP-OCR模型经过大量实验,其泛化性也足以支撑复杂垂类场景下的效果。

系列项目全集:

  • 主线篇

    • PPOCR:多类别电表读数识别
    • PPOCR:使用TextRender进行电表编号识别的finetune
    • 数据标注懒人包:PPOCRLabel极速增强版——以电表识别为例(二)
  • 番外篇

    • PPOCR+PPDET电表读数和编号检测

安装说明

环境要求

  • PaddlePaddle >= 2.1.0
  • 3.5 <= Python < 3.9
  • PaddleOCR >= 2.1
# 克隆项目
!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/

数据集简介

(注:数据集稍后公开,尽请期待)

首先,我们来简单看一下数据集的情况。总的来说,这个场景面临几个比较大的问题:

  • 电表类型较多,相比之下,现有数据量(500张)可能不够。
  • 照片角度倾斜较厉害,有些电表可能不具备正面拍照条件。
  • 反光严重,影响目标框定位和数字识别。
  • 表号是点阵数字,不易识别。
  • 对检测框精准度要求非常高。

数据标注

在数据标注工具上,使用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 Imageimage = 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')

如果您想要进一步优化识别结果,可以通过以下两种思路:

  1. 重新训练识别模型

    • 通过 导出识别数据 功能在PPOCRLabel中导出识别数据:包含已经裁切好的识别图片与label。
    • 如果真实数据量太小,使用Textrenderer、StyleText等造数据工具,制造合成数据(可能需要提供字体文件等)。
    • 将数据按照识别模型训练文档整理数据后启动训练,通过调整学习率、调整相应的合成与真实数据比例(保证每个batch中真实:合成=10:1左右)等操作优化识别模型。
  2. 通过后处理解决,包括调整阈值、将非数字内容处理掉等。

如果您对本项目以及PaddleOCR应用有更深入的需求,欢迎扫码加群交流:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

番外篇:基于目标检测方案的探索

工业场景中对于文字的检测也可以算是目标的一种,因此我们也探索了通用目标检测的方法在该场景中的效果。

整体方案的流程首先将PPOCRLabel的标注文件格式转换为VOC格式,然后训练YOLOv3模型进行文本检测。 具体代码可参考 PPOCR+PPDET电表读数和编号识别。

最终预测效果如下:

(预测结果图片)

从上面的预测结果看来,我们发现直接用矩形框检测也存在问题。由于输入图片会存在歪斜,导致矩形框可能会框住多余的文字,进而影响文字识别效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/622272.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3移动端适配

将vue3项目中的 px 单位&#xff0c;自动转换为rem 单位 可以看到这里会根据页面缩小放大变化 需要安装两个插件&#xff0c;看步骤 amfe-flexible --- 默认指向2.2.1版本 npm i -S amfe-flexiblepostcss-pxtorem --- 默认指向6.0.0版本 --save-dev 参数会把依赖包的版本信…

机器学习---lightGBM

1. lightGBM演进过程 AdaBoost是⼀种提升树的方法&#xff0c;和三个臭皮匠&#xff0c;赛过诸葛亮的道理⼀样。 AdaBoost两个问题&#xff1a; (1) 如何改变训练数据的权重或概率分布提高前⼀轮被弱分类器错误分类的样本的权重&#xff0c;降低前⼀ 轮被分对的权重 (2) 如何…

vue3、vue2文件导入事件

一、vue3写法 1、html部分 <el-buttontype"info"plainicon"Upload"click"handleImport"v-hasPermi"[system:user:import]">导入</el-button><!-- 导入对话框 --><el-dialog :title"upload.title" v-…

mysql进阶-索引基础

目录 1. 概念-索引是什么&#xff1f; 2. 索引的数据结构(索引模型) 2.1 二分查找&#xff1a; 2.2 二叉查找树&#xff08;BST Binary Search Tree&#xff09;&#xff1a; 2.3 平衡二叉树(AVL Tree Balanced binary search trees) 2.4 多路平衡查找树(B Tree Balanced…

推荐一款通过ssh连接linux服务的开源工具WindTerm

文章目录 前言WindTerm介绍WindTerm使用主密码和锁屏总结 前言 工作一入门便是游戏服务器开发&#xff0c;所以常常有连接Linux服务器的需求&#xff0c;之前用的最多的是Xshell&#xff0c;最近这个软件个人版只能免费使用一个月了&#xff0c;超过时间会提示更新无法正常使用…

C++学习笔记——输入、输出和文件

目录 一、标准输入输出 2.1下面是它们的基本用法 解释 二、格式化输入输出 2.2下面是一个示例 解释 三、文件读写 3.3下面是一个文件读写的示例 解释 四、异常处理和错误检测 4.1下面是一个示例 解释 五、一个实例代码 5.1如何读取 CSV 文件&#xff0c;并计算每…

【数据结构】交换排序

插入排序链接。 这篇文章讲解交换排序的两种排序&#xff1a;冒泡排序与快速排序。 目录 冒泡排序&#xff1a;完整代码&#xff1a; 快速排序&#xff1a;单趟排序&#xff1a;hoare&#xff1a;挖坑&#xff1a;前后指针&#xff1a; 完整代码&#xff08;3种方式&#xff0…

3 - AOP

1. 快速入门 1.1 基本说明 AOP(aspect oriented programming) &#xff0c;面向切面编程 切面类中声明通知方法&#xff1a; 前置通知&#xff1a;Before返回通知&#xff1a;AfterReturning异常通知&#xff1a;AfterThrowing后置通知&#xff1a;After环绕通知&#xff1…

2、Redis持久化、主从与哨兵:构建强大而稳定的数据生态

Redis作为一款高性能的内存数据库&#xff0c;其在持久化、主从复制和哨兵系统方面的支持使其在大规模应用和高可用性场景中脱颖而出。本文将深入探讨Redis的持久化机制、主从复制以及哨兵系统&#xff0c;为构建强大而稳定的数据生态揭示关键技术。 持久化&#xff1a;数据的…

二进制与十六进制,二进制与八进制之间的相互转换技巧

目录 1.二进制转换为八进制 2.八进制转换为二进制 3.二进制转换为十六进制 4.十六进制转换为二进制 1.二进制转换为八进制 转换为8进制 第一步&#xff1a;以小数点为分界线&#xff0c;整数部分自右向左&#xff0c;小数部分自左向右每3位取成1位&#xff1a; 整数部分…

【python入门】day28:记录用户登录日志

演示 代码 #-*- coding:utf-8 -*- print(记录用户登录日志----------------------------) import time def show_info():print(输入提示数字,执行相应操作:0退出,1查看登录日志) def write_logininfo(username):#----------记录日志with open(log.txt,a,encodingutf-8)as file…

如何高效阅读Linux的man page

有时候需要在man page中查某个命令的用法&#xff0c;我们一般会使用man command的方式来查询&#xff0c;例如man vmstat.但是对于一些bash内置的命令&#xff0c;如alias,如果使用man alias会打开General Commands Manual ,如下图 可以看到&#xff0c;内置命令很多&#xff…

COBOL语言 :一种主要专注于解决业务问题的编程语言

译文&#xff1a; 什么是COBOL? COBOL是一种主要专注于解决业务问题的编程语言。COBOL的完整形式是面向业务的通用语言。它主要用于公司和政府的商业、金融和行政系统。这种语言也被用来解决许多数据处理问题。 它是由CODASYL(数据系统语言会议)开发的。它被用作大型机中的一…

基于 InternLM 和 LangChain 搭建你的知识库

如何打造垂域大模型是一个重要落地方向。 如何打造个人专属的大模型应用也是重要的问题。 RAG 外挂一个知识库 优势&#xff1a;成本低&#xff0c;实时更新 劣势&#xff1a;能力受基座模型影响大&#xff0c;RAG每次需要将检索文档和问题提交给大模型&#xff0c;极大占用上下…

工程项目管理系统源码与Spring Cloud:实现高效系统管理与二次开发

随着企业规模的不断扩大和业务的快速发展&#xff0c;传统的工程项目管理方式已经无法满足现代企业的需求。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;企业需要借助先进的数字化技术进行转型。本文将介绍一款采用Spring CloudSpring BootMybat…

C++力扣题目701--二叉搜索树中的插入操作

给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c;可能存在多种有效的插入方式&a…

苏州倍丰智能新型雾化粉末技术量产成功!金属3D打印全产业链更进一步

苏州倍丰智能深耕金属3D打印技术领域&#xff0c;以金属3D打印全产业链为目标&#xff0c;围绕金属3D打印设备&#xff0c;涵盖包括金属粉末前后处理设备、金属粉末原材料制备、先进工艺研发等多个领域&#xff0c;完成了一整条自上而下的金属3D打印全产业链。 近日&#xff0c…

大数据Doris(五十四):SQL函数之日期函数(二)

文章目录 SQL函数之日期函数(二) 一、DAYOFMONTH(DATETIME date) 二、dayofweek(DATETIME date)

HarmonyOS 通过 animateTo讲解尺寸动画效果

上文 HarmonyOS讲解并演示 animateTo 动画效果 我们已经做出了基本的动画效果 也对 animateTo 的使用比较熟悉了 第一个参数是 配置动画参数的json 第二个参数 则是改变我们元素属性值的事件 但属性值 远远不止位置属性 本文 我们来说 通过尺寸变化 完成动画效果 如果你有看过…

代码随想录算法训练营第4天 | 24. 两两交换链表中的节点 , 19.删除链表的倒数第N个节点 , 面试题 02.07. 链表相交 , 142.环形链表II

链表知识基础 文章链接&#xff1a;https://programmercarl.com/%E9%93%BE%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html# 24. 两两交换链表中的节点 题目链接&#xff1a;https://leetcode.cn/problems/swap-nodes-in-pairs/ 使用虚拟头结点&#xff0c;这样会方便很…