仪表检测与读数(一):仪表检测

news2024/12/23 14:49:58

基于YOLOv4的仪表检测

  • 前言
  • YOLOv4源码下载
  • 数据集处理与模型训练
  • 模型性能测试

前言

  本系列是想记录一下自己实现的一种用于仪表检测与读数的方法,首先方法仅针对于单指针仪表和单行显示的数字仪表进行了检测与读数方法的设计。方法的整体思路是:第一步对拍摄图像进行仪表检测,然后对仪表位置进行裁剪,并根据仪表类别对应进行指针仪表读数识别和数字仪表读数识别,最后在将读数结果对应输出。整体流程如下:

输入图像
仪表检测
指针仪表读数识别
数字仪表读数识别
输出读数结果

  考虑到读数识别均需依赖于仪表检测结果,因此首先实现仪表检测,因为现在基于深度学习的目标检测算法有非常好的效果,同时考虑到模型复杂性等问题,我选择了单阶段的目标检测网络YOLOv4来进行仪表检测(当然也可根据自身任务的难易程度选择更合适的网络),然后为了能够简化后续的流程,我考虑到检测任务同时还能够对目标进行分类,因此我选择将仪表按照不同的量程来作为分类标准,这样虽然加大了检测的难度(如果仅区分指针仪表或数字仪表,感觉对于YOLOv4又有些大材小用了),但是能够有效地简化后续的读数流程。(当然这种分类方式弊端也很多,如表明脏污、相似仪表、按量程区分仪表种类众多等问题,但这也算是提供了一种思路吧。)

YOLOv4源码下载

  对于YOLOv4的网络结构及原理的介绍在网上有许多文章,或者可以阅读YOLOv4的论文。然后主要就是复现YOLOv4网络的源码,这里我选择的是Bubbliiiing博主实现的YOLOv4网络(包括后文还有另外一个网络的源码同样也是该博主的,非常感谢B导的无私奉献),对应博主的源码以及文章的链接见下面的两个链接(如果想了解更多,可以去B站看博主录制的视频):
文章: link.
源码: Github.

数据集处理与模型训练

  在前言中也有介绍,我对仪表数据的标注方式是按照不同量程进行区分标注,如0-160℃单指针温度表和0-200℃单指针温度表是被划分为两类的。因此按照这种标注方式,需要同类型的仪表数量居多,我在网络上没有收集到足够的仪表图像作为数据集,绝大部分图像是自行拍摄的图像。图像拍摄不做过多赘述。
  数据标注采用labelimg软件标注,下载地址:
Labelimg: 下载地址
  软件的具体使用方法可自行搜索,标注的形式如下图,每一种仪表都按照仪表量程进行了细分类,如160℃和200℃的温度表被分别标注为160和200:
在这里插入图片描述
  在标注完成后,会在指定目录生成对应的xml标注文件。这之后为了能够观察各类别仪表的样本数(理论上各样本数尽量均衡),单独写了一个脚本进行统计。

# coding:utf-8

"""
description: 统计各类别真实框数量,并显示一个统计图(主要是看看类别均衡)

author:     kuang
time:       2020.6.16       by home
"""

import xml.etree.ElementTree as ET
import os
import matplotlib.pyplot as plt
import matplotlib

# 指定默认字体
matplotlib.rcParams['font.sans-serif'] = ['FangSong']
matplotlib.rcParams['font.family'] = 'sans-serif'

# xml所在路径
path = "./train/Annotations/"

def count():
    # 获取所有xml文件
    xml_list = os.listdir(path)
    # 创建对应字典,且初始化
    class_count = {}

    # 对每个xml进行统计
    for file in xml_list:
        with open(os.path.join(path, file), "r", encoding="utf-8") as in_file:
            # 打开xml文件
            tree = ET.parse(in_file)
            # 获取根节点
            root = tree.getroot()
            # 迭代每个object
            for obj in root.iter('object'):
                # 获取当前object的class name
                cls = obj.find('name').text
                if cls not in class_count.keys():
                    class_count[cls] = 1
                # 计数
                class_count[cls] += 1

    return class_count

