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

news2024/12/26 8:14:45

目录

  • 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 == 0
        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_path
                try:
                    for model, tm, im in self.predict():
                        print(self.save_dir)
                        self.model = model
                        det = self.predictor.output['det']
                        self.det = det

                        # 存储结果,向tableview和comboBox中添加信息
                        self.image_detections[self.fileName1] = det # 存储检测结果
                        self.image_path[filename] = file_path
                        self.image_tm[self.fileName1] = tm
                        self.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] = 0
                            class_count[class_name] += 1

                            #创建新标签
                            new_class_name = f"{class_name}{class_count[class_name] - 1}" if class_count[class_name] > 1 else class_name
                            new_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_classes
                        self.image_sum[self.fileName1] = self.sum
                        self.image = self.predictor.annotator.result() # 标记所有的结果图
                    
                        self.label_6.setText(str(self.sum)) # 总目标数
                        self.label_8.setText(str(round(tm*1000, 3))+'ms') # 用时


                        # 将numpy图片转成QImage
                        height, width, channels = self.image.shape
                        bytes_per_line = 3 * width
                        q_image = QImage(self.image.data, width, height, bytes_per_line, QImage.Format_BGR888)
                        # Convert QImage to QPixmap
                        pixmap = 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 text
                except 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_path
                try:
                    for model, tm, im in self.predict():
                        print(self.save_dir)
                        self.model = model
                        det = self.predictor.output['det']
                        self.det = det

                        # 存储结果,向tableview和comboBox中添加信息
                        self.image_detections[self.fileName1] = det # 存储检测结果
                        self.image_path[filename] = file_path
                        self.image_tm[self.fileName1] = tm
                        self.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] = 0
                            class_count[class_name] += 1

                            #创建新标签
                            new_class_name = f"{class_name}{class_count[class_name] - 1}" if class_count[class_name] > 1 else class_name
                            new_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_classes
                        self.image_sum[self.fileName1] = self.sum
                        self.image = self.predictor.annotator.result() # 标记所有的结果图
                    
                        self.label_6.setText(str(self.sum)) # 总目标数
                        self.label_8.setText(str(round(tm*1000, 3))+'ms') # 用时


                        # 将numpy图片转成QImage
                        height, width, channels = self.image.shape
                        bytes_per_line = 3 * width
                        q_image = QImage(self.image.data, width, height, bytes_per_line, QImage.Format_BGR888)
                        # Convert QImage to QPixmap
                        pixmap = 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 text
                except Exception as e:
                    print(f"Error processing {filename}: {e}")

5.3 视频检测和摄像头检测

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

6. 效果展示

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

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

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

相关文章

云边端架构的优势是什么?面临哪些挑战?

一、云边端架构的优势 降低网络延迟:在传统集中式架构中,数据需传输到云计算中心处理,导致网络延迟较高。而云边端架构将计算和存储推向边缘设备,可在离用户更近的地方处理数据,大大降低了网络延迟,提升了用…

微机接口课设——基于Proteus和8086的打地鼠设计(8255、8253、8259)

原理图设计 汇编代码 ; I/O 端口地址定义 IOY0 EQU 0600H IOY1 EQU 0640H IOY2 EQU 0680HMY8255_A EQU IOY000H*2 ; 8255 A 口端口地址 MY8255_B EQU IOY001H*2 ; 8255 B 口端口地址 MY8255_C EQU IOY002H*2 ; 8255 C 口端口地址 MY8255_MODE EQU IOY003H*2 ; …

Origin教程008:Origin绘制热图

文章目录 练习数据热图练习数据 https://download.csdn.net/download/WwLK123/90185283热图 使用拖拽的方式导入数据: 然后【单击】全选数据: 然后选择【绘图】->【等高线图】->【带标签热图】: 然后勾选【Y数据跨列】: 点击【确定

LabVIEW数字式气压计自动检定系统

开发了一个基于LabVIEW开发的数字式气压计自动检定系统。在自动化检定PTB220和PTB210系列数字气压计,通过优化硬件组成和软件设计,实现高效率和高准确度的检定工作,有效降低人力成本并提升操作准确性。 项目背景 随着自动气象站的广泛部署&a…

阿里云镜像服务使用指南

阿里云容器镜像服务ACR(Alibaba Cloud Container Registry)是面向容器镜像、Helm Chart等符合OCI标准云原生制品安全托管及高效分发平台。ACR企业版支持全球同步加速、大规模和大镜像分发加速、多代码源构建加速等全链路加速能力,与容器服务A…

【Ambari】使用 Knox 进行 LDAP 身份认证

目录 一、knox介绍 二、Ambari配置LDAP认证 三、验证Knox网关 3.1YARNUI 3.2 HDFSUI 3.3 HDFS RestFULL 3.4 SparkHistoryserver 3.5 HBASEUI 一、knox介绍 Apache Knox网关是一个用于与Apache Hadoop部署的REST api和ui交互的应用程序网关。Knox网关为所有与Apache Ha…

