目标检测——基于yolov8和pyqt的螺栓松动检测系统

目录

  • 1.项目克隆和环境配置
    • 1.1 我这里使用的是v8.0.6版本
    • 1.2 项目代码结构介绍
  • 2.数据集介绍
    • 2.1 数据集采集
    • 2.2采集结果介绍
  • 3.模型训练
  • 4.pyqt界面设计
    • 4.1 界面内容介绍
    • 4.2 界面实现
  • 5.操作中的逻辑实现
    • 5.1 图片检测
    • 5.2 文件夹检测
    • 5.3 视频检测和摄像头检测
  • 6. 效果展示

1.项目克隆和环境配置

1.1 我这里使用的是v8.0.6版本

这里为了方便学习,我使用的是旧的版本,先从官网上Tag下找到v8.0.6版本的安装包,然后下载解压,下面就是项目下载地方
在这里插入图片描述

1.2 项目代码结构介绍

将这个版本的yolov8下载到本地后整个项目结构和下面这张图是类似的,整体项目结构和v5有些不同,其中重要的代码都在ultralytics中
在这里插入图片描述
|——bolt_datasets:这个里面存放的是我用来进行螺栓松动检测的数据集。
|——docker:是一个应用容器引擎。
|——doc:这里面的东西不用管。
|——example:这里面是下载ultralytics这个python库,用这个来进行训练和推理的一 些例子。
|——Flowers_Dataset:这是另一个花朵数据集。
|——ultralytics:这里面包含模型配置,数据集配置yolov8模型的实现等。

ultralytics中代码结构如下图,主要使用的是ultralytics\yolo\v8\classify\predict.py这部分代码,如果想用自己的数据集训练模型可以看这篇文章,v8和v5项目结构有一些变化,不过数据集处理等是一样的,用python中labeling标注数据。
在这里插入图片描述
在这里插入图片描述

2.数据集介绍

2.1 数据集采集

我是用的自己手机进行采集的,用三脚架固定手机,通过调整手机高度、距离螺栓远近和拍摄角度来采集数据的。
总共拍摄了5个松动的10秒视频和5个拧紧的10秒视频,再将视频处理为一帧一帧的形式生成一个数据集,将每帧调整为640×640大小的图片,最后使用其中的200张图片训练,每张图片包含4个螺栓。

2.2采集结果介绍

上面两张是螺栓拧紧的图片,下面两张是螺栓松动的图片
在这里插入图片描述
下面是我用yolov8进行训练的的数据集结构,制作类似这样的数据集可以看这篇文章,该数据集共800个螺栓,图片大小为640×640,训练集和测试集比例为9:1。
在这里插入图片描述

3.模型训练

先修改ultralytics\yolo\configs\default.yaml这部分中的配置文件,我是用的是预训练yolov8n.pt模型进行训练,共训练100次,最后训练出的文件如下图
在这里插入图片描述

4.pyqt界面设计

4.1 界面内容介绍

界面中内容包括5个部分,分别是检测窗口、检测结果与位置信息、检测参数设置、检测结果和操作。检测窗口用来显示图片,检测结果与位置信息显示序号、检测图片文件路径、目标编号、类别、置信度和坐标位置这六个部分,然后检测参数包括阈值和交并比阈值,还有检测结果和操作等等。

4.2 界面实现

这里我用的是python带的pyqt5写的,用designer设计布局,再将ui文件转为py文件,这里注意一定要使用界面布局,这样整个界面布局更清晰并且也能放大放小,不容易混乱。
下面是我的界面图:
在这里插入图片描述

5.操作中的逻辑实现

我的实现方法是在detect\predict.py这个文件内容上新创建了一个类来实现操作中功能,这个类能初始化界面,实现按钮功能等。

5.1 图片检测

