3

迷途小书童的Note

 2 years ago
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框架? 本篇,我们就来实现一下,废话不多说,先看看效果图

yolov5 pyqt5

界面元素非常简单,2个功能按钮,对应的是图片和视频检测,1个图片显示区域,显示图片或视频目标检测后的结果

yolov5 pyqt5

yolov5 pyqt5

基础环境安装

这里我们使用yolov5的最新发布版本5.0,依赖库的安装本篇就不再讲述了,可以参考 YOLOv5发布5.0版本

接下来安装pyqt5,使用如下命令

pip install pyqt5 pyqt5-tools

UI界面设计

界面部分的设计,使用pyqt5自带的图形化设计工具designer,好处是简单易用,所见即所得。设计完成后生成的ui文件,只需要执行一条命令就可以轻松转换成python代码。

首先打开designer.exe,创建Main Window

yolov5 pyqt5

界面上有2个按钮和一个文本框(使用文本框来显示图片),对应到pyqt5中是push buttonlabel,从左侧的widget box中搜索并拖入到中间的工作区中,元素的属性可以在右侧修改

2个按钮,使用垂直布局排列

yolov5 pyqt5

按钮布局和文本框,使用水平布局

yolov5 pyqt5

为了自适应布局,也就是当放大、缩小窗口大小时,仍保持界面元素的比例,可以在空白位置,点击鼠标右键,选择 布局 --> 水平布局

yolov5 pyqt5

yolov5 pyqt5

布局的属性,同样的进行适当修改

yolov5 pyqt5

调整后的界面

yolov5 pyqt5

最后保存下,生成一个.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中相应的代码移植过来。

  1. 加个程序入口

    PyQt5的惯用写法

    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        ui = Ui_MainWindow()
        ui.show()
        sys.exit(app.exec_())
  2. Ui_MainWindow类中添加构造函数__init__

    这里主要是几个方法的调用,包括界面的搭建、槽函数的初始化、定时器的初始化、模型的初始化

  3. 图片的选择与yolov5的检测,放在了一个方法中,检测结束后,将带有检测框的图片显示在文本框中

  4. 视频选择与视频检测,在2个方法(都是slot)中处理,当选中了某个视频,定时器开启,然后视频检测的方法启动

把工程已经放在了github上,https://github.com/xugaoxiang/yolov5-pyqt5,觉得有用,请给个star


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK