YOLOv5实战记录05 Pyside6可视化界面

2024-04-07 11:28

本文主要是介绍YOLOv5实战记录05 Pyside6可视化界面,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

个人打卡,慎看。

指路大佬:【手把手带你实战YOLOv5-入门篇】YOLOv5 Pyside6可视化界面_哔哩哔哩_bilibili

零、虚拟环境迁移路径后pip报错解决

yolov5-master文件夹我换位置后,无法pip install了。解决如下:

  • activate.bat中修改:@set "VIRTUAL_ENV=D:\yolov5-master\venv"
  • activate中修改:VIRTUAL_ENV='D:\yolov5-master\venv'
  • 更新pip:python -m pip install --upgrade pip

参考:Python 虚拟环境迁移路径后pip报错解决记录_pybot移动路径后-CSDN博客

【建议挂v,速度会快】

一、环境安装

  • 下载Pyside6:  pip install pyside6

我的pyside6不在Python.exe的上级文件夹的子目录下,packages和python.exe的位置也不同,发现解释器的位置设置错了,之前一直提示我Invalid,我也没有注意。

一般python.exe和site-packages的位置关系是,python.exe和它的上级在同一文件夹下。

比如anaconda下python.exe, lib

lib下site-packages ,也可以输入以下命令,查找site-packages的位置。

import site
print(site.getsitepackages())

以后安装了包,但是无法import,也可以查找site-packages的位置,很有可能这里面没有那个包。是python.exe选取的错误,修改为对应的python.exe即可。

  • 找到pyside6/designer.exe,将快捷方式发送到桌面。
  • up主用vscode安装了qt for python插件,但是我使用的是Pycharm,vscode不熟练,在pycharm中,设置setting->tools->external tools,点击+ ,添加,在Program中,输入designer.exe的位置。name和group随便设置,点击ok。

二、设计UI

  1. 新建mainwindow
  2. 把两个textlabel拖到mainwindow中【存放图片】,用vertical line隔离他们。拖两个pushbutton【按钮】。
  3. 勾选scaledcontents可以实现label中存放内容缩放。将alignment设置水平中心对齐。
  4. 修改对象的名字,便于记忆。比如label1改成input
  5. 保存到yolov5-master文件夹下,修改名字为main_window

三、将ui转换成py

添加external tool

我的血泪教训,改这个错改了40min:

  1. program不要选site-packages\Pyside6\uic.exe 这样转换出来的结果可能是C++代码。
  2. 选\Scripts\pyside6-uic.exe这个文件

  • Program: D:\anaconda\Scripts\pyside6-uic.exe 【输入自己的pyside6-uic.exe文件路径】
  • Arguments: $FileName$ -o $FileNameWithoutExtension$.py
  • working directory: $FileDir$

四、调用mainwindow

import sysfrom PySide6.QtWidgets import QMainWindow, QApplicationfrom main_window import Ui_MainWindow
#这里的main_window是你的ui转换成的py名字
#Ui_MainWindow是main_window里的class名字class MainWindow(QMainWindow,Ui_MainWindow):def __init__(self):super(MainWindow,self).__init__()   #self后不要加(),我加了()报错无法调用mainwindowself.setupUi(self)if __name__=="__main__":app=QApplication(sys.argv)window1 = MainWindow()window1.show()app.exec()

运行上面的指令即可弹出UI设计界面。

五、关联按钮和代码

bing_slots()函数负责绑定。det_image和pushButton_2【忘改了】是那两个按钮的名字。

import sysfrom PySide6.QtWidgets import QMainWindow, QApplication,QFileDialog
#QFileDialog可以访问文件资源管理器from main_window import Ui_MainWindowclass MainWindow(QMainWindow,Ui_MainWindow):def __init__(self):super(MainWindow,self).__init__()self.setupUi(self)self.bind_slots()  #不要忘记调用,不写这句话无法显示。def open_image(self):print("点击显示图片!")def open_video(self):print("点击显示视频!")def bind_slots(self):#绑定self.det_image.clicked.connect(self.open_image)self.pushButton_2.clicked.connect(self.open_video)if __name__=="__main__":app=QApplication(sys.argv)window1 = MainWindow()window1.show()app.exec()

六、获取图片

  • 一开始无法显示,我设置QPixmap("./datasets/images/train/30.jpg")发现可以显示,于是判断是filepath格式的问题;
  • QPixmap的参数是string类型的。打印file_path[0]发现打印出来的仍然是list格式。
  • 于是转换list为string类型。filePath=','.join(file_path[0])
#与上个代码省略了相同的部分,方便理解。from PySide6.QtGui import QPixmap
#显示图片def open_image(self):file_path=QFileDialog.getOpenFileNames(self,dir="./datasets/images/train",filter="*.jpg;*.png")#设置从dir里找图片, filter分号隔离不同格式#file_path返回的是有两个元素的数组,我们运行后,发现第一个元素是路径,第二个元素是格式。我们只输出路径。if file_path[0]:filePath=','.join(file_path[0])print(file_path[0])print(filePath)self.input.setPixmap(QPixmap(filePath))  #图片显示

七、训练图片

  • 首先,遇到了问题,我运行页面卡住了,一直在下载某个包,经查找,发现是下面这行代码的问题。我运行提示卡在了“'Downloading torch-2.2.2-cp310-cp310-win_amd64.whl (198.6 MB)”,
  • model = torch.hub.load("./","custom",path="runs/train/exp2/weights/best.pt",trust_repo=True, source="local") 运行这行代码时卡住了,其他代码不会卡。
  • 已解决:下载几个包即可:pip install torch torchvision torchaudio
  • 参考:通过pip安装pytorch超时问题解决 - 知乎 (zhihu.com)

运行代码:

import sys
import torch
from PySide6.QtWidgets import QMainWindow, QApplication,QFileDialog
#QFileDialog可以访问文件资源管理器from PySide6.QtGui import QPixmap,QImage
#显示图片from main_window import Ui_MainWindowdef convert2QImage(img):height,width,channel=img.shapereturn QImage(img,width,height,width*channel,QImage.Format_RGB888)class MainWindow(QMainWindow,Ui_MainWindow):def __init__(self):super(MainWindow,self).__init__()self.setupUi(self)self.model=torch.hub.load("./","custom",path="runs/train/exp2/weights/best.pt",source="local")self.bind_slots()  #不要忘记调用,不写这句话无法显示def image_pred(self,filePath):results=self.model(filePath)image=results.render()[0]return convert2QImage(image)#检测后的图片def open_image(self):file_path=QFileDialog.getOpenFileNames(self,dir="./datasets/images/train",filter="*.jpg;*.png")#设置从dir里找图片, filter分号隔离不同格式#file_path返回的是有两个元素的数组,我们运行后,发现第一个元素是路径,第二个元素是格式。我们只输出路径。if file_path[0]:filePath=','.join(file_path[0])qimage=self.image_pred(filePath)self.input.setPixmap(QPixmap(filePath))self.output.setPixmap(QPixmap.fromImage(qimage))def open_video(self):print("点击显示视频!")def bind_slots(self):#绑定self.det_image.clicked.connect(self.open_image)self.pushButton_2.clicked.connect(self.open_video)if __name__=="__main__":app=QApplication(sys.argv)window1 = MainWindow()window1.show()app.exec()

八、训练视频

仍然遇到了报错:Traceback (most recent call last):
  File "D:\yolov5-master\yolov5-master\base_ui.py", line 57, in open_video
    self.input.setPixmap(QPixmap(convert2QImage(filePath)))
  File "D:\yolov5-master\yolov5-master\base_ui.py", line 13, in convert2QImage
    height,width,channel=imag.shape
AttributeError: 'str' object has no attribute 'shape'

但是我训练图片时, height,width,channel=imag.shape这行代码就没有出现问题,于是查找包含改行代码的函数调用的参数,果然写错了self.input.setPixmap(QPixmap(convert2QImage(frame)))是frame不是filePath。 一定要细心!!!

import sys
import cv2
import torch
from PySide6.QtWidgets import QMainWindow, QApplication,QFileDialog
#QFileDialog可以访问文件资源管理器from PySide6.QtGui import QPixmap,QImage
#显示图片from main_window import Ui_MainWindowdef convert2QImage(imag):height,width,channel=imag.shapereturn QImage(imag,width,height,width*channel,QImage.Format_RGB888)class MainWindow(QMainWindow,Ui_MainWindow):def __init__(self):super(MainWindow,self).__init__()self.setupUi(self)self.model=torch.hub.load("./","custom",path="runs/train/exp2/weights/best.pt",source="local")self.bind_slots()  #不要忘记调用,不写这句话无法显示def image_pred(self,filePath):results=self.model(filePath)image=results.render()[0]return convert2QImage(image)#检测后的图片def video_pred(self,img):results=self.model(img)image=results.render()[0]return convert2QImage(image)def open_image(self):file_path=QFileDialog.getOpenFileNames(self,dir="./datasets/images/train",filter="*.jpg;*.png")#设置从dir里找图片, filter分号隔离不同格式#file_path返回的是有两个元素的数组,我们运行后,发现第一个元素是路径,第二个元素是格式。我们只输出路径。if file_path[0]:filePath=','.join(file_path[0])qimage=self.image_pred(filePath)self.input.setPixmap(QPixmap(filePath))self.output.setPixmap(QPixmap.fromImage(qimage))def open_video(self):#视频检测是一帧一帧地检测,利用opencv抽帧。file_path = QFileDialog.getOpenFileNames(self, dir="./datasets", filter="*.mp4")if file_path[0]:filePath=','.join(file_path[0])print(filePath)video = cv2.VideoCapture(filePath)while True:ret,frame=video.read()if not ret:breakframe = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)qimage=self.video_pred(frame)self.input.setPixmap(QPixmap(convert2QImage(frame)))self.output.setPixmap(QPixmap.fromImage(qimage))print("点击显示视频!")def bind_slots(self):#绑定self.det_image.clicked.connect(self.open_image)self.pushButton_2.clicked.connect(self.open_video)if __name__=="__main__":app=QApplication(sys.argv)window1 = MainWindow()window1.show()app.exec()

不过我运行后很慢,并且只显示了视频最后一帧的检测结果和原图片。

问题:界面刷新不及时。

解决:加入计时器from PySide6.QtCore import QTimer
 

import sys
import cv2
import torch
from PySide6.QtWidgets import QMainWindow, QApplication,QFileDialog
#QFileDialog可以访问文件资源管理器from PySide6.QtGui import QPixmap,QImage
#显示图片
from PySide6.QtCore import QTimer
#计时器from main_window import Ui_MainWindowdef convert2QImage(imag):height,width,channel=imag.shapereturn QImage(imag,width,height,width*channel,QImage.Format_RGB888)class MainWindow(QMainWindow,Ui_MainWindow):def __init__(self):super(MainWindow,self).__init__()self.setupUi(self)self.model=torch.hub.load("./","custom",path="runs/train/exp2/weights/best.pt",source="local")self.timer=QTimer()self.timer.setInterval(100) #时间间隔。默认单位毫秒ms ,可以设置的小一点儿,视频更加丝滑。self.bind_slots()  #不要忘记调用,不写这句话无法显示def image_pred(self,filePath):results=self.model(filePath)image=results.render()[0]return convert2QImage(image)#检测后的图片def video_pred(self):ret, frame = self.video.read()if not ret:self.timer.stop()else:frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)self.input.setPixmap(QPixmap.fromImage(convert2QImage(frame)))#放在这儿而不是self.output上面,因为可能受检测的图像影响。在检测之前先显示出来。results=self.model(frame)image=results.render()[0]self.output.setPixmap(QPixmap.fromImage(convert2QImage(image)))def open_image(self):file_path=QFileDialog.getOpenFileNames(self,dir="./datasets/images/train",filter="*.jpg;*.png")#设置从dir里找图片, filter分号隔离不同格式#file_path返回的是有两个元素的数组,我们运行后,发现第一个元素是路径,第二个元素是格式。我们只输出路径。if file_path[0]:filePath=','.join(file_path[0])qimage=self.image_pred(filePath)self.input.setPixmap(QPixmap(filePath))self.output.setPixmap(QPixmap.fromImage(qimage))def open_video(self):#视频检测是一帧一帧地检测,利用opencv抽帧。file_path = QFileDialog.getOpenFileNames(self, dir="./datasets", filter="*.mp4")if file_path[0]:filePath=','.join(file_path[0])print(filePath)self.video = cv2.VideoCapture(filePath)self.timer.start()# while True:#     ret,frame=video.read()##     if not ret:#         break#     frame = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)#     qimage=self.video_pred(frame)#     self.input.setPixmap(QPixmap(convert2QImage(frame)))#     self.output.setPixmap(QPixmap.fromImage(qimage))print("点击显示视频!")def bind_slots(self):#绑定self.det_image.clicked.connect(self.open_image)self.pushButton_2.clicked.connect(self.open_video)self.timer.timeout.connect(self.video_pred)if __name__=="__main__":app=QApplication(sys.argv)window1 = MainWindow()window1.show()app.exec()

仍然存在问题,如果再点击“图片检测”按钮,不会停下,这是因为计时器没有停。

解决方案:在打开图片时,关闭计时器,def open_image(self): self.timer.stop()

全部代码:

import sys
import cv2
import torch
from PySide6.QtWidgets import QMainWindow, QApplication,QFileDialog
#QFileDialog可以访问文件资源管理器from PySide6.QtGui import QPixmap,QImage
#显示图片
from PySide6.QtCore import QTimer
#计时器from main_window import Ui_MainWindowdef convert2QImage(imag):height,width,channel=imag.shapereturn QImage(imag,width,height,width*channel,QImage.Format_RGB888)class MainWindow(QMainWindow,Ui_MainWindow):def __init__(self):super(MainWindow,self).__init__()self.setupUi(self)self.model=torch.hub.load("./","custom",path="runs/train/exp2/weights/best.pt",source="local")self.timer=QTimer()self.timer.setInterval(1) #默认单位毫秒msself.bind_slots()  #不要忘记调用,不写这句话无法显示def image_pred(self,filePath):results=self.model(filePath)image=results.render()[0]return convert2QImage(image)#检测后的图片def video_pred(self):ret, frame = self.video.read()if not ret:self.timer.stop()else:frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)self.input.setPixmap(QPixmap.fromImage(convert2QImage(frame)))# 放在这儿而不是self.output上面,因为可能受检测的图像影响。在检测之前先显示出来。results=self.model(frame)image=results.render()[0]self.output.setPixmap(QPixmap.fromImage(convert2QImage(image)))def open_image(self):self.timer.stop()file_path=QFileDialog.getOpenFileNames(self,dir="./datasets/images/train",filter="*.jpg;*.png")#设置从dir里找图片, filter分号隔离不同格式#file_path返回的是有两个元素的数组,我们运行后,发现第一个元素是路径,第二个元素是格式。我们只输出路径。if file_path[0]:filePath=','.join(file_path[0])qimage=self.video_pred(filePath)self.input.setPixmap(QPixmap(filePath))self.output.setPixmap(QPixmap.fromImage(qimage))def open_video(self):#视频检测是一帧一帧地检测,利用opencv抽帧。file_path = QFileDialog.getOpenFileNames(self, dir="./datasets", filter="*.mp4")if file_path[0]:filePath=','.join(file_path[0])print(filePath)self.video = cv2.VideoCapture(filePath)self.timer.start()# while True:#     ret,frame=video.read()##     if not ret:#         break#     frame = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)#     qimage=self.video_pred(frame)#     self.input.setPixmap(QPixmap(convert2QImage(frame)))#     self.output.setPixmap(QPixmap.fromImage(qimage))print("点击显示视频!")def bind_slots(self):#绑定self.det_image.clicked.connect(self.open_image)self.pushButton_2.clicked.connect(self.open_video)self.timer.timeout.connect(self.video_pred)if __name__=="__main__":app=QApplication(sys.argv)window1 = MainWindow()window1.show()app.exec()

