迷途小书童的Note
source link: https://xugaoxiang.com/2021/06/30/yolov5-pyqt5/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
有小伙伴在问,能不能给yolov5
做个GUI
界面,比如使用pyqt5
框架? 本篇,我们就来实现一下,废话不多说,先看看效果图
界面元素非常简单,2个功能按钮,对应的是图片和视频检测,1个图片显示区域,显示图片或视频目标检测后的结果
基础环境安装
这里我们使用yolov5
的最新发布版本5.0,依赖库的安装本篇就不再讲述了,可以参考 YOLOv5发布5.0版本
接下来安装pyqt5
,使用如下命令
pip install pyqt5 pyqt5-tools
UI界面设计
界面部分的设计,使用pyqt5
自带的图形化设计工具designer
,好处是简单易用,所见即所得。设计完成后生成的ui
文件,只需要执行一条命令就可以轻松转换成python
代码。
首先打开designer.exe
,创建Main Window
界面上有2个按钮和一个文本框(使用文本框来显示图片),对应到pyqt5
中是push button
和label
,从左侧的widget box
中搜索并拖入到中间的工作区中,元素的属性可以在右侧修改
2个按钮,使用垂直布局排列
按钮布局和文本框,使用水平布局
为了自适应布局,也就是当放大、缩小窗口大小时,仍保持界面元素的比例,可以在空白位置,点击鼠标右键,选择 布局 --> 水平布局
布局的属性,同样的进行适当修改
调整后的界面
最后保存下,生成一个.ui
的文件,然后,通过pyqt5
提供的转换工具,将ui
文件转换成python
的代码,如下
pyuic5.bat -o main.py untitled.ui
生成的代码main.py
是这样的
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '.\untitled.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetNoConstraint)
self.horizontalLayout.setObjectName("horizontalLayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setContentsMargins(-1, -1, 0, -1)
self.verticalLayout.setSpacing(80)
self.verticalLayout.setObjectName("verticalLayout")
self.pushButton_img = QtWidgets.QPushButton(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton_img.sizePolicy().hasHeightForWidth())
self.pushButton_img.setSizePolicy(sizePolicy)
self.pushButton_img.setMinimumSize(QtCore.QSize(150, 100))
self.pushButton_img.setMaximumSize(QtCore.QSize(150, 100))
font = QtGui.QFont()
font.setFamily("Agency FB")
font.setPointSize(12)
self.pushButton_img.setFont(font)
self.pushButton_img.setObjectName("pushButton_img")
self.verticalLayout.addWidget(self.pushButton_img, 0, QtCore.Qt.AlignHCenter)
self.pushButton_video = QtWidgets.QPushButton(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton_video.sizePolicy().hasHeightForWidth())
self.pushButton_video.setSizePolicy(sizePolicy)
self.pushButton_video.setMinimumSize(QtCore.QSize(150, 100))
self.pushButton_video.setMaximumSize(QtCore.QSize(150, 100))
font = QtGui.QFont()
font.setFamily("Agency FB")
font.setPointSize(12)
self.pushButton_video.setFont(font)
self.pushButton_video.setObjectName("pushButton_video")
self.verticalLayout.addWidget(self.pushButton_video, 0, QtCore.Qt.AlignHCenter)
self.verticalLayout.setStretch(0, 1)
self.verticalLayout.setStretch(1, 1)
self.horizontalLayout.addLayout(self.verticalLayout)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.horizontalLayout.setStretch(0, 1)
self.horizontalLayout.setStretch(1, 3)
self.horizontalLayout_2.addLayout(self.horizontalLayout)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "PyQt5+YOLOv5示例"))
self.pushButton_img.setText(_translate("MainWindow", "图片检测"))
self.pushButton_video.setText(_translate("MainWindow", "视频检测"))
self.label.setText(_translate("MainWindow", "TextLabel"))
整合YOLOv5和PyQt5
有了上面的main.py
界面代码,我们就可以在它的基础上加入yolov5
检测的代码了。说白了,就是将yolov5
中的detect.py
中相应的代码移植过来。
-
加个程序入口
PyQt5
的惯用写法if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) ui = Ui_MainWindow() ui.show() sys.exit(app.exec_())
-
在
Ui_MainWindow
类中添加构造函数__init__
这里主要是几个方法的调用,包括界面的搭建、槽函数的初始化、定时器的初始化、模型的初始化
-
图片的选择与
yolov5
的检测,放在了一个方法中,检测结束后,将带有检测框的图片显示在文本框中 -
视频选择与视频检测,在2个方法(都是
slot
)中处理,当选中了某个视频,定时器开启,然后视频检测的方法启动
把工程已经放在了github
上,https://github.com/xugaoxiang/yolov5-pyqt5,觉得有用,请给个star
。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK