赞
踩
主要将自己基于PYQT5和YOLOv8进行检测界面制作的全程流程做一个总结,进行分享,其中对于自己借鉴学习的内容就不再发文章书写了,会将借鉴的文章链接贴在下面致敬,大家直接点击链接进行学习就好.
以下是我的项目代码:
mbl1234/YOLOv8_PYQT5_GUI: 基于YOLOv8和PYQT5的检测界面 (github.com)
想直接使用我的项目,避免YOLOv8的版本变化,可以直接使用我当时的版本进行模型训练,再将模型直接嵌入项目代码,进行测试使用就行:
mbl1234/YOLOv8_GUI: YOLOv8训练网络,与YOLOv8_PYQT5_GUI相关联 (github.com)
这一篇是基于YOLOv5和PYQT5进行检测界面的制作的内容:
(超详细流程-适合小白入门-一篇就够)基于YOLOv5和PYQT5进行检测界面的制作-CSDN博客
我是基于python语言,pycharm编译器,Anaconda包管理器.如果是初学者以上安装可以直接看此博主的链接进行学习:
目标检测---教你利用yolov5训练自己的目标检测模型_目标检测 教你利用-CSDN博客
基本内容安装成功后,进行PYQT5安装和配置,参考此博主链接进行学习:
[主要是在pycharm编译器中配置:
QT Designer(用于界面的可视化制作)
PyUIC(将QT Designer生成的.ui文件转换为编译器可以通过代码进行编译的.py文件)
Pyrcc(用于将QT Designer中引用图像文件生成的.qrc文件转换成.py文件,以便上一个.ui转换成的.py文件可以进行导入)]
PyQt5保姆级入门教程——从安装到使用_pyqt5教程-CSDN博客
整体基本安装配置完成之后,进行QT Designer的学习,进行检测界面的制作,参考此博主的链接进行学习:
GUI设计 PyQt5学习(二)——QtDesigner的基本使用方法_qt的designer在哪里-CSDN博客
Python-GUI编程-PyQt5 (少)_哔哩哔哩_bilibili
实验室项目展示用PyQt系列(2)设计基本流程、Qt Designer使用、界面中添加图片等_qt designer怎么显示图片-CSDN博客
基于YOLO系列代码和PYQT5进行GUI制作,可以参考此博主的链接进行学习:
使用PyQt5为YoloV5添加界面(一)_pyqt pyvista-CSDN博客
在代码跑动过程中,会遇到pycharm编译器中的GUI.py文件直接闪退不报错的问题,建议大家参考以下链接进行设置,直接会显示报错原因,方便进行修改:
解决pycharm调试Pyqt5异常退出,没有错误日志的问题_pyqt5界面无论登录错误还是成功都出现退出代码现象-CSDN博客
以上是项目目录,除了跑GUI文件YOLOv8中需要的文件外:
test文件夹中存放:测试YOLOv8_PYQT5_GUI所需要的权重文件和图像,用的都是官方权重和图像.
ui文件夹中存放:QT Designer制作的.ui文件和转换生成的.py文件.
ui_img文件夹中存放:QT Designer制作GUI界面需要的图像文件.
Detect_GUI.py文件主要是直接进入检测界面.
Login_GUI.py文件主要是从注册和登录界面进入检测界面.
userInfo.csv文件中主要存放注册界面生成的账号.
除了正常的登录和注册界面以外,检测界面主要能够完成以下任务:
模型加载,图像加载,图像保存,图像保存,应用退出
可以好好看看这段代码中的注释,对于各个功能模块所牵涉到的功能函数进行了备注.
其中在图像打开之后直接嵌入了模型调用命令行进行调用和检测.
- import sys
- import cv2
- from ultralytics.yolo.engine.model import YOLO
- from PyQt5 import QtCore, QtGui, QtWidgets
- from PyQt5.QtWidgets import *
- import ui_img.detect_images_rc
- class Ui_MainWindow(QMainWindow):
- def __init__(self):
- super(Ui_MainWindow, self).__init__()
- self.setWindowTitle("基于YOLOv8的检测演示软件V1.0")
- self.resize(1500, 1000)
- self.setStyleSheet("QWidget#centralwidget{background-image: url(:/detect_background/detect.JPG);}")
- self.centralwidget = QWidget()
- self.centralwidget.setObjectName("centralwidget")
-
- # 模型选择
- self.btn_selet_model = QtWidgets.QPushButton(self.centralwidget)
- self.btn_selet_model.setGeometry(QtCore.QRect(70, 810, 70, 70))
- self.btn_selet_model.setStyleSheet("border-image: url(:/detect_button_background/upload.png);")
- self.btn_selet_model.setText("")
- self.btn_selet_model.setObjectName("btn_selet_model")
- self.btn_selet_model.clicked.connect(self.seletModels)
-
- # 选择图像进行检测
- self.btn_detect_img = QtWidgets.QPushButton(self.centralwidget)
- self.btn_detect_img.setGeometry(QtCore.QRect(390, 810, 70, 70))
- self.btn_detect_img.setStyleSheet("border-image: url(:/detect_button_background/images.png);")
- self.btn_detect_img.setText("")
- self.btn_detect_img.setObjectName("btn_detect_img")
- self.btn_detect_img.clicked.connect(self.openImage)
-
- # 保存结果图像
- self.btn_save_img = QtWidgets.QPushButton(self.centralwidget)
- self.btn_save_img.setGeometry(QtCore.QRect(730, 810, 70, 70))
- self.btn_save_img.setStyleSheet("border-image: url(:/detect_button_background/save.png);")
- self.btn_save_img.setText("")
- self.btn_save_img.setObjectName("btn_save_img")
- self.btn_save_img.clicked.connect(self.saveImage)
-
- # 清除结果图像
- self.btn_clear_img = QtWidgets.QPushButton(self.centralwidget)
- self.btn_clear_img.setGeometry(QtCore.QRect(1050, 810, 70, 70))
- self.btn_clear_img.setStyleSheet("border-image: url(:/detect_button_background/delete.png);")
- self.btn_clear_img.setText("")
- self.btn_clear_img.setObjectName("btn_clear_img")
- self.btn_clear_img.clicked.connect(self.clearImage)
-
- # 退出应用
- self.btn_exit_app = QtWidgets.QPushButton(self.centralwidget)
- self.btn_exit_app.setGeometry(QtCore.QRect(1360, 810, 70, 70))
- self.btn_exit_app.setStyleSheet("border-image: url(:/detect_button_background/exit.png);")
- self.btn_exit_app.setText("")
- self.btn_exit_app.setObjectName("btn_exit_app")
- self.btn_exit_app.clicked.connect(self.exitApp)
-
- # 呈现原始图像
- self.label_show_yuanshi = QtWidgets.QLabel(self.centralwidget)
- self.label_show_yuanshi.setGeometry(QtCore.QRect(0, 80, 700, 700))
- self.label_show_yuanshi.setStyleSheet("background-color: rgb(255, 255, 255);")
- self.label_show_yuanshi.setObjectName("label_show_yuanshi")
-
- # 呈现结果图像
- self.label_show_jieguo = QtWidgets.QLabel(self.centralwidget)
- self.label_show_jieguo.setGeometry(QtCore.QRect(800, 80, 700, 700))
- self.label_show_jieguo.setStyleSheet("background-color: rgb(255, 255, 255);")
- self.label_show_jieguo.setObjectName("label_show_jieguo")
-
- # 呈现功能按键
- self.label_show_button = QtWidgets.QLabel(self.centralwidget)
- self.label_show_button.setGeometry(QtCore.QRect(0, 800, 1501, 141))
- self.label_show_button.setStyleSheet("background-color: rgb(255, 255, 255);")
- self.label_show_button.setText("")
- self.label_show_button.setObjectName("label_show_button")
-
- #编写模型加载
- self.edit_selet_model = QtWidgets.QLineEdit(self.centralwidget)
- self.edit_selet_model.setGeometry(QtCore.QRect(20, 890, 161, 40))
- font = QtGui.QFont()
- font.setFamily("Adobe 宋体 Std L")
- font.setPointSize(28)
- self.edit_selet_model.setFont(font)
- self.edit_selet_model.setLayoutDirection(QtCore.Qt.RightToLeft)
- self.edit_selet_model.setObjectName("edit_selet_model")
-
- #编写图像加载
- self.edit_detect_img = QtWidgets.QLineEdit(self.centralwidget)
- self.edit_detect_img.setGeometry(QtCore.QRect(350, 890, 161, 40))
- font = QtGui.QFont()
- font.setFamily("Adobe 宋体 Std L")
- font.setPointSize(28)
- self.edit_detect_img.setFont(font)
- self.edit_detect_img.setObjectName("edit_detect_img")
-
- #编写图像保存
- self.edit_save_img = QtWidgets.QLineEdit(self.centralwidget)
- self.edit_save_img.setGeometry(QtCore.QRect(690, 890, 161, 40))
- font = QtGui.QFont()
- font.setFamily("Adobe 宋体 Std L")
- font.setPointSize(28)
- self.edit_save_img.setFont(font)
- self.edit_save_img.setObjectName("edit_save_img")
-
- #编写图像清除
- self.edit_clear_img = QtWidgets.QLineEdit(self.centralwidget)
- self.edit_clear_img.setGeometry(QtCore.QRect(1000, 890, 161, 40))
- font = QtGui.QFont()
- font.setFamily("Adobe 宋体 Std L")
- font.setPointSize(28)
- self.edit_clear_img.setFont(font)
- self.edit_clear_img.setObjectName("edit_clear_img")
-
- #编写应用退出
- self.edit_exit_app = QtWidgets.QLineEdit(self.centralwidget)
- self.edit_exit_app.setGeometry(QtCore.QRect(1300, 890, 161, 40))
- font = QtGui.QFont()
- font.setFamily("Adobe 宋体 Std L")
- font.setPointSize(28)
- self.edit_exit_app.setFont(font)
- self.edit_exit_app.setObjectName("edit_exit_app")
-
- # 标题
- self.label_show_title = QtWidgets.QLabel(self.centralwidget)
- self.label_show_title.setGeometry(QtCore.QRect(190, 10, 1101, 80))
- font = QtGui.QFont()
- font.setFamily("Adobe 黑体 Std R")
- font.setPointSize(28)
- self.label_show_title.setFont(font)
- self.label_show_title.setStyleSheet("")
- self.label_show_title.setObjectName("label_show_title")
-
- self.label_show_button.raise_()
- self.btn_selet_model.raise_()
- self.btn_detect_img.raise_()
- self.btn_save_img.raise_()
- self.btn_clear_img.raise_()
- self.btn_exit_app.raise_()
- self.label_show_title.raise_()
- self.label_show_yuanshi.raise_()
- self.label_show_jieguo.raise_()
- self.edit_selet_model.raise_()
- self.edit_detect_img.raise_()
- self.edit_save_img.raise_()
- self.edit_clear_img.raise_()
- self.edit_exit_app.raise_()
-
- # 主窗口
- self.setCentralWidget(self.centralwidget)
- self.retranslateUi(self.centralwidget)
- QtCore.QMetaObject.connectSlotsByName(self.centralwidget)
-
- def retranslateUi(self, MainWindow):
- _translate = QtCore.QCoreApplication.translate
- MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
- self.label_show_title.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\"><span style=\" font-size:28pt; font-weight:600; color:#ffffff;\">基于YOLOv8的检测演示软件</span></p></body></html>"))
- self.label_show_yuanshi.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\"><span style=\" font-size:20pt;\">原始图像</span></p></body></html>"))
- self.label_show_jieguo.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\"><span style=\" font-size:20pt;\">检测图像</span></p></body></html>"))
- self.edit_selet_model.setText(_translate("MainWindow", "模型加载"))
- self.edit_detect_img.setText(_translate("MainWindow", "图像加载"))
- self.edit_save_img.setText(_translate("MainWindow", "图像保存"))
- self.edit_clear_img.setText(_translate("MainWindow", "图像清除"))
- self.edit_exit_app.setText(_translate("MainWindow", "应用退出"))
-
- # 模型选择函数
- def seletModels(self):
- self.openfile_name_model, _ = QFileDialog.getOpenFileName(self.btn_selet_model, '选择weights文件', '.', '权重文件(*.pt)')
- if not self.openfile_name_model:
- QMessageBox.warning(self, "Warning:", "打开权重失败", buttons=QMessageBox.Ok,)
- else:
- print('加载weights文件地址为:' + str(self.openfile_name_model))
- QMessageBox.information(self, u"Notice", u"权重打开成功", buttons=QtWidgets.QMessageBox.Ok)
-
- # 图像选择函数
- def openImage(self):
- name_list = []
- fname, _ = QFileDialog.getOpenFileName(self, '打开文件', '.', '图像文件(*.jpg)')
- self.fname = fname
- pixmap = QtGui.QPixmap(fname)
- self.label_show_yuanshi.setPixmap(pixmap)
- self.label_show_yuanshi.setScaledContents(True)
- img = cv2.imread(fname)
- # 引入模型
- model = YOLO(self.openfile_name_model)
- # 通过引用模型进行图像检测
- results = model.predict(source=self.fname)
- annotated_frame = results[0].plot()
- # 将图像数据转换为QImage格式
- height, width, channel = annotated_frame.shape
- bytes_per_line = 3 * width
- qimage = QtGui.QImage(annotated_frame.data, width, height, bytes_per_line, QtGui.QImage.Format_RGB888)
- self.qImg = qimage
- # 将QImage转换为QPixmap
- pixmap = QtGui.QPixmap.fromImage(qimage)
- self.label_show_jieguo.setPixmap(pixmap)
- self.label_show_jieguo.setScaledContents(True)
- return self.qImg
-
- # 图像保存函数
- def saveImage(self):
- fd, _ = QFileDialog.getSaveFileName(self, "保存图片", ".", "*.jpg")
- self.qImg.save(fd)
-
- # 图像清除函数
- def clearImage(self, stopp):
- result = QMessageBox.question(self, "Warning:", "是否清除本次检测结果", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
- if result == QMessageBox.Yes:
- self.label_show_yuanshi.clear()
- self.label_show_jieguo.clear()
- else:
- stopp.ignore()
-
- # 应用退出函数
- def exitApp(self, event):
- event = QApplication.instance()
- result = QMessageBox.question(self, "Notice:", "您真的要退出此应用吗", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
- if result == QMessageBox.Yes:
- event.quit()
- else:
- event.ignore()
-
- if __name__ == '__main__':
- app = QApplication(sys.argv)
- ui = Ui_MainWindow()
- ui.show()
- sys.exit(app.exec_())
登录界面中包含登录和检测,其中还需要导入你在QT Designer中制作的的登录注册界面的.ui文件转换成的.py文件
- import sys
- from datetime import datetime
- from PyQt5.QtWidgets import *
- from utils.id_utils import get_id_info, sava_id_info # 账号信息工具函数
- from lib.share import shareInfo # 公共变量名
- # 导入QT-Design生成的UI
- from ui.login_ui import Ui_Form
- from ui.registe_ui import Ui_Dialog
- # 导入设计好的检测界面
- from Detect_GUI import Ui_MainWindow
- import matplotlib.backends.backend_tkagg
- # 界面登录
- class win_Login(QMainWindow):
- def __init__(self, parent = None):
- super(win_Login, self).__init__(parent)
- self.ui_login = Ui_Form()
- self.ui_login.setupUi(self)
- self.init_slots()
- self.hidden_pwd()
-
- # 密码输入框隐藏
- def hidden_pwd(self):
- self.ui_login.edit_password.setEchoMode(QLineEdit.Password)
-
- # 绑定信号槽
- def init_slots(self):
- self.ui_login.btn_login.clicked.connect(self.onSignIn) # 点击按钮登录
- self.ui_login.edit_password.returnPressed.connect(self.onSignIn) # 按下回车登录
- self.ui_login.btn_regeist.clicked.connect(self.create_id)
-
- # 跳转到注册界面
- def create_id(self):
- shareInfo.createWin = win_Registe()
- shareInfo.createWin.show()
-
- # 保存登录日志
- def sava_login_log(self, username):
- with open('login_log.txt', 'a', encoding='utf-8') as f:
- f.write(username + '\t log in at' + datetime.now().strftimestrftime+ '\r')
-
- # 登录
- def onSignIn(self):
- print("You pressed sign in")
- # 从登陆界面获得输入账户名与密码
- username = self.ui_login.edit_username.text().strip()
- password = self.ui_login.edit_password.text().strip()
- print(username)
- print(password)
- # 获得账号信息
- USER_PWD = get_id_info()
- # print(USER_PWD)
- if username not in USER_PWD.keys():
- replay = QMessageBox.warning(self,"登陆失败!", "账号或密码输入错误", QMessageBox.Yes)
- else:
- # 若登陆成功,则跳转主界面
- if USER_PWD.get(username) == password:
- print("Jump to main window")
- # 所以使用公用变量名
- # shareInfo.mainWin = UI_Logic_Window()
- shareInfo.mainWin = Ui_MainWindow()
- shareInfo.mainWin.show()
- # 关闭当前窗口
- self.close()
- else:
- replay = QMessageBox.warning(self, "!", "账号或密码输入错误", QMessageBox.Yes)
-
- # 注册界面
- class win_Registe(QMainWindow):
- def __init__(self, parent = None):
- super(win_Registe, self).__init__(parent)
- self.ui_registe = Ui_Dialog()
- self.ui_registe.setupUi(self)
- self.init_slots()
-
- # 绑定槽信号
- def init_slots(self):
- self.ui_registe.pushButton_regiser.clicked.connect(self.new_account)
- self.ui_registe.pushButton_cancer.clicked.connect(self.cancel)
-
- # 创建新账户
- def new_account(self):
- print("Create new account")
- USER_PWD = get_id_info()
- # print(USER_PWD)
- new_username = self.ui_registe.edit_username.text().strip()
- new_password = self.ui_registe.edit_password.text().strip()
- # 判断用户名是否为空
- if new_username == "":
- replay = QMessageBox.warning(self, "!", "账号不准为空", QMessageBox.Yes)
- else:
- # 判断账号是否存在
- if new_username in USER_PWD.keys():
- replay = QMessageBox.warning(self, "!", "账号已存在", QMessageBox.Yes)
- else:
- # 判断密码是否为空
- if new_password == "":
- replay = QMessageBox.warning(self, "!", "密码不能为空", QMessageBox.Yes)
- else:
- # 注册成功
- print("Successful!")
- sava_id_info(new_username, new_password)
- replay = QMessageBox.warning(self, "!", "注册成功!", QMessageBox.Yes)
- # 关闭界面
- self.close()
-
- # 取消注册
- def cancel(self):
- self.close() # 关闭当前界面
-
- if __name__ == "__main__":
- app = QApplication(sys.argv)
- # 利用共享变量名来实例化对象
- shareInfo.loginWin = win_Login() # 登录界面作为主界面
- shareInfo.loginWin.show()
- sys.exit(app.exec_())
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。