当前位置:   article > 正文

QT部署YOLOV5_qt yolo

qt yolo


前言

  这篇文章主要用来记录用pyqt5搭建YOLOV5的检测平台,代码是在yoloV5官方代码上加了个qt模块,目前可以支持GPU/CPU下pt/onnx推理

一、准备工作

1、代码下载

git clone https://github.com/ultralytics/yolov5.git
  • 1

2、环境安装

根据代码中的requirements.txt进行环境搭建,前提是你已有Python环境

pip install -r requirements.txt
  • 1

这里需要注意的是,pyqt5需要配置下环境,参考连接为:安装pyqt5,步骤如下:

2.1、安装PyQt5

pip install PyQt5
  • 1

2.2、安装Qt Designer图形界面开发工具

pip install PyQt5-tools
  • 1

安装完成后,会在当前环境目录下生成如下文件
在这里插入图片描述

2.3、pycharm配置

在这里插入图片描述
在这里插入图片描述
先配置Qt Designer
在这里插入图片描述
参数如下:
Name:Qt Designer。方便记忆。实际可以任意取值。

Program:designer.exe程序绝对路径。根据实际安装路径填写,参考路径为安装的xxxx/Lib/sit-packages/qt5_applications\Qt\bin\designer.exe(其中xxxx为虚拟环境目录下)。
Working directory: $ProjectFileDir$。固定取值。

配置PyUIC,该工具是用于将Qt Designer工具开发完成的.ui文件转化为.py文件。配置打开路径同Qt Designer。参数配置说明:
Name:PyUIC。方便记忆。实际可以任意取值。
Program:python.exe程序绝对路径。根据实际安装路径填写。
Parameters:-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py。固定取值。
Working directory: $FileDir$。固定取值。

3、模型准备

根据readme.md文件中的地址选择对应的模型下载,如图:

在这里插入图片描述

本文直接以yolov5s.pt进行示范

二、界面展示

1.界面大致如下

在这里插入图片描述

代码如下(示例):

