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

news2024/11/19 3:40:33

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

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

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

项目背景

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

在本系列项目中,使用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 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')

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

  1. 重新训练识别模型

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

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

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

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

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

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

最终预测效果如下:

(预测结果图片)

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

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

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

相关文章

linux Tcp总结

Tcp连接建立时的影响因素 在Client发出SYN后&#xff0c;如果过了1秒 &#xff0c;还没有收到Server的响应&#xff0c;那么就会进行第一次重传&#xff1b;如果经过2s的时间还没有收到Server的响应&#xff0c;就会进行第二次重传&#xff1b;一直重传tcp_syn_retries次。 对…

无公网ip如何随时随地远程查看本地群晖NAS存储的文件资源

文章目录 前言本教程解决的问题是&#xff1a;按照本教程方法操作后&#xff0c;达到的效果是前排提醒&#xff1a; 1. 搭建群晖虚拟机1.1 下载黑群晖文件vmvare虚拟机安装包1.2 安装VMware虚拟机&#xff1a;1.3 解压黑群晖虚拟机文件1.4 虚拟机初始化1.5 没有搜索到黑群晖的解…

python -- pyQt5中 样式设置

一、父控件设置样式表后对子控件产生影响&#xff0c;控制styleSheet的作用范围 https://blog.csdn.net/qq_31073871/article/details/90288625 QFrame 作为容器&#xff0c;放入其他多种部件&#xff0c;里面的边框都生效 在类名后面用 #号串接变量名&#xff0c;子控件不…

浅学Linux之旅 day1 学习路线及计算机入门知识介绍

我不要做静等被掀起的轻波&#xff0c;我要生起翠绿的斑驳 偶尔过季的遭遭人事化长风拂过 思绪撕碎点燃了火 ——24.1.14 一、Linux学习路线 ①计算机入门知识介绍 ②Linux系统概述 ③Linux系统的安装和体验 ④Linux的网络配置和连接工具 ⑤Linux的目录结构 ⑥Linux的常用命令 …

Qt/QML编程学习之心得:小键盘keyboard(36)

小键盘对于qml应用是经常用到的,在qml里面,就如一个fileDialog也要自己画一样,小键盘keyboard也是要自己画的,对于相应的每个按键的clicked都要一一实现的。 这里有一个示例: 代码如下: import QtQuick 2.5 import QtQuick.Controls 1.4 import QtQuick.Window 2.0 im…

五种嵌入式经典通信总线协议

一.先前知识 1.并行与串行 并行通信和串行通信是两种不同的数据传输方式&#xff1a; 并行通信&#xff1a;并行通信是指在同一时间使用多条并行传输的线路传输多个比特的数据。每个比特使用独立的线路进行传输&#xff0c;同时进行。这样可以在一个时钟周期内传输多个比特&…

Kafka消费全流程

Kafka消费全流程 1.Kafka一条消息发送和消费的流程图(非集群) 2.三种发送方式 准备工作 创建maven工程&#xff0c;引入依赖 <dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>3.3.1&l…

阿里云服务器的tcp端口无法访问(云服务厂家问题?)

问题->无法访问 阿里云服务器的tcp端口 最近一台阿里云服务器的一个端口61616无法访问&#xff0c;在服务器内用外网地ip发现无法访问&#xff0c;用内网ip访问是正常的&#xff0c;通过技术排查&#xff1a; 解决->无法访问 阿里云服务器的tcp端口 1 配置官网的安全组…

如何正确使用数据库的读写分离

本文已收录至我的个人网站&#xff1a;程序员波特&#xff0c;主要记录Java相关技术系列教程&#xff0c;共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源&#xff0c;让想要学习的你&#xff0c;不再迷茫。 背景 在应用系统发展的初期&#xff0c;我们并不知…

spring基于XML方式的组件管理

基本介绍 依赖注入是一种处理对象间依赖关系的技术。在Spring中&#xff0c;依赖注入有构造方法注入和设值注入两种方式。 设值注入是将依赖作为成员变量&#xff0c;通过主调类的setter方法注入依赖。构造方法注入则是在Bean的构造方法中注入依赖。 本次我们将通过具体例子来…