def draw(class_count):
    x = class_count.keys()
    y = class_count.values()

    # 柱状图的宽度
    width = 0.4
    # 绘制条形统计图,横向
    plt.bar(range(len(x)), y, align='center', color='steelblue', width=width, alpha=0.8)
    # 添加轴标签
    plt.ylabel('类别数量')
    # 添加标题
    plt.title('各类别数量统计图')
    # 添加刻度标签
    plt.xticks(range(len(x)), x)

    # 为每个条形图添加数值标签,横向条形统计图
    for i, j in enumerate(y):
        plt.text(i - 0.1, j + 8, '%s' % str(list(y)[i]), va='center')

    # 显示图形
    plt.show()


if __name__ == "__main__":
    class_count = count()
    draw(class_count)

统计结果示例如下图:
在这里插入图片描述

  最后,在按照博主在GitHub中给出的训练自己的数据集的训练步骤进行模型训练即可,注意根据自己硬件条件修改部分train.py文件中的参数(如batchsize、save_period等)。

模型性能测试

  训练完成后,首先修改yolo.py文件中的model_path、classes_path的路径以及input_shape的大小,然后就可以运行项目中的predict.py文件调用训练后的模型进行仪表检测了,检测结果示意如下图所示。
在这里插入图片描述在这里插入图片描述
  在完成检测后,可得到仪表的类别以及对应仪表的位置,通过该位置坐标即可对仪表进行裁剪(将yolo.py文件中的detect_image函数的crop修改为true即可),得到仅包含单个仪表的图像,从而进行下一步的分类仪表读数识别。裁剪后图像示例如下。
在这里插入图片描述

  最后,如果需要统计模型的mAP值,则可以运行get_map.py文件得到。

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

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

相关文章

[ 云计算 | Azure ] Chapter 06 | 计算服务之虚拟机、虚拟机规模集、Azure 容器、Azure App 与 Azure Functions

本系列已经更新文章列表(已更新): [ Azure 云计算从业者 ] Chapter 03 | 描述云计算运营中的 CapEx 与 OpEx,如何区分 CapEx 与 OpEx[ Azure 云计算从业者 ] Chapter 04 | Azure核心体系结构组件之数据中心、区域与区域对、可用区…

【Qt】插件Plugin入门之Q_PLUGIN_METADATA()宏【2023.05.07】

摘要 分析Q_PLUGIN_METADATA宏的设计意图,站在设计者的意图进行插件的高屋建瓴式学习。 Meta-Object Compiler 简称MOC Qt 的 Meta-Object Compiler(MOC)是一个预处理器,用于处理带有特殊关键字的 C 文件,并生成用于…

Linux命令·netstat

netstat命令用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP监听,进程内存管理的相关报告。 如果你的计算机有时候…

详细版简单易学版TypeScript各类型声明

假如本地新建了一个b.ts文件 安装TypeScript:npm install -g typescript 编译代码:tsc b.ts 运行js:node b.js 在终端输入 tsc -init 生成 tsconfig.json 文件 类型注解:TypeScript里的类型注解是一种轻量级的为函数或变量添加约束…

Python中模块和包基础学习

目录 模块 引入模块 使用from...import语句引入模块中的指定变量或函数 使用import...as语句给模块起别名 使用dir()函数查看模块中的所有变量和函数 使用__name__变量判断模块是被导入还是直接执行 包 注意 示例 模块 Python中的模块是指一个文件,可以包…

2.1 掌握NumPy数组对象ndarray

2.1 掌握NumPy数组对象ndarray 2.2.1 创建数组对象1.数组创建2.数组属性:ndarray(数组)是存储单一数据类型的多维数组。3.数组数据类型 2.1.2 生成随机数random模块常用随机数生成函数 2.1.3 通过索引访问数…

Python中异常处理的学习

目录 异常的基本介绍 异常处理语句 抛出异常 异常的基本介绍 在Python中,如果程序出现错误,会抛出异常。异常是一种Python对象,它封装了错误的信息,并提供了一种处理错误的机制。Python中内置了很多异常类型,包括但…

C语言-学习之路-07

C语言-学习之路-07 内存管理作用域局部变量静态(static)局部变量全局变量extern全局变量声明全局函数和静态函数 内存分布内存分区 内存管理 作用域 C语言中变量的作用域可分为:代码作用域、函数作用域、文件作用域 局部变量 局部变量也叫…

C嘎嘎~~ [类 下篇(2)]