实现步骤大致为三步,打开要检测的图片,对图片进行检测,最后将检测结果显示在界面上。
用QFileDialog打开图片,打开图片后用yolo\engine\predictor中的类实例进行检测,检测过程中同过yield返回必要的数据,包括模型model、检测花费时间tm和原图im0s。之后根据返回的信息存储边界框、置信度、类别序号信息,向界面tableview和comboBox中插入信息等操作。
具体代码

    # 文件中图片检测def open_file(self):   folder_path = QFileDialog.getExistingDirectory(self, 'Select Folder', '')# 清空表格数据row_count = self.tb_model.rowCount()self.tb_model.removeRows(0, row_count)self.flag == 0for filename in os.listdir(folder_path):self.sum = 0# 构造完整的文件路径file_path = os.path.join(folder_path, filename)# # 检查文件是否是图片文件,可以根据文件扩展名来判断if file_path.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):self.fileName1 = file_pathtry:for model, tm, im in self.predict():print(self.save_dir)self.model = modeldet = self.predictor.output['det']self.det = det# 存储结果,向tableview和comboBox中添加信息self.image_detections[self.fileName1] = det # 存储检测结果self.image_path[filename] = file_pathself.image_tm[self.fileName1] = tmself.image_allLabel[self.fileName1] = os.path.join(self.save_dir, filename)box = det[:,:4] # 边界框confidences = det[:,4] # 置信度class_indices = det[:,5].astype(int) # 类序号predicted_classes = [model.names[idx] for idx in class_indices] # 序号转成类别名class_count = {}new_predicted_classes = []for box, confidences, class_name in zip(box,confidences, predicted_classes): # 修改重复的类别名# 给相同类别的标签添加数字后缀if class_name not in class_count:class_count[class_name] = 0class_count[class_name] += 1#创建新标签new_class_name = f"{class_name}{class_count[class_name] - 1}" if class_count[class_name] > 1 else class_namenew_predicted_classes.append(new_class_name)pp = '(' + ', '.join([str(item) for item in box]) + ')'self.sum += 1# 向TableView添加信息row = []file=f'{self.save_dir}/crops/{new_class_name}/{new_class_name}.jpg'row.append(QStandardItem(str(self.sum)))row.append(QStandardItem(str(file)))row.append(QStandardItem(str(self.sum)))row.append(QStandardItem(str(new_class_name)))row.append(QStandardItem(str(f'{confidences:.2f}')))row.append(QStandardItem(str(pp)))self.tb_model.appendRow(row)self.comboBox.clear()self.comboBox.addItem('全部')self.comboBox.addItems(new_predicted_classes)self.image_boBox[self.fileName1] = new_predicted_classesself.image_sum[self.fileName1] = self.sumself.image = self.predictor.annotator.result() # 标记所有的结果图self.label_6.setText(str(self.sum)) # 总目标数self.label_8.setText(str(round(tm*1000, 3))+'ms') # 用时# 将numpy图片转成QImageheight, width, channels = self.image.shapebytes_per_line = 3 * widthq_image = QImage(self.image.data, width, height, bytes_per_line, QImage.Format_BGR888)# Convert QImage to QPixmappixmap = QPixmap.fromImage(q_image)self.label_2.setPixmap(pixmap.scaled(self.label_2.size(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation))self.label_2.setText('')  # Clear the label textexcept Exception as e:print(f"Error processing {filename}: {e}")

5.2 文件夹检测

这部分是对文件夹中存在的所有图片进行检测,并且鼠标点击tableview可以切换检测图片,同时能够切换检测图片中的单个检测对象。
实现流程跟上面类似,就是多了个读取文件夹中每张图片的过程,代码如下:

for filename in os.listdir(folder_path):self.sum = 0# 构造完整的文件路径file_path = os.path.join(folder_path, filename)# # 检查文件是否是图片文件,可以根据文件扩展名来判断if file_path.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):self.fileName1 = file_pathtry:for model, tm, im in self.predict():print(self.save_dir)self.model = modeldet = self.predictor.output['det']self.det = det# 存储结果,向tableview和comboBox中添加信息self.image_detections[self.fileName1] = det # 存储检测结果self.image_path[filename] = file_pathself.image_tm[self.fileName1] = tmself.image_allLabel[self.fileName1] = os.path.join(self.save_dir, filename)box = det[:,:4] # 边界框confidences = det[:,4] # 置信度class_indices = det[:,5].astype(int) # 类序号predicted_classes = [model.names[idx] for idx in class_indices] # 序号转成类别名class_count = {}new_predicted_classes = []for box, confidences, class_name in zip(box,confidences, predicted_classes): # 修改重复的类别名# 给相同类别的标签添加数字后缀if class_name not in class_count:class_count[class_name] = 0class_count[class_name] += 1#创建新标签new_class_name = f"{class_name}{class_count[class_name] - 1}" if class_count[class_name] > 1 else class_namenew_predicted_classes.append(new_class_name)pp = '(' + ', '.join([str(item) for item in box]) + ')'self.sum += 1# 向TableView添加信息row = []file=f'{self.save_dir}/crops/{new_class_name}/{new_class_name}.jpg'row.append(QStandardItem(str(self.sum)))row.append(QStandardItem(str(file)))row.append(QStandardItem(str(self.sum)))row.append(QStandardItem(str(new_class_name)))row.append(QStandardItem(str(f'{confidences:.2f}')))row.append(QStandardItem(str(pp)))self.tb_model.appendRow(row)self.comboBox.clear()self.comboBox.addItem('全部')self.comboBox.addItems(new_predicted_classes)self.image_boBox[self.fileName1] = new_predicted_classesself.image_sum[self.fileName1] = self.sumself.image = self.predictor.annotator.result() # 标记所有的结果图self.label_6.setText(str(self.sum)) # 总目标数self.label_8.setText(str(round(tm*1000, 3))+'ms') # 用时# 将numpy图片转成QImageheight, width, channels = self.image.shapebytes_per_line = 3 * widthq_image = QImage(self.image.data, width, height, bytes_per_line, QImage.Format_BGR888)# Convert QImage to QPixmappixmap = QPixmap.fromImage(q_image)self.label_2.setPixmap(pixmap.scaled(self.label_2.size(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation))self.label_2.setText('')  # Clear the label textexcept Exception as e:print(f"Error processing {filename}: {e}")

