当前位置:   article > 正文

(超详细流程-适合小白入门-一篇就够)基于YOLOv8和PYQT5进行检测界面的制作_yolov8怎么和pyqt5结合

yolov8怎么和pyqt5结合

前言

主要将自己基于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博客

一.PYQT5的安装和QT Designer的学习

我是基于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文件中主要存放注册界面生成的账号.

项目所能完成的任务

检测

除了正常的登录和注册界面以外,检测界面主要能够完成以下任务:

模型加载,图像加载,图像保存,图像保存,应用退出

Detect_GUI.py文件

可以好好看看这段代码中的注释,对于各个功能模块所牵涉到的功能函数进行了备注.

其中在图像打开之后直接嵌入了模型调用命令行进行调用和检测.

  1. import sys
  2. import cv2
  3. from ultralytics.yolo.engine.model import YOLO
  4. from PyQt5 import QtCore, QtGui, QtWidgets
  5. from PyQt5.QtWidgets import *
  6. import ui_img.detect_images_rc
  7. class Ui_MainWindow(QMainWindow):
  8. def __init__(self):
  9. super(Ui_MainWindow, self).__init__()
  10. self.setWindowTitle("基于YOLOv8的检测演示软件V1.0")
  11. self.resize(1500, 1000)
  12. self.setStyleSheet("QWidget#centralwidget{background-image: url(:/detect_background/detect.JPG);}")
  13. self.centralwidget = QWidget()
  14. self.centralwidget.setObjectName("centralwidget")
  15. # 模型选择
  16. self.btn_selet_model = QtWidgets.QPushButton(self.centralwidget)
  17. self.btn_selet_model.setGeometry(QtCore.QRect(70, 810, 70, 70))
  18. self.btn_selet_model.setStyleSheet("border-image: url(:/detect_button_background/upload.png);")
  19. self.btn_selet_model.setText("")
  20. self.btn_selet_model.setObjectName("btn_selet_model")
  21. self.btn_selet_model.clicked.connect(self.seletModels)
  22. # 选择图像进行检测
  23. self.btn_detect_img = QtWidgets.QPushButton(self.centralwidget)
  24. self.btn_detect_img.setGeometry(QtCore.QRect(390, 810, 70, 70))
  25. self.btn_detect_img.setStyleSheet("border-image: url(:/detect_button_background/images.png);")
  26. self.btn_detect_img.setText("")
  27. self.btn_detect_img.setObjectName("btn_detect_img")
  28. self.btn_detect_img.clicked.connect(self.openImage)
  29. # 保存结果图像
  30. self.btn_save_img = QtWidgets.QPushButton(self.centralwidget)
  31. self.btn_save_img.setGeometry(QtCore.QRect(730, 810, 70, 70))
  32. self.btn_save_img.setStyleSheet("border-image: url(:/detect_button_background/save.png);")
  33. self.btn_save_img.setText("")
  34. self.btn_save_img.setObjectName("btn_save_img")
  35. self.btn_save_img.clicked.connect(self.saveImage)
  36. # 清除结果图像
  37. self.btn_clear_img = QtWidgets.QPushButton(self.centralwidget)
  38. self.btn_clear_img.setGeometry(QtCore.QRect(1050, 810, 70, 70))
  39. self.btn_clear_img.setStyleSheet("border-image: url(:/detect_button_background/delete.png);")
  40. self.btn_clear_img.setText("")
  41. self.btn_clear_img.setObjectName("btn_clear_img")
  42. self.btn_clear_img.clicked.connect(self.clearImage)
  43. # 退出应用
  44. self.btn_exit_app = QtWidgets.QPushButton(self.centralwidget)
  45. self.btn_exit_app.setGeometry(QtCore.QRect(1360, 810, 70, 70))
  46. self.btn_exit_app.setStyleSheet("border-image: url(:/detect_button_background/exit.png);")
  47. self.btn_exit_app.setText("")
  48. self.btn_exit_app.setObjectName("btn_exit_app")
  49. self.btn_exit_app.clicked.connect(self.exitApp)
  50. # 呈现原始图像
  51. self.label_show_yuanshi = QtWidgets.QLabel(self.centralwidget)
  52. self.label_show_yuanshi.setGeometry(QtCore.QRect(0, 80, 700, 700))
  53. self.label_show_yuanshi.setStyleSheet("background-color: rgb(255, 255, 255);")
  54. self.label_show_yuanshi.setObjectName("label_show_yuanshi")
  55. # 呈现结果图像
  56. self.label_show_jieguo = QtWidgets.QLabel(self.centralwidget)
  57. self.label_show_jieguo.setGeometry(QtCore.QRect(800, 80, 700, 700))
  58. self.label_show_jieguo.setStyleSheet("background-color: rgb(255, 255, 255);")
  59. self.label_show_jieguo.setObjectName("label_show_jieguo")
  60. # 呈现功能按键
  61. self.label_show_button = QtWidgets.QLabel(self.centralwidget)
  62. self.label_show_button.setGeometry(QtCore.QRect(0, 800, 1501, 141))
  63. self.label_show_button.setStyleSheet("background-color: rgb(255, 255, 255);")
  64. self.label_show_button.setText("")
  65. self.label_show_button.setObjectName("label_show_button")
  66. #编写模型加载
  67. self.edit_selet_model = QtWidgets.QLineEdit(self.centralwidget)
  68. self.edit_selet_model.setGeometry(QtCore.QRect(20, 890, 161, 40))
  69. font = QtGui.QFont()
  70. font.setFamily("Adobe 宋体 Std L")
  71. font.setPointSize(28)
  72. self.edit_selet_model.setFont(font)
  73. self.edit_selet_model.setLayoutDirection(QtCore.Qt.RightToLeft)
  74. self.edit_selet_model.setObjectName("edit_selet_model")
  75. #编写图像加载
  76. self.edit_detect_img = QtWidgets.QLineEdit(self.centralwidget)
  77. self.edit_detect_img.setGeometry(QtCore.QRect(350, 890, 161, 40))
  78. font = QtGui.QFont()
  79. font.setFamily("Adobe 宋体 Std L")
  80. font.setPointSize(28)
  81. self.edit_detect_img.setFont(font)
  82. self.edit_detect_img.setObjectName("edit_detect_img")
  83. #编写图像保存
  84. self.edit_save_img = QtWidgets.QLineEdit(self.centralwidget)
  85. self.edit_save_img.setGeometry(QtCore.QRect(690, 890, 161, 40))
  86. font = QtGui.QFont()
  87. font.setFamily("Adobe 宋体 Std L")
  88. font.setPointSize(28)
  89. self.edit_save_img.setFont(font)
  90. self.edit_save_img.setObjectName("edit_save_img")
  91. #编写图像清除
  92. self.edit_clear_img = QtWidgets.QLineEdit(self.centralwidget)
  93. self.edit_clear_img.setGeometry(QtCore.QRect(1000, 890, 161, 40))
  94. font = QtGui.QFont()
  95. font.setFamily("Adobe 宋体 Std L")
  96. font.setPointSize(28)
  97. self.edit_clear_img.setFont(font)
  98. self.edit_clear_img.setObjectName("edit_clear_img")
  99. #编写应用退出
  100. self.edit_exit_app = QtWidgets.QLineEdit(self.centralwidget)
  101. self.edit_exit_app.setGeometry(QtCore.QRect(1300, 890, 161, 40))
  102. font = QtGui.QFont()
  103. font.setFamily("Adobe 宋体 Std L")
  104. font.setPointSize(28)
  105. self.edit_exit_app.setFont(font)
  106. self.edit_exit_app.setObjectName("edit_exit_app")
  107. # 标题
  108. self.label_show_title = QtWidgets.QLabel(self.centralwidget)
  109. self.label_show_title.setGeometry(QtCore.QRect(190, 10, 1101, 80))
  110. font = QtGui.QFont()
  111. font.setFamily("Adobe 黑体 Std R")
  112. font.setPointSize(28)
  113. self.label_show_title.setFont(font)
  114. self.label_show_title.setStyleSheet("")
  115. self.label_show_title.setObjectName("label_show_title")
  116. self.label_show_button.raise_()
  117. self.btn_selet_model.raise_()
  118. self.btn_detect_img.raise_()
  119. self.btn_save_img.raise_()
  120. self.btn_clear_img.raise_()
  121. self.btn_exit_app.raise_()
  122. self.label_show_title.raise_()
  123. self.label_show_yuanshi.raise_()
  124. self.label_show_jieguo.raise_()
  125. self.edit_selet_model.raise_()
  126. self.edit_detect_img.raise_()
  127. self.edit_save_img.raise_()
  128. self.edit_clear_img.raise_()
  129. self.edit_exit_app.raise_()
  130. # 主窗口
  131. self.setCentralWidget(self.centralwidget)
  132. self.retranslateUi(self.centralwidget)
  133. QtCore.QMetaObject.connectSlotsByName(self.centralwidget)
  134. def retranslateUi(self, MainWindow):
  135. _translate = QtCore.QCoreApplication.translate
  136. MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
  137. 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>"))
  138. self.label_show_yuanshi.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\"><span style=\" font-size:20pt;\">原始图像</span></p></body></html>"))
  139. self.label_show_jieguo.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\"><span style=\" font-size:20pt;\">检测图像</span></p></body></html>"))
  140. self.edit_selet_model.setText(_translate("MainWindow", "模型加载"))
  141. self.edit_detect_img.setText(_translate("MainWindow", "图像加载"))
  142. self.edit_save_img.setText(_translate("MainWindow", "图像保存"))
  143. self.edit_clear_img.setText(_translate("MainWindow", "图像清除"))
  144. self.edit_exit_app.setText(_translate("MainWindow", "应用退出"))
  145. # 模型选择函数
  146. def seletModels(self):
  147. self.openfile_name_model, _ = QFileDialog.getOpenFileName(self.btn_selet_model, '选择weights文件', '.', '权重文件(*.pt)')
  148. if not self.openfile_name_model:
  149. QMessageBox.warning(self, "Warning:", "打开权重失败", buttons=QMessageBox.Ok,)
  150. else:
  151. print('加载weights文件地址为:' + str(self.openfile_name_model))
  152. QMessageBox.information(self, u"Notice", u"权重打开成功", buttons=QtWidgets.QMessageBox.Ok)
  153. # 图像选择函数
  154. def openImage(self):
  155. name_list = []
  156. fname, _ = QFileDialog.getOpenFileName(self, '打开文件', '.', '图像文件(*.jpg)')
  157. self.fname = fname
  158. pixmap = QtGui.QPixmap(fname)
  159. self.label_show_yuanshi.setPixmap(pixmap)
  160. self.label_show_yuanshi.setScaledContents(True)
  161. img = cv2.imread(fname)
  162. # 引入模型
  163. model = YOLO(self.openfile_name_model)
  164. # 通过引用模型进行图像检测
  165. results = model.predict(source=self.fname)
  166. annotated_frame = results[0].plot()
  167. # 将图像数据转换为QImage格式
  168. height, width, channel = annotated_frame.shape
  169. bytes_per_line = 3 * width
  170. qimage = QtGui.QImage(annotated_frame.data, width, height, bytes_per_line, QtGui.QImage.Format_RGB888)
  171. self.qImg = qimage
  172. # 将QImage转换为QPixmap
  173. pixmap = QtGui.QPixmap.fromImage(qimage)
  174. self.label_show_jieguo.setPixmap(pixmap)
  175. self.label_show_jieguo.setScaledContents(True)
  176. return self.qImg
  177. # 图像保存函数
  178. def saveImage(self):
  179. fd, _ = QFileDialog.getSaveFileName(self, "保存图片", ".", "*.jpg")
  180. self.qImg.save(fd)
  181. # 图像清除函数
  182. def clearImage(self, stopp):
  183. result = QMessageBox.question(self, "Warning:", "是否清除本次检测结果", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
  184. if result == QMessageBox.Yes:
  185. self.label_show_yuanshi.clear()
  186. self.label_show_jieguo.clear()
  187. else:
  188. stopp.ignore()
  189. # 应用退出函数
  190. def exitApp(self, event):
  191. event = QApplication.instance()
  192. result = QMessageBox.question(self, "Notice:", "您真的要退出此应用吗", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
  193. if result == QMessageBox.Yes:
  194. event.quit()
  195. else:
  196. event.ignore()
  197. if __name__ == '__main__':
  198. app = QApplication(sys.argv)
  199. ui = Ui_MainWindow()
  200. ui.show()
  201. sys.exit(app.exec_())

Login_GUI.py

登录界面中包含登录和检测,其中还需要导入你在QT Designer中制作的的登录注册界面的.ui文件转换成的.py文件

  1. import sys
  2. from datetime import datetime
  3. from PyQt5.QtWidgets import *
  4. from utils.id_utils import get_id_info, sava_id_info # 账号信息工具函数
  5. from lib.share import shareInfo # 公共变量名
  6. # 导入QT-Design生成的UI
  7. from ui.login_ui import Ui_Form
  8. from ui.registe_ui import Ui_Dialog
  9. # 导入设计好的检测界面
  10. from Detect_GUI import Ui_MainWindow
  11. import matplotlib.backends.backend_tkagg
  12. # 界面登录
  13. class win_Login(QMainWindow):
  14. def __init__(self, parent = None):
  15. super(win_Login, self).__init__(parent)
  16. self.ui_login = Ui_Form()
  17. self.ui_login.setupUi(self)
  18. self.init_slots()
  19. self.hidden_pwd()
  20. # 密码输入框隐藏
  21. def hidden_pwd(self):
  22. self.ui_login.edit_password.setEchoMode(QLineEdit.Password)
  23. # 绑定信号槽
  24. def init_slots(self):
  25. self.ui_login.btn_login.clicked.connect(self.onSignIn) # 点击按钮登录
  26. self.ui_login.edit_password.returnPressed.connect(self.onSignIn) # 按下回车登录
  27. self.ui_login.btn_regeist.clicked.connect(self.create_id)
  28. # 跳转到注册界面
  29. def create_id(self):
  30. shareInfo.createWin = win_Registe()
  31. shareInfo.createWin.show()
  32. # 保存登录日志
  33. def sava_login_log(self, username):
  34. with open('login_log.txt', 'a', encoding='utf-8') as f:
  35. f.write(username + '\t log in at' + datetime.now().strftimestrftime+ '\r')
  36. # 登录
  37. def onSignIn(self):
  38. print("You pressed sign in")
  39. # 从登陆界面获得输入账户名与密码
  40. username = self.ui_login.edit_username.text().strip()
  41. password = self.ui_login.edit_password.text().strip()
  42. print(username)
  43. print(password)
  44. # 获得账号信息
  45. USER_PWD = get_id_info()
  46. # print(USER_PWD)
  47. if username not in USER_PWD.keys():
  48. replay = QMessageBox.warning(self,"登陆失败!", "账号或密码输入错误", QMessageBox.Yes)
  49. else:
  50. # 若登陆成功,则跳转主界面
  51. if USER_PWD.get(username) == password:
  52. print("Jump to main window")
  53. # 所以使用公用变量名
  54. # shareInfo.mainWin = UI_Logic_Window()
  55. shareInfo.mainWin = Ui_MainWindow()
  56. shareInfo.mainWin.show()
  57. # 关闭当前窗口
  58. self.close()
  59. else:
  60. replay = QMessageBox.warning(self, "!", "账号或密码输入错误", QMessageBox.Yes)
  61. # 注册界面
  62. class win_Registe(QMainWindow):
  63. def __init__(self, parent = None):
  64. super(win_Registe, self).__init__(parent)
  65. self.ui_registe = Ui_Dialog()
  66. self.ui_registe.setupUi(self)
  67. self.init_slots()
  68. # 绑定槽信号
  69. def init_slots(self):
  70. self.ui_registe.pushButton_regiser.clicked.connect(self.new_account)
  71. self.ui_registe.pushButton_cancer.clicked.connect(self.cancel)
  72. # 创建新账户
  73. def new_account(self):
  74. print("Create new account")
  75. USER_PWD = get_id_info()
  76. # print(USER_PWD)
  77. new_username = self.ui_registe.edit_username.text().strip()
  78. new_password = self.ui_registe.edit_password.text().strip()
  79. # 判断用户名是否为空
  80. if new_username == "":
  81. replay = QMessageBox.warning(self, "!", "账号不准为空", QMessageBox.Yes)
  82. else:
  83. # 判断账号是否存在
  84. if new_username in USER_PWD.keys():
  85. replay = QMessageBox.warning(self, "!", "账号已存在", QMessageBox.Yes)
  86. else:
  87. # 判断密码是否为空
  88. if new_password == "":
  89. replay = QMessageBox.warning(self, "!", "密码不能为空", QMessageBox.Yes)
  90. else:
  91. # 注册成功
  92. print("Successful!")
  93. sava_id_info(new_username, new_password)
  94. replay = QMessageBox.warning(self, "!", "注册成功!", QMessageBox.Yes)
  95. # 关闭界面
  96. self.close()
  97. # 取消注册
  98. def cancel(self):
  99. self.close() # 关闭当前界面
  100. if __name__ == "__main__":
  101. app = QApplication(sys.argv)
  102. # 利用共享变量名来实例化对象
  103. shareInfo.loginWin = win_Login() # 登录界面作为主界面
  104. shareInfo.loginWin.show()
  105. sys.exit(app.exec_())

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/579609
推荐阅读
相关标签
  

闽ICP备14008679号