类 下篇2 5.赋值运算符重载5.1运算符重载5.1.1 运算符的概念5..1.2 重载运费符的位置5.1.3运算符重载的实质 5.2 赋值运算符重载5.2.1深刻理解---编译器生成的默认赋值运算符重载5.2.2深刻理解---拷贝构造和赋值运算符重载5.2.3深刻理解---传参和返回值用引用修饰 5.赋值运算符…

ADAS-透视前方:汽车HUD技术原理解析

“ 当人们谈论未来的汽车技术时,汽车HUD(Head-Up Display)是一个经常被提及的技术。HUD是一种驾驶辅助技术,它可以将关键的驾驶信息直接显示在驾驶员的视线范围内,让驾驶员无需转移视线就能获得所需信息。这个技术在过…

HZNUCTF2023 web

目录 <1> guessguessguess <2> ezflask(无过滤ssti) ​ <3> ppppop(cookie泄露反序列化) <4> ezlogin(bool盲注) <5> ezpickle(pickle反序列化) <6> eznode(原型链污染) <1> guessguessguess 尝试是否存在sql注入&#xff0c;…

03- 目标检测数据集和标注工具介绍 (目标检测)

要点&#xff1a; 常用数据集和标注工具 标注工具 PPOCRLabel github地址&#xff1a;paddleocrlabel 参考文档&#xff1a;目标检测简介 - 知乎 一 目标检测数据集 1. PASCAL VOC VOC数据集是目标检测经常用的一个数据集&#xff0c;自2005年起每年举办一次比赛&#xff…

JWT快速入门及日常使用

什么是JWT JSON Web Token&#xff0c;通过数字签名的方式&#xff0c;以json对象为载体&#xff0c;在不同服务端之间安全的传输信息 JWT有什么用 JWT最常见的场景就是授权认证&#xff0c;一旦用户登录&#xff0c;后续每个请求都将包含JWT&#xff0c;系统每次处理用户请求前…

总结下自己编译alembic的过程

编译alembic过程回顾 前言 总结下自己编译alembic的过程 最近想学习编译啥的&#xff0c;就想着一边编译着&#xff0c;一边学习的&#xff0c;刚好&#xff0c;拿alembic编译练手&#xff0c;记录下自己编译的过程吧。 编译的使用的是Visual Studio 2022&#xff0c;python…

【性能设计篇】性能设计-缓存

前言 在分布式系统中&#xff0c;最耗费性能的地方就是数据库&#xff0c;而对于数据库的操作基本上就是添加&#xff0c;修改&#xff0c;删除和查询&#xff0c;对于前3者来说&#xff0c;基本上不会出现性能瓶颈。最耗费性能的地方就是查询了&#xff0c;对于查询有join、w…

Kafka相关知识

一、基本概念及流程 Broker:kafka集群中的实例Topic:队列的主题,逻辑概念;Partition:Topic分区,物理概念,同意parttion内消息有序;Producer & Consumer:生产消息的客户端 & 消费消息的客户端,kafka认为是服务器。将每个Topic划分为多个分区Partition,每个分…

Vim (NeoVim) 配置

Vim 基础 模式 o 代表的是open a new line i 代表的是insert a 代表的是append Visual [Character] 视觉模式&#xff1a;用于选择单个字符&#xff08;v小写’v’&#xff09;视觉线模式&#xff1a;用于一次选择整条线&#xff08;V大写“V”&#xff09;视觉块模式&#…

深度学习数据集—动物数据集大合集(二)

近期又整理了一批各类动物数据集&#xff0c;分享给大家。废话不多说&#xff0c;直接上干货&#xff01;&#xff01; 1、151种动物图片数据集共6271张&#xff0c;图片大小&#xff1a;224x224 jpg ​ ​ 下载地址&#xff1a;151种动物图片数据集 2、9种海洋生物&#xff0…

C++学习之字符常量、字符串常量和符号常量的区别

字符常量 字符常量就是把一个字符用单引号括起来。 注&#xff1a; 字符常量只能包含一个字符&#xff0c;如’AB’是不合法的字符常量区分大小写字母单引号“ ’ ”是定界符&#xff0c;而不属于字符常量的一部分 字符串常量 字符串常量时用双引号括起来的字符序列。 举例…

kill 命令信号详解

信号 列出所有信号 $ kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18…