5.3 视频检测和摄像头检测

这部分我使用的是源代码对这两种流数据处理过程,通过__call__函数和yield返回程序处理过程中的中间数据,再对中间数据进行存储、显示等操作。代码与上面类似,注意这里没有使用Timer对数据帧定时处理。

6. 效果展示

对全部检测结果显示
在这里插入图片描述
对部分检测结果显示
在这里插入图片描述
到这里螺栓松动检测系统就完成了,如果有需要源代码的可以小刀。

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

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

相关文章

宠物行业的出路:在爱与陪伴中寻找增长新机遇

在当下的消费市场中,如果说有什么领域能够逆势而上,宠物行业无疑是一个亮点。当人们越来越注重生活品质和精神寄托时,宠物成为了许多人的重要伴侣。它们不仅仅是家庭的一员,更是情感的寄托和生活的调剂。然而,随着行业…

原点安全再次入选信通院 2024 大数据“星河”案例

近日,中国信息通信研究院和中国通信标准化协会大数据技术标准推进委员会(CCSA TC601)共同组织开展的 2024 大数据“星河(Galaxy)”案例征集活动结果正式公布。由工银瑞信基金管理有限公司、北京原点数安科技有限公司联…

【0x001D】HCI_Read_Remote_Version_Information命令详解

