数字式仪表和两种指针式仪表读数识别

最近放假看到YOLOv8一直在更新,想着在家无聊把本科毕设重新做了下,之前用的是YOLOv5,下载了YOLOv8最新版把项目迁移了过来,相比于v5来说YOLOv8变化还是挺大的,功能更加集成了,话不多说,直接上结果图片和最后的检测视频。

数字式仪表识别效果

指针式仪表识别效果

360度指针式仪表识别效果

数字式仪表和指针式仪表检测视频

YOLOv8+PyQt+OpenCV+Python实现数字式仪表和两种指针式仪表读数识别

整体思路流程

YOLOv8的检测结果更加集成了,可以在JupyterLab中根据检测结果一步步获取目标框的位置信息,不用像yolov5一样还得在源码里找到对应参数再更改那么麻烦,再根据JupyterLab调试结果把代码合成一个py文件,就方便很多。数字式仪表读数和指针式仪表读数实现的具体思路在后面。

文章(一)主要介绍①不同规格仪器仪表图像识别(识别结果裁剪出来作为数字式仪表和指针式仪表读数识别的数据集)、②数字式仪表读数识别(读数思路、PyQt界面显示等)。

关于两种指针式仪表的读数识别将会在文章(二)介绍。

以下是当时论文整体流程图以及图像获取系统图,可以参考,内容主要包括不同规格仪器仪表图像识别、数字式仪表读数识别、指针式仪表读数识别、360度指针式仪表读数识别等。

整体流程图

图像获取系统图

不同规格仪器仪表图像识别(较基础可跳过)

不同规格仪表图像检测路线图及一些方法

数据集准备

分为数据集和验证集共135张图像。部分图像如下所示。

透视矫正

校正前图片和校正后结果图片如下。由于代码较长且实现不太复杂就不放了。

图像标注

使用LabelImg或者Makesence都可以,这部分就不用多说了。

数据增强

使用随机裁剪、随机缩放、随机旋转、图像镜像以及颜色增强等数据增强方法。由于代码较长且实现不太复杂就不放了。效果图及对应xml如下。YOLO标注为txt文件,可转为xml文件。

检测结果

正常训练检测就好,这个也比较基础,没什么说的。

图像分割

针对不同类型的仪器仪表识别训练好的模型,根据检测结果计算出需要裁剪的区域,将其裁剪下来并保存,由此构成数字式仪器仪表识别的数据集。分割后部分图像如下,以及裁剪代码。

import os

import cv2

def main():

img_path = 'C:/Users/wsz/Desktop/ultralytics/datasets/mydata_type/images/train' # 图片路径

label_path = 'C:/Users/wsz/Desktop/ultralytics/tools_testpic/caijian/predict/labels' # txt文件路径

save_path = 'C:/Users/wsz/Desktop/ultralytics/tools_result/caijianhou' # 保存路径

img_total = []

label_total = []

imgfile = os.listdir(img_path)

labelfile = os.listdir(label_path)

for filename in imgfile:

name, type = os.path.splitext(filename)

if type == ('.jpg' or '.png'):

img_total.append(name)

for filename in labelfile:

name, type = os.path.splitext(filename)

if type == '.txt':

label_total.append(name)

for _img in img_total:

if _img in label_total:

filename_img = _img + '.jpg'

path = os.path.join(img_path, filename_img)

img = cv2.imread(path) # 读取图片,结果为三维数组

filename_label = _img + '.txt'

w = img.shape[1] # 图片宽度(像素)

h = img.shape[0] # 图片高度(像素)

n = 1

# 打开文件,编码格式'utf-8','r+'读写

with open(os.path.join(label_path, filename_label), "r+", encoding='utf-8', errors="ignor") as f:

for line in f:

msg = line.split(" ") # 根据空格切割字符串,最后得到的是一个list

x1 = int((float(msg[1]) - float(msg[3]) / 2) * w) # x_center - width/2

y1 = int((float(msg[2]) - float(msg[4]) / 2) * h) # y_center - height/2

x2 = int((float(msg[1]) + float(msg[3]) / 2) * w) # x_center + width/2

y2 = int((float(msg[2]) + float(msg[4]) / 2) * h) # y_center + height/2

filename_last = _img + "_1" + ".jpg"

print(filename_last)

img_roi = img[y1:y2, x1:x2] # 剪裁,roi:region of interest

cv2.imwrite(os.path.join(save_path, filename_last), img_roi)

n = n + 1

else:

continue

if __name__ == '__main__':

main()

数字式仪表读数识别

数据集准备+标注

标签选择数字“0-9” 和小数点“.”以及常见的“m,k,A,V,Ω,M,W,h”等单位,共标注图像 180 张。下图为部分数据集。

检测效果

之前加入混洗注意力机制,效果如下。从图中可以看到,对数字及单位识别的置信度水平均在 96%以上,最高的达到了 98%,表明模型训练效果较好,达到了较高的水平。训练过程mAP变化在Origin中绘制如下,有s、m、l、x、x_AT(加入了注意力机制)五条曲线。

读数思路

之前在YOLOv5中是在源码中找到目标框的相关坐标参数,来进行修改显示,在YOLOv8中,由于检测结果的集成,可以根据检测结果result接收这一参数,对result的[0]里面的boxes的数据进行处理:

选取data和xywh,由于data里的坐标参数为目标框架的四个边缘坐标以及目标框的置信度及类别,xywh为目标框的中心xy坐标以及wh,所以将data里的最后一列类别提取出来加入到xywh中,加入后的xywh根据第一列x的坐标从小到大进行排列,由此可得出对应类别的排序,最后提取最后一列类别,转为python列表,根据result的names使用列表推导和字典的get方法获取对应键值即可完成检测结果的从左到右排序,转为相应类型如字符串输出即可。

PyQt界面显示

界面包括导入图片、开始检测、确认读数、修改读数、结果显示(包括当前时间、读数结果)、清除数据等操作,读数结果会保存在相应txt文件中,如下所示。其中确认读数会在文件中追加并显示"The reading is correct.",修改读数会自动读取模型的检测结果,修改后在文件中追加并显示"The corrected reading is:XXX"。写这个界面还是花了一点时间。

参考阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。