九、复盘

  1. 首先利用Pyside6的designer设计了UI界面。两个button,两个label,一条线。导出生成ui文件。将ui文件编译生成成py文件,注意external tool选的是pyside6-uic.exe,不是uic.exe!!!
  2. 构建程序,设计函数:初始化;绑定按键与函数事件;打开图片;打开视频;图片预测;视频预测【预测部分利用了torch.hub,实际上是对每一帧的图片进行预测,利用了计时器】

 效果如下:【我之前标注的label很草率,所以效果很差,不过迈出了从0到1的步子,我很开心了。】

pyside6可视化页面预测


今天最大的收获就是可以平静地对待报错了,之前从大一开始每次改报错都特别烦躁,今天竟然可以平静地坐着改几个小时的bug。我之前特别怵头以后做机器学习、python相关的研究,现在不怕了。

要相信你遇到的问题,别人也遇到过,并且他们解决了。

如果别人没有遇到过,那正好,你会是第一个发现问题并解决的人,之后的人都会借鉴你的解决方案。

这篇关于YOLOv5实战记录05 Pyside6可视化界面的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/882472

相关文章

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题

《Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题》在爬虫工程里,“HTTPS”是绕不开的话题,HTTPS为传输加密提供保护,同时也给爬虫带来证书校验、... 目录一、核心问题与优先级检查(先问三件事)二、基础示例:requests 与证书处理三、高并发选型:

docker编写java的jar完整步骤记录

《docker编写java的jar完整步骤记录》在平常的开发工作中,我们经常需要部署项目,开发测试完成后,最关键的一步就是部署,:本文主要介绍docker编写java的jar的相关资料,文中通过代... 目录all-docker/生成Docker打包部署文件配置服务A的Dockerfile (a/Docke

Oracle Scheduler任务故障诊断方法实战指南

《OracleScheduler任务故障诊断方法实战指南》Oracle数据库作为企业级应用中最常用的关系型数据库管理系统之一,偶尔会遇到各种故障和问题,:本文主要介绍OracleSchedul... 目录前言一、故障场景:当定时任务突然“消失”二、基础环境诊断:搭建“全局视角”1. 数据库实例与PDB状态2

Git进行版本控制的实战指南

《Git进行版本控制的实战指南》Git是一种分布式版本控制系统,广泛应用于软件开发中,它可以记录和管理项目的历史修改,并支持多人协作开发,通过Git,开发者可以轻松地跟踪代码变更、合并分支、回退版本等... 目录一、Git核心概念解析二、环境搭建与配置1. 安装Git(Windows示例)2. 基础配置(必

MySQL使用EXISTS检查记录是否存在的详细过程

《MySQL使用EXISTS检查记录是否存在的详细过程》EXISTS是SQL中用于检查子查询是否返回至少一条记录的运算符,它通常用于测试是否存在满足特定条件的记录,从而在主查询中进行相应操作,本文给大... 目录基本语法示例数据库和表结构1. 使用 EXISTS 在 SELECT 语句中2. 使用 EXIS

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可