目录 一、命令概述 二、命令格式及参数说明 2.12. HCI_Read_Remote_Version_Information 命令格式 2.2. Connection_Handle 三、生成事件 3.1. HCI_Command_Status 事件 3.2. HCI_Read_Remote_Version_Information_Complete 事件 四、命令执行流程 4.1. 命令发起阶段(…

C语言-结构体内存大小

#include <stdio.h> #include <string.h> struct S1 { char a;//1 int b;//4 char c;//1 }; //分析 默认对齐数 成员对齐数 对齐数(前两个最小值) 最大对齐数 // 8 1 …

直流电源如何输出恒压源和恒流源

输出电流达到预定值时&#xff0c;变成稳流特性。 输出电压达到预定值时&#xff0c;变成稳压特性。 电流变大&#xff0c;成稳压。 电压变大&#xff0c;成稳流。

【软考高级】系统架构设计师复习笔记-精华版

文章目录 前言0 系统架构设计师0.1 考架构还是考系分0.2 架构核心知识0.3 架构教材变化 1 计算机操作系统1.1 cpu 组成1.2 内核的五大功能1.3 流水线技术1.4 段页式存储1.5 I/O 软件1.6 文件管理1.7 系统工程相关 2 嵌入式2.1 嵌入式技术2.2 板级支持包&#xff08;BSP&#xf…

如何识别钓鱼邮件和诈骗网站?(附网络安全意识培训PPT资料)

识别钓鱼邮件和诈骗网站是网络安全中的一个重要环节。以下是一些识别钓鱼邮件和诈骗网站的方法&#xff1a; 识别钓鱼邮件&#xff1a; 检查发件人地址&#xff1a; 仔细查看发件人的电子邮件地址&#xff0c;看是否与官方域名一致。 检查邮件内容&#xff1a; 留意邮件中是否…

查询 MySQL 默认的存储引擎(SELECT @@default_storage_engine;)

要查询 MySQL 默认的存储引擎&#xff0c;可以使用以下 SQL 查询语句&#xff1a; SELECT default_storage_engine;解释&#xff1a; SELECT: 表示你要执行一个查询。default_storage_engine: 这是一个 MySQL 系统变量&#xff0c;它存储着当前 MySQL 服务器的默认存储引擎。…

ROM修改进阶教程------修改刷机包init.rc 自启用户自定义脚本的一些基本操作 代码格式与注意事项

在很多定制化固件中。我们需要修改系统的rc文件来启动自己的一些脚本。但有时候修改会不起作用,其具体原因在于权限与代码格式的问题。博文将系统的解析代码操作编写的注意事项与各种权限分别。了解以上. 轻松编写自定义启动脚本. 通过博文了解💝💝💝 1-------💝💝…

openwrt 负载均衡方法 openwrt负载均衡本地源接口

openwrt 负载均衡方法 openwrt负载均衡本地源接口_mob6454cc647bdb的技术博客_51CTO博客 本人注重原理分析&#xff0c;要求对其原理掌握&#xff0c;否则按教程操作&#xff0c;你怕是什么都学不会&#xff0c;仔细看&#xff0c;认真记比较好。 首先确认一下基本细节 1、路由…

InnoDB引擎的内存结构

InnoDB擅长处理事务&#xff0c;具有自动崩溃恢复的特性 架构图&#xff1a; 由4部分组成&#xff1a; 1.Buffer Pool&#xff1a;缓冲池&#xff0c;缓存表数据和索引数据&#xff0c;减少磁盘I/O操作&#xff0c;提升效率 2.change Buffer&#xff1a;写缓冲区&#xff0c…

从 GitLab.com 到 JihuLab.com 的迁移指南

本文分享从 GitLab.com 到 JihuLab.com 的迁移指南。 近期&#xff0c;GitLab Inc. 针对其 SaaS 产品做了限制&#xff0c;如果被判定为国内用户&#xff0c;则会建议使用其在国内的发布版本极狐GitLab。从 GitLab SaaS 产品&#xff08;GitLab.com&#xff09;迁移到极狐GitL…

基于STM32F103控制L298N驱动两相四线步进电机

文章目录 前言一、模块参数二、接口说明三、准备工作四、直流电机驱动引脚接线效果展示 五、两相四线步进电机驱动步进电机相关概念拍数驱动时序引脚接线效果展示 六、参考示例 前言 L298N 是一种常见的双 H 桥电机驱动模块&#xff0c;广泛用于驱动直流电机和步进电机。它基于…

【赵渝强老师】MongoDB逻辑存储结构

MongoDB的逻辑存储结构是一种层次结构&#xff0c;主要包括了三个部分&#xff0c;即&#xff1a;数据库&#xff08;Database&#xff09;、集合&#xff08;Collection&#xff0c;也可以叫做表&#xff09;和文档&#xff08;Document&#xff0c;也可以叫做记录&#xff09…

观察者模式和发布-订阅模式有什么异同?它们在哪些情况下会被使用?

大家好&#xff0c;我是锋哥。今天分享关于【观察者模式和发布-订阅模式有什么异同&#xff1f;它们在哪些情况下会被使用&#xff1f;】面试题。希望对大家有帮助&#xff1b; 观察者模式和发布-订阅模式有什么异同&#xff1f;它们在哪些情况下会被使用&#xff1f; 1000道 …

多目标应用(一):多目标麋鹿优化算法(MOEHO)求解10个工程应用,提供完整MATLAB代码

一、麋鹿优化算法 麋鹿优化算法&#xff08;Elephant Herding Optimization&#xff0c;EHO&#xff09;是2024年提出的一种启发式优化算法&#xff0c;该算法的灵感来源于麋鹿群的繁殖过程&#xff0c;包括发情期和产犊期。在发情期&#xff0c;麋鹿群根据公麋鹿之间的争斗分…

Word窗体联动Excel实现级联组合框

在Word中的使用用户窗体&#xff08;UserForm&#xff09;定制界面如下图所示&#xff0c;其中控件如下&#xff08;忽略Label控件&#xff09;&#xff1a; CompanyName 组合框Attention 组合框CommandButton1 按钮 现在需要实现级联组合框效果&#xff0c;即用户在 CompanyN…

浅谈TARA在汽车网络安全中的关键角色

随着现代汽车技术的迅猛发展&#xff0c;网络安全成为汽车行业一个不可忽视的领域。为了应对日益复杂的网络威胁&#xff0c;ISO/SAE 21434标准和UN R155法规提供了系统化的网络安全管理框架。其中&#xff0c;TARA&#xff08;威胁分析与风险评估&#xff09;作为核心方法论&a…

领克Z20结合AI技术,革新自动驾驶辅助系统

眼瞅着&#xff0c;再有不到 5 个星期&#xff0c;春节就要热热闹闹地登场啦&#xff01;对于在外辛苦打拼了一整年的打工人而言&#xff0c;回家过年可不就是这一年里心心念念、最最期盼的高光时刻嘛。这不&#xff0c;这几天各地的高速公路愈发熙熙攘攘起来&#xff0c;川流不…

C语言结构体位定义(位段)的实际作用深入分析

1、结构体位段格式 struct struct_name {type [member_name] : width; };一般定义结构体&#xff0c;成员都是int、char等类型&#xff0c;占用的空间大小是固定的在成员名称后用冒号来指定位宽&#xff0c;可以指定每个成员所占用空间&#xff0c;并且也不用受结构体成员起始…