大白话讲清楚:什么是 Langchain 及其核心概念

在AI和机器学习领域&#xff0c;每天都有新技术和框架涌现。今天&#xff0c;我们来聊聊最近引起广泛关注的一个框架 —— Langchain。 https://python.langchain.com/docs/get_started/introduction 那么&#xff0c;Langchain到底是什么&#xff0c;它为什么这么受欢迎&#…

[NAND Flash 6.4] NAND FLASH基本读操作及原理_NAND FLASH Read Operation源码实现

依公知及经验整理,原创保护,禁止转载。 专栏 《深入理解NAND Flash》 <<<< 返回总目录 <<<< ​全文 6000 字 内容摘要 NAND Flash 引脚功能 读操作步骤 NAND Flash中的特殊硬件结构 NAND Flash 读写时的数据流向 Read 操作时序 读时序操作过…

测试SpringBoot的时候报错mapper未装载的解决方案:

1.报错信息和截图&#xff1a; org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name com.tang.testspringboot.TestSpringBootApplicationTests: Unsatisfied dependency expressed through field mapper: No qualifying bean o…

SAM:segment anything model——一个通用的图像分割基础模型

文章目录 一、Segment Anything Task二、SAM模型的架构&#xff08;一&#xff09;图像编码器image encoder&#xff08;二&#xff09;prompt encoder&#xff08;三&#xff09;mask decoder 三、SAM 模型的思想&#xff08;一&#xff09;Transformer的自注意力机制&#xf…

Oracle-数据库性能变慢问题分析

问题背景: 应用运维报障说最近两天业务数据入库和表查询都变得很慢&#xff0c;需要排查一下数据库的性能问题 问题分析&#xff1a; 登录到服务器上&#xff0c;通过TOP命令快速看了一下&#xff0c;服务器整体的CPU使用%usr不算特别高&#xff0c;但%wa IO等待很高&#xff…

数据库与SQL

数据库与SQL 学习链接数据库关系型数据库管理系统&#xff08;RDBMS&#xff09; SQLSQL介绍SQL类型SQL 基础语言学习创建表&#xff08;create table&#xff09;语法 数据类型SQL最常用的数据类型 学习链接 基础篇&#xff1a;数据库 SQL 入门教程 数据库 用于存储数据 存放…

centos下系统全局检测工具dstat使用

目录 一&#xff1a;没有需要安装 二&#xff1a;dstat命令参数 三、监测界面各参数含义&#xff08;部分&#xff09; 四、dstat的高级用法 一&#xff1a;没有需要安装 yum install dstat 二&#xff1a;dstat命令参数 有默认选项&#xff0c;执行dstat命令不加任何参数…

docker完成redis 三主三从

文章目录 关闭防火墙启动docker后台服务新建6个docker容器redis实例创建并运行docker容器实例 进入容器redis-node-1并为6台机器构建集群关系链接进入6381作为切入点&#xff0c;查看集群状态主从容错切换迁移案例容错切换迁移 主从扩容案例为主节点6387分配从节点6388主从缩容…

第二十八周:文献阅读笔记(弱监督学习)+ pytorch学习

第二十八周&#xff1a;文献阅读笔记&#xff08;弱监督学习&#xff09; 摘要Abstract1. 弱监督学习1.1. 文献摘要1.2. 引言1.3. 不完全监督1.3.1. 主动学习与半监督学习1.3.2. 通过人工干预1.3.3. 无需人工干预 1.4. 不确切的监督1.5. 不准确的监督1.6. 弱监督学习的创新点 2…

List集合遍历过程中修改元素(有坑)

说来惭愧&#xff0c;学 java 2年了&#xff0c;对 “Java是值传递” 这句话还没有理解它的精髓&#xff0c;以至于编程的时候出现了一些错误&#xff0c;这里记录一下。 一.问题再现 1.1将List集合中的每个字符串更改为其他值 1.2将List集合中的对象更改为其他对象 二.问题分…