目标检测——基于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 == 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. 效果展示

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTTP 协议、AJAX - 异步网络请求及跨域、同源策略

文章目录 一、HTTP 协议简述1. 协议的基本理解2. HTTP 协议的数据格式 二、Express 服务器1. Express 服务器的安装和启动2. Express 服务器的基本使用 三、AJAX 异步网络请求1. ES5 的 XMLHttpRequest 对象实现 AJAX 异步网络请求2. 利用 jQuery 库实现 AJAX 异步网络请求3. E…

使用 OpenCV 绘制线条和矩形

OpenCV 是一个功能强大的计算机视觉库,它不仅提供了丰富的图像处理功能,还支持图像的绘制。绘制简单的几何图形(如线条和矩形)是 OpenCV 中常见的操作。在本篇文章中,我们将介绍如何使用 OpenCV 在图像上绘制线条和矩形…

【每日学点鸿蒙知识】上架流程、h5返回收拾拦截、两个枚举类型之间转换、hvigorw命令、绘制本地图片

1、HarmonyOS 上架流程? 上架流程,请参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-publish-app-V5 上架的一些条件,也请 这边悉知,参考链接:https://developer.huawe…

使用腾讯云CVM搭建 K8s + Docker + Harbor :部署SpringBoot应用与配置指南

在现代云原生应用的开发和部署过程中,容器化技术已经成为主流,而 Kubernetes(K8s)则是容器编排的绝对领导者。为了高效地管理和分发容器镜像,拥有一个可靠的私有镜像仓库是每个开发者和运维工程师不可或缺的工具。Dock…

第5章 组合计数与离散概率

2024年12月25日 5.1 基本原理 5.1.1 加法原理 5.1.2 乘法原理 5.2 排列与组合 5.2.1 排列 5.2.2 组合 5.3 排列组合生成算法 5.3.1 排列生成算法 5.3.2 组合生成算法 5.4 广义的排列和组合 5.5 二项式系数和组合恒等式 5.5.1 二项式定理 5.5.2 组合恒等式 5.6 鸽笼…

oscp备战系列-Kioptrix2014

文章目录 一、信息收集二、漏洞探测三、漏洞利用四、后渗透 一、信息收集 主机探测 nmap 192.168.30.0/24 -sP端口及版本探测 nmap 192.168.30.199 -sV可以看到开放了80,8080端口,采用apache 2.2.21 mod_ssl2.2.21 openssl0.9.8q WebDAV2 php5.3.8 O…

sqli-labs关卡记录13

同样还是post型,按照常规的方法,抓包,找到注入点: updatexml(1,concat(0x7e,substr((select group_concat(username,password)from users),31,30),0x7e),1)-- 这里找到注入点,闭合方式为)类型,然后就是判断…

操作系统(23)外存的存储空间的管理

一、外存的基本概念与特点 定义:外存,也称为辅助存储器,是计算机系统中用于长期存储数据的设备,如硬盘、光盘、U盘等。与内存相比,外存的存储容量大、成本低,但访问速度相对较慢。特点:外存能够…

matrix-breakout-2-morpheus

将这一关的镜像导入虚拟机,出现以下页面表示导入成功 以root身份打开kali终端,输入以下命令,查看靶机ip arp-scan -l 根据得到的靶机ip,浏览器访问进入环境 我们从当前页面没有得到有用的信息,尝试扫描后台 发现有一个…

最新的强大的文生视频模型Pyramid Flow 论文阅读及复现

《PYRAMIDAL FLOW MATCHING FOR EFFICIENT VIDEO GENERATIVE MODELING》 论文地址:2410.05954https://arxiv.org/pdf/2410.05954 项目地址: jy0205/Pyramid-Flow: 用于高效视频生成建模的金字塔流匹配代码https://github.com/jy0205/Pyram…

RSICV国产芯片之CHV208

1. 芯片选型分析的对比维度 分析或者对标应用的芯片替代思路 1.1 内核/主频/存储空间支持 内核能力/指令集支持(考虑工具链兼容性); 主频:对比计算能力是否满足基本要求 存储:内存--数据搬移空间决定数据运算的…

7. petalinux 根文件系统配置(package group)

根文件系统配置(Petalinux package group) 当使能某个软件包组的时候,依赖的包也会相应被使能,解决依赖问题,在配置页面的help选项可以查看需要安装的包 每个软件包组的功能: packagegroup-petalinux-audio包含与音…

基于Spring Boot的个人健康管理系统

一、系统背景与意义 随着现代生活节奏的加快和人们健康意识的日益增强,个人健康管理成为了人们关注的焦点。然而,传统的健康管理方式往往依赖于纸质记录、定期体检等手段,不仅效率低下,而且难以实现对健康数据的持续跟踪和深入分…

上手教程:使用Terraform打造弹性VPC架构

最近Akamai发布的虚拟专用云(VPC)功能提供了一种隔离的网络,让云资源可以用私密的方式进行通信。 关于Akamai VPC功能,最棒的地方在于它有着极高的灵活性。用户可以通过Cloud Manager、开发人员工具(如CLI&#xff09…

要查询 `user` 表中 `we_chat_subscribe` 和 `we_chat_union_id` 列不为空的用户数量

文章目录 1、we_chat_subscribe2、we_chat_union_id 1、we_chat_subscribe 要查询 user 表中 we_chat_subscribe 列不为空的用户数量,你可以使用以下 SQL 查询语句: SELECT COUNT(*) FROM user WHERE we_chat_subscribe IS NOT NULL;解释: …

【论文复现】进行不同视角图像的拼接

📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀ 进行不同视角图像的拼接 背景描述算法简介SIFT算法原理代码原理代码部署核心代码拼接结果其他的图片如何进行拼接? 修改内容&…

xxl-job 简单的入门到实战

本文是参考官方文档自己实践一次,纯享版,大致也是作者边写博客边去跟着官方文档实现 一、前期准备 1、官网地址 GitHub地址: GitHub - xuxueli/xxl-job: A distributed task scheduling framework.(分布式任务调度平台XXL-JOB&…

数字后端培训项目Floorplan常见问题系列专题续集1

今天继续给大家分享下数字IC后端设计实现floorplan阶段常见问题系列专题。这些问题都是来自于咱们社区IC后端训练营学员提问的问题库。目前这部分问题库已经积累了4年了,后面会陆续分享这方面的问题。 希望对大家的数字后端学习和工作有所帮助。 数字后端项目Floor…

江苏捷科云:可视化平台助力制造企业智能化管理

公司简介 江苏捷科云信息科技有限公司(以下简称“捷科”)是一家专注于云平台、云储存、云管理等产品领域的创新型企业,集研发、生产和销售于一体,致力于在网络技术领域打造尖端品牌。在推动制造业企业数字化转型的进程中&#xf…

【视觉惯性SLAM:对极几何】

对极几何(Epipolar Geometry)介绍 对极几何是立体视觉中的核心内容之一,它描述了两个相机在观察同一个三维场景时,成像平面之间的几何关系。对极几何能够约束图像中对应点的位置关系,是双目立体匹配、三维重建、以及位…