class Ui_Form(QtWidgets.QWidget):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(1130, 730)
        self.stride=64
        #检测结果展示区
        self.label2 = QtWidgets.QLabel(Form)
        self.label2.setGeometry(QtCore.QRect(650, 410, 300, 300))
        self.label2.setAlignment(QtCore.Qt.AlignCenter)
        self.label2.setStyleSheet("border: 1px solid black;")
        self.label2.setObjectName("label2")

        #图片或视频路径选择
        self.pushButton = QtWidgets.QPushButton(Form)
        self.pushButton.setGeometry(QtCore.QRect(50, 310, 160, 30))
        self.pushButton.setStyleSheet("font: 15pt \"宋体\";\n"
"border:1px solid black;\n"
"background-color:#e1e1e1;")
        self.pushButton.setChecked(False)  # 设置开始时的状态为未选中
        self.pushButton.clicked.connect(lambda :self.select_file())
        self.pushButton.setObjectName("pushButton")  #图片选择按钮

        #模式选择
        self.comboBox = QtWidgets.QComboBox(Form)
        self.comboBox.setGeometry(QtCore.QRect(50, 260, 160, 30))
        self.comboBox.setStyleSheet("font: 15pt \"宋体\";\n"
"border:1px solid black;\n"
"background-color:#e1e1e1;")
        self.comboBox.setPlaceholderText("")
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.currentIndexChanged.connect(lambda :self.select_mode())

        #开始检测按钮
        self.pushButton_2 = QtWidgets.QPushButton(Form)
        self.pushButton_2.setGeometry(QtCore.QRect(190, 610, 100, 70))
        self.pushButton_2.setStyleSheet("font: 15pt \"宋体\";\n"
"border:1px solid black;\n"
"background-color:#e1e1e1;")
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_2.setChecked(False)
        self.pushButton_2.clicked.connect(lambda :self.vim_show())

        self.pushButton_3 = QtWidgets.QPushButton(Form)
        self.pushButton_3.setGeometry(QtCore.QRect(50, 210, 160, 30))
        self.pushButton_3.setStyleSheet("font: 15pt \"宋体\";\n"
"border:1px solid black;\n"
"background-color:#e1e1e1;")
        self.pushButton_3.setObjectName("pushButton_3")
        self.pushButton_3.setChecked(False) # 设置开始时的状态为未选中
        self.pushButton_3.clicked.connect(lambda :self.select_modelfile())

        self.pushButton_7 = QtWidgets.QPushButton(Form)
        self.pushButton_7.setGeometry(QtCore.QRect(50, 550, 160, 30))
        self.pushButton_7.setStyleSheet("font: 15pt \"宋体\";\n"
                                        "border:1px solid black;\n"
                                        "background-color:#e1e1e1;")
        self.pushButton_7.setObjectName("pushButton_7")

        self.lineEdit_2=QtWidgets.QLineEdit(Form)
        self.lineEdit_2.setGeometry(QtCore.QRect(230, 550, 220, 30))
        self.lineEdit_2.setStyleSheet("border: 1px solid black;")
        self.lineEdit_2.setObjectName("lineEdit_2")

        self.label1=QtWidgets.QLabel(Form)
        self.label1.setGeometry(QtCore.QRect(650, 100, 300, 300))
        self.label2.setAlignment(QtCore.Qt.AlignCenter)
        self.label1.setStyleSheet("border: 1px solid black;")
        self.label1.setObjectName("label1")

        self.textEdit = QtWidgets.QTextEdit(Form)
        self.textEdit.setGeometry(QtCore.QRect(600, 100, 40, 300))
        self.textEdit.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.textEdit.setStyleSheet("border: 1px solid black;\n"
"font: 15pt \"宋体\";")

        self.textEdit.setObjectName("textEdit")

        self.textEdit_2 = QtWidgets.QTextEdit(Form)
        self.textEdit_2.setGeometry(QtCore.QRect(600, 410, 40, 300))
        self.textEdit_2.setStyleSheet("border: 1px solid black;\n"
"font: 15pt \"宋体\";")
        self.textEdit_2.setAlignment(QtCore.Qt.AlignHCenter)
        self.textEdit_2.setObjectName("textEdit_2")

        self.tableWidget = QtWidgets.QTableWidget(Form)
        self.tableWidget.setGeometry(QtCore.QRect(230, 370, 221, 170))
        self.tableWidget.setStyleSheet("font: 15pt \"宋体\";\n"
"")
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(1)
        self.tableWidget.setRowCount(4)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        self.tableWidget.horizontalHeader().setDefaultSectionSize(100)
        self.tableWidget.horizontalHeader().setMinimumSectionSize(100)
        self.tableWidget.verticalHeader().setDefaultSectionSize(30)

        self.lineEdit_3 = QtWidgets.QLineEdit(Form)
        self.lineEdit_3.setGeometry(QtCore.QRect(230, 210, 220, 30))
        self.lineEdit_3.setStyleSheet("border: 1px solid black;")
        self.lineEdit_3.setObjectName("lineEdit_3")

        self.lineEdit_4 = QtWidgets.QLineEdit(Form)
        self.lineEdit_4.setGeometry(QtCore.QRect(230, 260, 220, 30))
        self.lineEdit_4.setStyleSheet("border: 1px solid black;")
        self.lineEdit_4.setObjectName("lineEdit_4")

        self.widget_3 = QtWidgets.QWidget(Form)
        self.widget_3.setGeometry(QtCore.QRect(20, 30, 460, 690))
        self.widget_3.setStyleSheet("border : 1px solid black;")
        self.widget_3.setObjectName("widget_3")

        self.lineEdit_5 = QtWidgets.QLineEdit(self.widget_3)
        self.lineEdit_5.setGeometry(QtCore.QRect(90, 20, 261, 51))
        self.lineEdit_5.setStyleSheet("font: 16pt \"宋体\";")
        self.lineEdit_5.setAlignment(QtCore.Qt.AlignCenter)
        self.lineEdit_5.setObjectName("lineEdit_5")

        self.lineEdit_7 = QtWidgets.QLineEdit(self.widget_3)
        self.lineEdit_7.setGeometry(QtCore.QRect(210, 280, 220, 30))
        self.lineEdit_7.setStyleSheet("border: 1px solid black;")
        self.lineEdit_7.setObjectName("lineEdit_7")

        self.pushButton_4 = QtWidgets.QPushButton(self.widget_3)
        self.pushButton_4.setGeometry(QtCore.QRect(30, 410, 160, 61))
        self.pushButton_4.setStyleSheet("font: 15pt \"宋体\";\n"
"background-color:#e1e1e1;")
        self.pushButton_4.setObjectName("pushButton_4")

        #参数确认按钮
        self.pushButton_5 = QtWidgets.QPushButton(Form)
        self.pushButton_5.setGeometry(QtCore.QRect(50, 610, 100, 70))
        self.pushButton_5.setStyleSheet("font: 15pt \"宋体\";\n"
"border:1px solid black;\n"
"background-color:#e1e1e1;")
        self.pushButton_5.setObjectName("pushButton_5")
        self.pushButton_5.setChecked(False)
        self.pushButton_5.clicked.connect(lambda: self.param_show())

        #结束检测按钮
        self.pushButton_6 = QtWidgets.QPushButton(Form)
        self.pushButton_6.setGeometry(QtCore.QRect(330, 610, 100, 70))
        self.pushButton_6.setStyleSheet("font: 15pt \"宋体\";\n"
                                        "border:1px solid black;\n"
                                        "background-color:#e1e1e1;")
        self.pushButton_6.setObjectName("pushButton_6")
        self.pushButton_6.setChecked(False)
        self.pushButton_6.clicked.connect(lambda: self.end_detect())




        self.lineEdit_8 = QtWidgets.QLineEdit(self.widget_3)
        self.lineEdit_8.setGeometry(QtCore.QRect(210, 120, 220, 30))
        self.lineEdit_8.setStyleSheet("border: 1px solid black;")
        self.lineEdit_8.setObjectName("lineEdit_8")

        self.comboBox_2 = QtWidgets.QComboBox(self.widget_3)
        self.comboBox_2.setGeometry(QtCore.QRect(30, 120, 160, 30))
        self.comboBox_2.setStyleSheet("font: 15pt \"宋体\";\n"
"background-color:#e1e1e1;")
        self.comboBox_2.setPlaceholderText("")
        self.comboBox_2.setObjectName("comboBox_2")
        self.comboBox_2.currentIndexChanged.connect(lambda : self.select_device())
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")

        self.lineEdit_5.raise_()
        self.lineEdit_7.raise_()
        self.lineEdit_8.raise_()
        self.comboBox_2.raise_()

        self.pushButton_4.raise_()
        self.widget_4 = QtWidgets.QWidget(Form)
        self.widget_4.setGeometry(QtCore.QRect(530, 30, 510, 690))
        self.widget_4.setStyleSheet("border:1px solid black;")
        self.widget_4.setObjectName("widget_4")

        self.lineEdit_6 = QtWidgets.QLineEdit(self.widget_4)
        self.lineEdit_6.setGeometry(QtCore.QRect(70, 10, 350, 50))
        self.lineEdit_6.setStyleSheet("font: 16pt \"宋体\";")
        self.lineEdit_6.setAlignment(QtCore.Qt.AlignCenter)
        self.lineEdit_6.setObjectName("lineEdit_6")

        self.widget_4.raise_()
        self.widget_3.raise_()
        self.label2.raise_()
        self.pushButton.raise_()
        self.comboBox.raise_()
        self.pushButton_3.raise_()
        self.label1.raise_()
        self.textEdit.raise_()
        self.textEdit_2.raise_()
        self.tableWidget.raise_()
        self.lineEdit_3.raise_()
        self.lineEdit_4.raise_()
        self.pushButton_2.raise_()
        self.pushButton_5.raise_()
        self.pushButton_6.raise_()
        self.pushButton_7.raise_()
        self.lineEdit_2.raise_()

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)


    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "YOLOV5检测"))
        self.pushButton.setText(_translate("Form", "选择文件"))
        self.pushButton_7.setText(_translate("Form", "是否结束"))
        self.comboBox.setItemText(0, _translate("Form", "检测方式"))
        self.comboBox.setItemText(1, _translate("Form", "图片检测"))
        self.comboBox.setItemText(2, _translate("Form", "视频检测"))
        self.comboBox.setItemText(3, _translate("Form", "摄像头检测"))
        self.pushButton_2.setText(_translate("Form", "开始检测"))
        self.pushButton_5.setText(_translate("Form", "确定"))
        self.pushButton_6.setText(_translate("Form", "结束程序"))
        self.pushButton_3.setText(_translate("Form", "模型路径"))
        self.textEdit.setText(_translate("Form", "\n原\n始\n图\n片\n/\n视\n频"))
        self.textEdit_2.setText(_translate("Form", "\n\n\n测\n试\n结\n果"))
        item = self.tableWidget.verticalHeaderItem(0)
        item.setText(_translate("Form", "imgsize"))
        item = self.tableWidget.verticalHeaderItem(1)
        item.setText(_translate("Form", "conf"))
        item = self.tableWidget.verticalHeaderItem(2)
        item.setText(_translate("Form", "iou"))
        item = self.tableWidget.verticalHeaderItem(3)
        item.setText(_translate("Form", "dnn"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("Form", "数值"))
        self.tableWidget.setItem(0,0,QtWidgets.QTableWidgetItem("640")) #图片大小默认值
        self.tableWidget.setItem(0,1,QtWidgets.QTableWidgetItem("0.25")) #置信度阈值默认值
        self.tableWidget.setItem(0,2,QtWidgets.QTableWidgetItem("0.45")) #IOU阈值默认值
        self.tableWidget.setItem(0,3,QtWidgets.QTableWidgetItem("False")) #IOU阈值默认值

        self.lineEdit_3.setPlaceholderText(_translate("Form", "模型的路径"))
        self.lineEdit_4.setPlaceholderText(_translate("Form", "图片或视频检测及摄像头检测"))
        self.lineEdit_5.setText(_translate("Form", "参数设置及可视化"))
        self.lineEdit_7.setPlaceholderText(_translate("Form", "图片或视频路径"))
        self.pushButton_4.setText(_translate("Form", "其他参数"))
        self.lineEdit_8.setPlaceholderText(_translate("Form", "运行设备(CPU或GPU)"))
        self.comboBox_2.setItemText(0, _translate("Form", "设备选择"))
        self.comboBox_2.setItemText(1, _translate("Form", "CPU"))
        self.comboBox_2.setItemText(2, _translate("Form", "GPU"))
        self.lineEdit_6.setText(_translate("Form", "图片及测试结果可视化"))
        self.lineEdit_2.setPlaceholderText(_translate("Form", "是否关闭视频或者摄像头"))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260

三、效果展示

1、图片效果展示如下:

在这里插入图片描述

2、摄像头或视频检测

在这里插入图片描述

四、整体代码:

若界面太大或太小,就自己添加些代码,将界面自适应电脑,或者手动修改代码33行。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'det.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.

import sys
import os
root_path=os.path.abspath(os.path.join(os.path.dirname(__file__),".."))
sys.path.append(root_path)

from PyQt5 import QtCore, QtGui, QtWidgets
import torch
import cv2
from PIL import Image,ImageQt
import numpy as np
from utils.general import non_max_suppression
from utils.general import check_img_size,scale_coords
from utils.augmentations import letterbox
import os
from pathlib import Path
from utils.plots import Annotator,colors
from models.experimental import attempt_load


class Ui_Form(QtWidgets.QWidget):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(1130, 730)
        self.stride=64
        #检测结果展示区
        self.label2 = QtWidgets.QLabel(Form)
        self.label2.setGeometry(QtCore.QRect(650, 410, 300, 300))
        self.label2.setAlignment(QtCore.Qt.AlignCenter)
        self.label2.setStyleSheet("border: 1px solid black;")
        self.label2.setObjectName("label2")

        #图片或视频路径选择
        self.pushButton = QtWidgets.QPushButton(Form)
        self.pushButton.setGeometry(QtCore.QRect(50, 310, 160, 30))
        self.pushButton.setStyleSheet("font: 15pt \"宋体\";\n"
"border:1px solid black;\n"
"background-color:#e1e1e1;")
        self.pushButton.setChecked(False)  # 设置开始时的状态为未选中
        self.pushButton.clicked.connect(lambda :self.select_file())
        self.pushButton.setObjectName("pushButton")  #图片选择按钮

        #模式选择
        self.comboBox = QtWidgets.QComboBox(Form)
        self.comboBox.setGeometry(QtCore.QRect(50, 260, 160, 30))
        self.comboBox.setStyleSheet("font: 15pt \"宋体\";\n"
"border:1px solid black;\n"
"background-color:#e1e1e1;")
        self.comboBox.setPlaceholderText("")
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.currentIndexChanged.connect(lambda :self.select_mode())

        #开始检测按钮
        self.pushButton_2 = QtWidgets.QPushButton(Form)
        self.pushButton_2.setGeometry(QtCore.QRect(190, 610, 100, 70))
        self.pushButton_2.setStyleSheet("font: 15pt \"宋体\";\n"
"border:1px solid black;\n"
"background-color:#e1e1e1;")
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_2.setChecked(False)
        self.pushButton_2.clicked.connect(lambda :self.vim_show())

        self.pushButton_3 = QtWidgets.QPushButton(Form)
        self.pushButton_3.setGeometry(QtCore.QRect(50, 210, 160, 30))
        self.pushButton_3.setStyleSheet("font: 15pt \"宋体\";\n"
"border:1px solid black;\n"
"background-color:#e1e1e1;")
        self.pushButton_3.setObjectName("pushButton_3")
        self.pushButton_3.setChecked(False) # 设置开始时的状态为未选中
        self.pushButton_3.clicked.connect(lambda :self.select_modelfile())

        self.pushButton_7 = QtWidgets.QPushButton(Form)
        self.pushButton_7.setGeometry(QtCore.QRect(50, 550, 160, 30))
        self.pushButton_7.setStyleSheet("font: 15pt \"宋体\";\n"
                                        "border:1px solid black;\n"
                                        "background-color:#e1e1e1;")
        self.pushButton_7.setObjectName("pushButton_7")

        self.lineEdit_2=QtWidgets.QLineEdit(Form)
        self.lineEdit_2.setGeometry(QtCore.QRect(230, 550, 220, 30))
        self.lineEdit_2.setStyleSheet("border: 1px solid black;")
        self.lineEdit_2.setObjectName("lineEdit_2")

        self.label1=QtWidgets.QLabel(Form)
        self.label1.setGeometry(QtCore.QRect(650, 100, 300, 300))
        self.label2.setAlignment(QtCore.Qt.AlignCenter)
        self.label1.setStyleSheet("border: 1px solid black;")
        self.label1.setObjectName("label1")

        self.textEdit = QtWidgets.QTextEdit(Form)
        self.textEdit.setGeometry(QtCore.QRect(600, 100, 40, 300))
        self.textEdit.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.textEdit.setStyleSheet("border: 1px solid black;\n"
"font: 15pt \"宋体\";")

        self.textEdit.setObjectName("textEdit")

        self.textEdit_2 = QtWidgets.QTextEdit(Form)
        self.textEdit_2.setGeometry(QtCore.QRect(600, 410, 40, 300))
        self.textEdit_2.setStyleSheet("border: 1px solid black;\n"
"font: 15pt \"宋体\";")
        self.textEdit_2.setAlignment(QtCore.Qt.AlignHCenter)
        self.textEdit_2.setObjectName("textEdit_2")

        self.tableWidget = QtWidgets.QTableWidget(Form)
        self.tableWidget.setGeometry(QtCore.QRect(230, 370, 221, 170))
        self.tableWidget.setStyleSheet("font: 15pt \"宋体\";\n"
"")
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(1)
        self.tableWidget.setRowCount(4)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        self.tableWidget.horizontalHeader().setDefaultSectionSize(100)
        self.tableWidget.horizontalHeader().setMinimumSectionSize(100)
        self.tableWidget.verticalHeader().setDefaultSectionSize(30)

        self.lineEdit_3 = QtWidgets.QLineEdit(Form)
        self.lineEdit_3.setGeometry(QtCore.QRect(230, 210, 220, 30))
        self.lineEdit_3.setStyleSheet("border: 1px solid black;")
        self.lineEdit_3.setObjectName("lineEdit_3")

        self.lineEdit_4 = QtWidgets.QLineEdit(Form)
        self.lineEdit_4.setGeometry(QtCore.QRect(230, 260, 220, 30))
        self.lineEdit_4.setStyleSheet("border: 1px solid black;")
        self.lineEdit_4.setObjectName("lineEdit_4")

        self.widget_3 = QtWidgets.QWidget(Form)
        self.widget_3.setGeometry(QtCore.QRect(20, 30, 460, 690))
        self.widget_3.setStyleSheet("border : 1px solid black;")
        self.widget_3.setObjectName("widget_3")

        self.lineEdit_5 = QtWidgets.QLineEdit(self.widget_3)
        self.lineEdit_5.setGeometry(QtCore.QRect(90, 20, 261, 51))
        self.lineEdit_5.setStyleSheet("font: 16pt \"宋体\";")
        self.lineEdit_5.setAlignment(QtCore.Qt.AlignCenter)
        self.lineEdit_5.setObjectName("lineEdit_5")

        self.lineEdit_7 = QtWidgets.QLineEdit(self.widget_3)
        self.lineEdit_7.setGeometry(QtCore.QRect(210, 280, 220, 30))
        self.lineEdit_7.setStyleSheet("border: 1px solid black;")
        self.lineEdit_7.setObjectName("lineEdit_7")

        self.pushButton_4 = QtWidgets.QPushButton(self.widget_3)
        self.pushButton_4.setGeometry(QtCore.QRect(30, 410, 160, 61))
        self.pushButton_4.setStyleSheet("font: 15pt \"宋体\";\n"
"background-color:#e1e1e1;")
        self.pushButton_4.setObjectName("pushButton_4")

        #参数确认按钮
        self.pushButton_5 = QtWidgets.QPushButton(Form)
        self.pushButton_5.setGeometry(QtCore.QRect(50, 610, 100, 70))
        self.pushButton_5.setStyleSheet("font: 15pt \"宋体\";\n"
"border:1px solid black;\n"
"background-color:#e1e1e1;")
        self.pushButton_5.setObjectName("pushButton_5")
        self.pushButton_5.setChecked(False)
        self.pushButton_5.clicked.connect(lambda: self.param_show())

        #结束检测按钮
        self.pushButton_6 = QtWidgets.QPushButton(Form)
        self.pushButton_6.setGeometry(QtCore.QRect(330, 610, 100, 70))
        self.pushButton_6.setStyleSheet("font: 15pt \"宋体\";\n"
                                        "border:1px solid black;\n"
                                        "background-color:#e1e1e1;")
        self.pushButton_6.setObjectName("pushButton_6")
        self.pushButton_6.setChecked(False)
        self.pushButton_6.clicked.connect(lambda: self.end_detect())




        self.lineEdit_8 = QtWidgets.QLineEdit(self.widget_3)
        self.lineEdit_8.setGeometry(QtCore.QRect(210, 120, 220, 30))
        self.lineEdit_8.setStyleSheet("border: 1px solid black;")
        self.lineEdit_8.setObjectName("lineEdit_8")

        self.comboBox_2 = QtWidgets.QComboBox(self.widget_3)
        self.comboBox_2.setGeometry(QtCore.QRect(30, 120, 160, 30))
        self.comboBox_2.setStyleSheet("font: 15pt \"宋体\";\n"
"background-color:#e1e1e1;")
        self.comboBox_2.setPlaceholderText("")
        self.comboBox_2.setObjectName("comboBox_2")
        self.comboBox_2.currentIndexChanged.connect(lambda : self.select_device())
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")
        self.comboBox_2.addItem("")

        self.lineEdit_5.raise_()
        self.lineEdit_7.raise_()
        self.lineEdit_8.raise_()
        self.comboBox_2.raise_()

        self.pushButton_4.raise_()
        self.widget_4 = QtWidgets.QWidget(Form)
        self.widget_4.setGeometry(QtCore.QRect(530, 30, 510, 690))
        self.widget_4.setStyleSheet("border:1px solid black;")
        self.widget_4.setObjectName("widget_4")

        self.lineEdit_6 = QtWidgets.QLineEdit(self.widget_4)
        self.lineEdit_6.setGeometry(QtCore.QRect(70, 10, 350, 50))
        self.lineEdit_6.setStyleSheet("font: 16pt \"宋体\";")
        self.lineEdit_6.setAlignment(QtCore.Qt.AlignCenter)
        self.lineEdit_6.setObjectName("lineEdit_6")

        self.widget_4.raise_()
        self.widget_3.raise_()
        self.label2.raise_()
        self.pushButton.raise_()
        self.comboBox.raise_()
        self.pushButton_3.raise_()
        self.label1.raise_()
        self.textEdit.raise_()
        self.textEdit_2.raise_()
        self.tableWidget.raise_()
        self.lineEdit_3.raise_()
        self.lineEdit_4.raise_()
        self.pushButton_2.raise_()
        self.pushButton_5.raise_()
        self.pushButton_6.raise_()
        self.pushButton_7.raise_()
        self.lineEdit_2.raise_()

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)


    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "YOLOV5检测"))
        self.pushButton.setText(_translate("Form", "选择文件"))
        self.pushButton_7.setText(_translate("Form", "是否结束"))
        self.comboBox.setItemText(0, _translate("Form", "检测方式"))
        self.comboBox.setItemText(1, _translate("Form", "图片检测"))
        self.comboBox.setItemText(2, _translate("Form", "视频检测"))
        self.comboBox.setItemText(3, _translate("Form", "摄像头检测"))
        self.pushButton_2.setText(_translate("Form", "开始检测"))
        self.pushButton_5.setText(_translate("Form", "确定"))
        self.pushButton_6.setText(_translate("Form", "结束程序"))
        self.pushButton_3.setText(_translate("Form", "模型路径"))
        self.textEdit.setText(_translate("Form", "\n原\n始\n图\n片\n/\n视\n频"))
        self.textEdit_2.setText(_translate("Form", "\n\n\n测\n试\n结\n果"))
        item = self.tableWidget.verticalHeaderItem(0)
        item.setText(_translate("Form", "imgsize"))
        item = self.tableWidget.verticalHeaderItem(1)
        item.setText(_translate("Form", "conf"))
        item = self.tableWidget.verticalHeaderItem(2)
        item.setText(_translate("Form", "iou"))
        item = self.tableWidget.verticalHeaderItem(3)
        item.setText(_translate("Form", "dnn"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("Form", "数值"))
        self.tableWidget.setItem(0,0,QtWidgets.QTableWidgetItem("640")) #图片大小默认值
        self.tableWidget.setItem(0,1,QtWidgets.QTableWidgetItem("0.25")) #置信度阈值默认值
        self.tableWidget.setItem(0,2,QtWidgets.QTableWidgetItem("0.45")) #IOU阈值默认值
        self.tableWidget.setItem(0,3,QtWidgets.QTableWidgetItem("False")) #IOU阈值默认值

        self.lineEdit_3.setPlaceholderText(_translate("Form", "模型的路径"))
        self.lineEdit_4.setPlaceholderText(_translate("Form", "图片或视频检测及摄像头检测"))
        self.lineEdit_5.setText(_translate("Form", "参数设置及可视化"))
        self.lineEdit_7.setPlaceholderText(_translate("Form", "图片或视频路径"))
        self.pushButton_4.setText(_translate("Form", "其他参数"))
        self.lineEdit_8.setPlaceholderText(_translate("Form", "运行设备(CPU或GPU)"))
        self.comboBox_2.setItemText(0, _translate("Form", "设备选择"))
        self.comboBox_2.setItemText(1, _translate("Form", "CPU"))
        self.comboBox_2.setItemText(2, _translate("Form", "GPU"))
        self.lineEdit_6.setText(_translate("Form", "图片及测试结果可视化"))
        self.lineEdit_2.setPlaceholderText(_translate("Form", "是否关闭视频或者摄像头"))
    #选择图片或视频路径
    def select_file(self):
        file,_=QtWidgets.QFileDialog.getOpenFileName(None,"选择文件",os.getcwd(),"All Files(*.jpg;*.png;*.jpeg;*.mp4;*.flv;*.avi;);;Text Files (*.txt)")
        self.lineEdit_7.setText(file)

    #选择模型路径
    def select_modelfile(self):
        file,_=QtWidgets.QFileDialog.getOpenFileName(None,"选择文件",os.getcwd(),"All Files(*.pt;*.onnx;*.pth);;")
        self.lineEdit_3.setText(file)

    #设备选择
    def select_device(self):
        device=self.comboBox_2.currentText() #获取下拉框的信息
        self.lineEdit_8.setText(device)

    #模式选择
    def select_mode(self):
        mode=self.comboBox.currentText()
        self.lineEdit_4.setText(mode)

    #模型初始化
    def param_show(self):
        device = torch.device("cpu" if self.lineEdit_8.text()=="CPU" else "cuda") #设备
        modelpath = self.lineEdit_3.text() #模型路径

        self.suffix = Path(modelpath).suffix[1:]
        if self.suffix == "pt":
            self.flag=True
            self.model = attempt_load(modelpath if isinstance(modelpath, list) else modelpath,
                                 map_location=device)
            self.stride = int(self.model.stride.max())  # model stride
            self.names = self.model.module.names if hasattr(self.model, 'module') else self.model.names  # get class names
            if self.lineEdit_8.text() == "GPU":
                self.model.half()

        elif self.suffix == "onnx":
            self.dnn = False
            self.flag=False
            if self.dnn:
                # check_requirements(('opencv-python>=4.5.4',))
                self.model = cv2.dnn.readNetFromONNX(modelpath)
            else:
                # check_requirements(('onnx', 'onnxruntime-gpu' if torch.has_cuda else 'onnxruntime'))
                import onnxruntime
                self.model = onnxruntime.InferenceSession(modelpath, None)

        # 后两项分别为按钮(以|隔开,共有7种按钮类型,见示例后)、默认按钮(省略则默认为第一个按钮)
        msg=QtWidgets.QMessageBox(QtWidgets.QMessageBox.Warning,"消息框", "模型初始化完成,请开始检测")
        msg.exec_()

    #检测
    def vim_show(self):
        filepath=self.lineEdit_7.text() #文件路径
        detect_mode=self.lineEdit_4.text()#检测模式
        imgsize = int(self.tableWidget.item(0, 0).text())  # 图片尺寸
        conf_thres = float(self.tableWidget.item(1, 0).text())  # 置信度阈值
        iou_thres = float(self.tableWidget.item(2, 0).text())  # iou阈值
        device = self.lineEdit_8.text()  # 设备

        if detect_mode=="图片检测":
            #opencv读图展示
            origin_img=cv2.imread(filepath)
            if origin_img.shape[0] > origin_img.shape[1]:  # h>w
                orgin_img1 = cv2.resize(origin_img, (int(origin_img.shape[1] * (300 / origin_img.shape[0])-1), 300),
                                 cv2.INTER_LINEAR)
            else:  # w>=h
                orgin_img1 = cv2.resize(origin_img, (300, int(origin_img.shape[0] * (300 / origin_img.shape[1]))-1),
                                 cv2.INTER_LINEAR)

            #图片预处理
            input_img=self.process_img(origin_img,device,imgsize)
            #推理
            result=self.process_inference(origin_img,input_img,conf_thres,iou_thres)
            #结果展示
            if result.shape[0] > result.shape[1]:  # h>w
                img1 = cv2.resize(result, (int(result.shape[1] * (300 / result.shape[0]))-1, 300),
                                 cv2.INTER_LINEAR)
            else:  # w>=h
                img1 = cv2.resize(result, (300, int(result.shape[0] * (300 / result.shape[1]))-1),
                                 cv2.INTER_LINEAR)


            #原图展示
            rgb_img = cv2.cvtColor(orgin_img1, cv2.COLOR_BGR2RGB)
            qimg = QtGui.QImage(rgb_img.data, rgb_img.shape[1], rgb_img.shape[0], QtGui.QImage.Format_RGB888)
            self.label1.setPixmap(QtGui.QPixmap.fromImage(qimg))

            #结果展示
            rgb_img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
            qimg1 = QtGui.QImage(rgb_img1.data, rgb_img1.shape[1], rgb_img1.shape[0], QtGui.QImage.Format_RGB888)
            self.label2.setPixmap(QtGui.QPixmap.fromImage(qimg1))


        elif detect_mode=="视频检测":
            cap = cv2.VideoCapture(filepath)
            count = 1
            while cap.isOpened():
                if count % 2 == 0:
                    ret, frame = cap.read()
                    if ret:
                        if frame.shape[0] > frame.shape[1]:  # h>w
                            img = cv2.resize(frame, (int(frame.shape[1] * (300 / frame.shape[0])), 300),
                                             cv2.INTER_LINEAR)
                        else:  # w>=h
                            img = cv2.resize(frame, (300, int(frame.shape[0] * (300 / frame.shape[1]))),
                                             cv2.INTER_LINEAR)

                        input_img = self.process_img(frame, device, imgsize)
                        result = self.process_inference(frame, input_img, conf_thres, iou_thres)
                        if result.shape[0] > result.shape[1]:  # h>w
                            img1 = cv2.resize(result, (int(result.shape[1] * (300 / result.shape[0])) - 1, 300),
                                              cv2.INTER_LINEAR)
                        else:  # h<=w
                            img1 = cv2.resize(result, (300, int(result.shape[0] * (300 / result.shape[1])) - 1),
                                              cv2.INTER_LINEAR)

                        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
                        cv2.waitKey(1)
                        qimg = QtGui.QImage(img.data, img.shape[1], img.shape[0], QtGui.QImage.Format_RGB888)
                        self.label1.setPixmap(QtGui.QPixmap.fromImage(qimg))

                        # 结果展示
                        rgb1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
                        qimg1 = QtGui.QImage(rgb1.data, rgb1.shape[1], rgb1.shape[0], QtGui.QImage.Format_RGB888)
                        self.label2.setPixmap(QtGui.QPixmap.fromImage(qimg1))
                    else:

                        break

                    count=1
                else:
                    count += 1
            cap.release()
            cv2.destroyAllWindows()
        else:
            self.cap = cv2.VideoCapture(0)
            count = 1
            while True:
                if count % 2 == 0:
                    ret, frame = self.cap.read()
                    if ret:
                        if frame.shape[0] > frame.shape[1]:  # h>w
                            img = cv2.resize(frame, (int(frame.shape[1] * (300 / frame.shape[0])), 300),
                                             cv2.INTER_LINEAR)
                        else:  # w>=h
                            img = cv2.resize(frame, (300, int(frame.shape[0] * (300 / frame.shape[1]))),
                                             cv2.INTER_LINEAR)


                        input_img=self.process_img(frame,device,imgsize)
                        result=self.process_inference(frame,input_img,conf_thres,iou_thres)
                        if result.shape[0]>result.shape[1]: #h>w
                            img1=cv2.resize(result,(int(result.shape[1]*(300/result.shape[0]))-1,300),cv2.INTER_LINEAR)
                        else: #h<=w
                            img1=cv2.resize(result,(300,int(result.shape[0]*(300/result.shape[1]))-1),
                                            cv2.INTER_LINEAR)

                        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
                        cv2.waitKey(1)
                        qimg = QtGui.QImage(img.data, img.shape[1], img.shape[0], QtGui.QImage.Format_RGB888)
                        self.label1.setPixmap(QtGui.QPixmap.fromImage(qimg))

                        #结果展示
                        rgb1=cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)
                        qimg1=QtGui.QImage(rgb1.data,rgb1.shape[1],rgb1.shape[0],QtGui.QImage.Format_RGB888)
                        self.label2.setPixmap(QtGui.QPixmap.fromImage(qimg1))
                    #复位
                    count=1
                    if self.lineEdit_2.text()=="是":
                        break

                else:
                    count += 1
            self.cap.release()
            cv2.destroyAllWindows()

    #退出程序
    def end_detect(self):
       sys.exit(1)



    #图片处理
    def process_img(self,org_img,device,imgsize):
        '''
        Args:
            org_img: 原图
            device: 设备
            imgsize: 图片尺寸

        Returns:

        '''
        # 查看图片尺寸是否能别stride整除
        imgsz = check_img_size(imgsize, s=self.stride)
        # resize_padding
        img = letterbox(org_img, imgsz, self.stride, auto=self.flag)[0]
        img = img.transpose((2, 0, 1))[::-1]  # HWC to CHW, BGR to RGB
        img = np.ascontiguousarray(img)
        if self.suffix == "onnx":
            img = img.astype("float32")
        else:
            img = torch.from_numpy(img).to(device.lower())
            # 设置是否为半精度测试
            if device == "GPU":
                img = img.half()
            else:
                img=img.float()

        img /= 255.0  # 归一化
        if len(img.shape) == 3:
            img = img[None]

        return img

    #推理进程
    def process_inference(self,org_img,img,conf_thres,iou_thres):
        '''
        Args:
            org_img: 原图
            img: 缩放后的图
            conf_thres: 置信度阈值
            iou_thres: IOU阈值

        Returns:

        '''
        if self.suffix == "pt":
            pred = self.model(img)[0]
        elif self.suffix == "onnx":
            if self.dnn:
                self.model.setInput(img)
                pred = torch.tensor(self.model.forward())
            else:
                pred = torch.tensor(self.model.run([self.model.get_outputs()[0].name], {self.model.get_inputs()[0].name: img}))
        pred = non_max_suppression(pred, conf_thres, iou_thres, classes=None, agnostic=False, max_det=1000)
        dt, seen = [0.0, 0.0, 0.0], 0
        for i, det in enumerate(pred):
            seen += 1
            im0 = org_img.copy()
            # 绘制预测框
            annotator = Annotator(im0, line_width=3, example=str(1))
            # 检测到目标时
            if len(det):
                det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()
                # 写结果
                for *xyxy, conf, cls in reversed(det):
                    c = int(cls)
                    # label = f'{conf:.2f}'
                    label = f'{self.names[c]} {conf:.2f}'
                    annotator.box_label(xyxy, label, color=colors(c, True))

            im0 = annotator.result()


            # cv2.imwrite(save_path + os.sep + Path(img_path).name, im0)
        return im0


if __name__ == '__main__':
    import sys
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)  # 解决了Qtdesigner设计的界面与实际运行界面不一致的问题
    app = QtWidgets.QApplication(sys.argv)
    widget = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(widget)
    widget.show()
    sys.exit(app.exec_())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556

总结

以上就是本篇文章的全部内容,欢迎评论区指正错误,也可加入QQ群:995760755交流。

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

闽ICP备14008679号