Fiddler v5.0.2最新专业网络抓包工具简体中文版

前言 Fiddler抓包工具一个非常专业且已经翻译成中文的网络调试帮手。它就像一个超级监视器,能帮你看到电脑和互联网之间所有通过HTTP协议传输的信息。比如,当你在网上冲浪时,它可以记录下你和网站之间交换的所有“小纸条”,比如网…

我的 2024 年终总结

2024 年,我离开了待了两年的互联网公司,来到了一家聚焦教育机器人和激光切割机的公司,没错,是一家硬件公司,从未接触过的领域,但这还不是我今年最重要的里程碑事件 5 月份的时候,正式提出了离职…

汽车网络安全渗透测试

产品和企业IT的融合引发了新的网络安全风险,从功能安全到数据隐私都面临潜在威胁。汽车行业正在使用各种方法进行安全检测和验证,但传统的安全测试中漏洞检测低效且不完整。Vector带来一种使用更少测试案例的增强型灰盒渗透测试,能够在提高覆…

C#WPF基础介绍/第一个WPF程序

什么是WPF WPF(Windows Presentation Foundation)是微软公司推出的一种用于创建窗口应用程序的界面框架。它是.NET Framework的一部分,提供了一套先进的用户界面设计工具和功能,可以实现丰富的图形、动画和多媒体效果。 WPF 使用…

【EtherCATBasics】- KRTS C++示例精讲(2)

EtherCATBasics示例讲解 目录 EtherCATBasics示例讲解结构说明代码讲解 项目打开请查看【BaseFunction精讲】。 结构说明 EtherCATBasics:应用层程序,主要用于人机交互、数据显示、内核层数据交互等; EtherCATBasics.h : 数据定义…

秒验简介与下载说明

秒验简介与下载说明 产品概述 秒验是一款帮助开发者实现一键验证功能的产品,从根源上降低企业验证成本, 有效提高拉新转化率,降低因验证带来的流失率,3秒完成手机号验证 SDK信息 下载SDK 下载地址 SDK提供Maven和pod引入两种方…

算法学习(17)—— FloodFill算法

目录 关于FloodFill算法 部分OJ题详解 733. 图像渲染 200. 岛屿数量 695. 岛屿的最大面积 130. 被围绕的区域 417. 太平洋大西洋水流问题 529. 扫雷问题 LCR130. 衣橱整理 关于FloodFill算法 爆搜,深搜,回溯的算法原理并不难,这类题…

美国辅料查询之FDA批准药用辅料数据库(IID数据库)

药用辅料的性质很大程度上决定了制剂的性质,每一种新的药用辅料的问世,都会为制剂技术的发展带来新的机遇,每一种药用辅料都可能让制剂研发员开发出新剂型药物,所以在药物制剂研发过程中,药用辅料的信息调研是不可或缺…

SpringAI人工智能开发框架006---SpringAI多模态接口_编程测试springai多模态接口支持

可以看到springai对多模态的支持. 同样去创建一个项目 也是跟之前的项目一样,修改版本1.0.0 这里 然后修改仓库地址,为springai的地址 然后开始写代码

【ELK】filebeat采集数据输出到kafka指定topic

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 背景filebeat主体配置filebeat.inputs部分filebeat.output部分 filebeat完整配置 背景 今天收到需求,生产环境中通需要优化filebeat的输出,…

知识图谱+大模型:打造全新智慧城市底层架构

在数字化时代,智慧城市的建设正迎来新一轮的变革。本文将探讨如何结合知识图谱和大模型技术,构建智慧城市的全新底层架构,以应对日益增长的数据量和复杂性,提升城市管理的智能化水平。 知识图谱:智慧城市的知识库 知识…

网络安全 | 云计算中的数据加密与访问控制

网络安全 | 云计算中的数据加密与访问控制 一、前言二、云计算概述2.1 云计算的定义与特点2.2 云计算的服务模式2.3 云计算的数据安全挑战 三、数据加密技术在云计算中的应用3.1 对称加密算法3.2 非对称加密算法3.3 混合加密算法 四、云计算中的访问控制模型4.1 基于角色的访问…

计算机毕业设计Python+卷积神经网络租房推荐系统 租房大屏可视化 租房爬虫 hadoop spark 58同城租房爬虫 房源推荐系统

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

攻防世界 - Web - Level 1 unseping

关注这个靶场的其它相关笔记:攻防世界(XCTF) —— 靶场笔记合集-CSDN博客 0x01:Write UP 本关是一个 PHP 代码审计关卡,考察的是 PHP 反序列化漏洞以及命令执行的一些绕过手段,下面笔者将带你一步步过关。…