Yolov5(v5.0)+pyqt5界面設(shè)計(jì)圖文教程
1.下載安裝pyqt5工具包以及配置ui界面開(kāi)發(fā)環(huán)境
pip install PyQt5 pip install PyQt5-tools
2.點(diǎn)擊File->Settings->External Tools進(jìn)行工具添加,依次進(jìn)行Qt Designer、PyUIC環(huán)境配置.

2.1 添加QtDesigner

Qt Designer 是通過(guò)拖拽的方式放置控件,并實(shí)時(shí)查看控件效果進(jìn)行快速UI設(shè)計(jì)
| 位置 | 內(nèi)容 |
| name | 可以隨便命名,只要便于記憶就可以,本次采取通用命名:Qt Designer |
| Program | designer.exe路徑,一般在python中.\Library\bin\designer.exe |
| Arguments | 固定格式,直接復(fù)制也可:$FileDir$\$FileName$ |
| Working directory | 固定格式,直接復(fù)制也可:$FileDir$ |
2.2 添加PyUIC

PyUIC主要是把Qt Designer生成的.ui文件換成.py文件
| 位置 | 內(nèi)容 |
| name | 可以隨便命名,只要便于記憶就可以,本次采取通用命名:PyUiC |
| Program | python.exe路徑,一般在python安裝根目錄中 |
| Arguments | 固定格式,直接復(fù)制也可:-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py |
| Working directory | 固定格式,直接復(fù)制也可:$FileDir$ |
3. QtDesigner建立圖形化窗口界面
3.1 在根目錄下新建UI文件夾進(jìn)行UI文件的專(zhuān)門(mén)存儲(chǔ)
點(diǎn)擊Tools->External Tools->Qt Designer進(jìn)行圖形界面創(chuàng)建.

3.2 創(chuàng)建一個(gè)Main Window窗口



3.3 完成基本界面開(kāi)發(fā)后,保存其為Detect.ui,放置在UI文件夾下,利用PyUic工具將其轉(zhuǎn)化為Detect.py文件。


轉(zhuǎn)換完成后,進(jìn)行相應(yīng)的槽函數(shù)的建立與修改,此處建議直接看我后面給出的demo。
4. demo
使用時(shí)只需將parser.add_argument中的'--weights'設(shè)為響應(yīng)權(quán)重即可。
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '.\project.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
import sys
import cv2
import argparse
import random
import torch
import numpy as np
import torch.backends.cudnn as cudnn
from PyQt5 import QtCore, QtGui, QtWidgets
from utils.torch_utils import select_device
from models.experimental import attempt_load
from utils.general import check_img_size, non_max_suppression, scale_coords
from utils.datasets import letterbox
from utils.plots import plot_one_box
class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Ui_MainWindow, self).__init__(parent)
self.timer_video = QtCore.QTimer()
self.setupUi(self)
self.init_logo()
self.init_slots()
self.cap = cv2.VideoCapture()
self.out = None
# self.out = cv2.VideoWriter('prediction.avi', cv2.VideoWriter_fourcc(*'XVID'), 20.0, (640, 480))
parser = argparse.ArgumentParser()
parser.add_argument('--weights', nargs='+', type=str,
default='weights/best.pt', help='model.pt path(s)')
# file/folder, 0 for webcam
parser.add_argument('--source', type=str,
default='data/images', help='source')
parser.add_argument('--img-size', type=int,
default=640, help='inference size (pixels)')
parser.add_argument('--conf-thres', type=float,
default=0.25, help='object confidence threshold')
parser.add_argument('--iou-thres', type=float,
default=0.45, help='IOU threshold for NMS')
parser.add_argument('--device', default='',
help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument(
'--view-img', action='store_true', help='display results')
parser.add_argument('--save-txt', action='store_true',
help='save results to *.txt')
parser.add_argument('--save-conf', action='store_true',
help='save confidences in --save-txt labels')
parser.add_argument('--nosave', action='store_true',
help='do not save images/videos')
parser.add_argument('--classes', nargs='+', type=int,
help='filter by class: --class 0, or --class 0 2 3')
parser.add_argument(
'--agnostic-nms', action='store_true', help='class-agnostic NMS')
parser.add_argument('--augment', action='store_true',
help='augmented inference')
parser.add_argument('--update', action='store_true',
help='update all models')
parser.add_argument('--project', default='runs/detect',
help='save results to project/name')
parser.add_argument('--name', default='exp',
help='save results to project/name')
parser.add_argument('--exist-ok', action='store_true',
help='existing project/name ok, do not increment')
self.opt = parser.parse_args()
print(self.opt)
source, weights, view_img, save_txt, imgsz = self.opt.source, self.opt.weights, self.opt.view_img, self.opt.save_txt, self.opt.img_size
self.device = select_device(self.opt.device)
self.half = self.device.type != 'cpu' # half precision only supported on CUDA
cudnn.benchmark = True
# Load model
self.model = attempt_load(
weights, map_location=self.device) # load FP32 model
stride = int(self.model.stride.max()) # model stride
self.imgsz = check_img_size(imgsz, s=stride) # check img_size
if self.half:
self.model.half() # to FP16
# Get names and colors
self.names = self.model.module.names if hasattr(
self.model, 'module') else self.model.names
self.colors = [[random.randint(0, 255)
for _ in range(3)] for _ in self.names]
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(20, 130, 112, 34))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(20, 220, 112, 34))
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_3.setGeometry(QtCore.QRect(20, 300, 112, 34))
self.pushButton_3.setObjectName("pushButton_3")
self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox.setGeometry(QtCore.QRect(160, 90, 611, 411))
self.groupBox.setObjectName("groupBox")
self.label = QtWidgets.QLabel(self.groupBox)
self.label.setGeometry(QtCore.QRect(10, 40, 561, 331))
self.label.setObjectName("label")
self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit.setGeometry(QtCore.QRect(150, 10, 471, 51))
self.textEdit.setObjectName("textEdit")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 30))
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", "演示系統(tǒng)"))
self.pushButton.setText(_translate("MainWindow", "圖片檢測(cè)"))
self.pushButton_2.setText(_translate("MainWindow", "攝像頭檢測(cè)"))
self.pushButton_3.setText(_translate("MainWindow", "視頻檢測(cè)"))
self.groupBox.setTitle(_translate("MainWindow", "檢測(cè)結(jié)果"))
self.label.setText(_translate("MainWindow", "TextLabel"))
self.textEdit.setHtml(_translate("MainWindow",
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p align=\"center\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:18pt; font-weight:600;\">演示系統(tǒng)</span></p></body></html>"))
def init_slots(self):
self.pushButton.clicked.connect(self.button_image_open)
self.pushButton_3.clicked.connect(self.button_video_open)
self.pushButton_2.clicked.connect(self.button_camera_open)
self.timer_video.timeout.connect(self.show_video_frame)
def init_logo(self):
pix = QtGui.QPixmap('wechat.jpg')
self.label.setScaledContents(True)
self.label.setPixmap(pix)
def button_image_open(self):
print('button_image_open')
name_list = []
img_name, _ = QtWidgets.QFileDialog.getOpenFileName(
self, "打開(kāi)圖片", "", "*.jpg;;*.png;;All Files(*)")
if not img_name:
return
img = cv2.imread(img_name)
print(img_name)
showimg = img
with torch.no_grad():
img = letterbox(img, new_shape=self.opt.img_size)[0]
# Convert
# BGR to RGB, to 3x416x416
img = img[:, :, ::-1].transpose(2, 0, 1)
img = np.ascontiguousarray(img)
img = torch.from_numpy(img).to(self.device)
img = img.half() if self.half else img.float() # uint8 to fp16/32
img /= 255.0 # 0 - 255 to 0.0 - 1.0
if img.ndimension() == 3:
img = img.unsqueeze(0)
# Inference
pred = self.model(img, augment=self.opt.augment)[0]
# Apply NMS
pred = non_max_suppression(pred, self.opt.conf_thres, self.opt.iou_thres, classes=self.opt.classes,
agnostic=self.opt.agnostic_nms)
print(pred)
# Process detections
for i, det in enumerate(pred):
if det is not None and len(det):
# Rescale boxes from img_size to im0 size
det[:, :4] = scale_coords(
img.shape[2:], det[:, :4], showimg.shape).round()
for *xyxy, conf, cls in reversed(det):
label = '%s %.2f' % (self.names[int(cls)], conf)
name_list.append(self.names[int(cls)])
plot_one_box(xyxy, showimg, label=label,
color=self.colors[int(cls)], line_thickness=2)
cv2.imwrite('prediction.jpg', showimg)
self.result = cv2.cvtColor(showimg, cv2.COLOR_BGR2BGRA)
self.result = cv2.resize(
self.result, (640, 480), interpolation=cv2.INTER_AREA)
self.QtImg = QtGui.QImage(
self.result.data, self.result.shape[1], self.result.shape[0], QtGui.QImage.Format_RGB32)
self.label.setPixmap(QtGui.QPixmap.fromImage(self.QtImg))
def button_video_open(self):
video_name, _ = QtWidgets.QFileDialog.getOpenFileName(
self, "打開(kāi)視頻", "", "*.mp4;;*.avi;;All Files(*)")
if not video_name:
return
flag = self.cap.open(video_name)
if flag == False:
QtWidgets.QMessageBox.warning(
self, u"Warning", u"打開(kāi)視頻失敗", buttons=QtWidgets.QMessageBox.Ok, defaultButton=QtWidgets.QMessageBox.Ok)
else:
self.out = cv2.VideoWriter('prediction.avi', cv2.VideoWriter_fourcc(
*'MJPG'), 20, (int(self.cap.get(3)), int(self.cap.get(4))))
self.timer_video.start(30)
self.pushButton_3.setDisabled(True)
self.pushButton.setDisabled(True)
self.pushButton_2.setDisabled(True)
def button_camera_open(self):
if not self.timer_video.isActive():
# 默認(rèn)使用第一個(gè)本地camera
flag = self.cap.open(0)
if flag == False:
QtWidgets.QMessageBox.warning(
self, u"Warning", u"打開(kāi)攝像頭失敗", buttons=QtWidgets.QMessageBox.Ok,
defaultButton=QtWidgets.QMessageBox.Ok)
else:
self.out = cv2.VideoWriter('prediction.avi', cv2.VideoWriter_fourcc(
*'MJPG'), 20, (int(self.cap.get(3)), int(self.cap.get(4))))
self.timer_video.start(30)
self.pushButton_3.setDisabled(True)
self.pushButton.setDisabled(True)
self.pushButton_2.setText(u"關(guān)閉攝像頭")
else:
self.timer_video.stop()
self.cap.release()
self.out.release()
self.label.clear()
self.init_logo()
self.pushButton_3.setDisabled(False)
self.pushButton.setDisabled(False)
self.pushButton_2.setText(u"攝像頭檢測(cè)")
def show_video_frame(self):
name_list = []
flag, img = self.cap.read()
if img is not None:
showimg = img
with torch.no_grad():
img = letterbox(img, new_shape=self.opt.img_size)[0]
# Convert
# BGR to RGB, to 3x416x416
img = img[:, :, ::-1].transpose(2, 0, 1)
img = np.ascontiguousarray(img)
img = torch.from_numpy(img).to(self.device)
img = img.half() if self.half else img.float() # uint8 to fp16/32
img /= 255.0 # 0 - 255 to 0.0 - 1.0
if img.ndimension() == 3:
img = img.unsqueeze(0)
# Inference
pred = self.model(img, augment=self.opt.augment)[0]
# Apply NMS
pred = non_max_suppression(pred, self.opt.conf_thres, self.opt.iou_thres, classes=self.opt.classes,
agnostic=self.opt.agnostic_nms)
# Process detections
for i, det in enumerate(pred): # detections per image
if det is not None and len(det):
# Rescale boxes from img_size to im0 size
det[:, :4] = scale_coords(
img.shape[2:], det[:, :4], showimg.shape).round()
# Write results
for *xyxy, conf, cls in reversed(det):
label = '%s %.2f' % (self.names[int(cls)], conf)
name_list.append(self.names[int(cls)])
print(label)
plot_one_box(
xyxy, showimg, label=label, color=self.colors[int(cls)], line_thickness=2)
self.out.write(showimg)
show = cv2.resize(showimg, (640, 480))
self.result = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)
showImage = QtGui.QImage(self.result.data, self.result.shape[1], self.result.shape[0],
QtGui.QImage.Format_RGB888)
self.label.setPixmap(QtGui.QPixmap.fromImage(showImage))
else:
self.timer_video.stop()
self.cap.release()
self.out.release()
self.label.clear()
self.pushButton_3.setDisabled(False)
self.pushButton.setDisabled(False)
self.pushButton_2.setDisabled(False)
self.init_logo()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ui = Ui_MainWindow()
ui.show()
sys.exit(app.exec_())
5.添加背景圖片
將demo中最后一段代碼改為如下,其中background-image為背景圖片地址。
if __name__ == '__main__':
stylesheet = """
Ui_MainWindow {
background-image: url("4K.jpg");
background-repeat: no-repeat;
background-position: center;
}
"""
app = QtWidgets.QApplication(sys.argv)
app.setStyleSheet(stylesheet)
ui = Ui_MainWindow()
ui.show()
sys.exit(app.exec_())
6.reference
總結(jié)
到此這篇關(guān)于Yolov5(v5.0)+pyqt5界面設(shè)計(jì)的文章就介紹到這了,更多相關(guān)Yolov5+pyqt5界面設(shè)計(jì)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JupyterNotebook 如何調(diào)整輸出窗口的顯示效果
這篇文章主要介紹了JupyterNotebook 輸出窗口的顯示效果調(diào)整實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Python中的五個(gè)神仙級(jí)函數(shù)一起來(lái)看看
這篇文章主要為大家介紹了Python中的五個(gè)神仙級(jí)函數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-01-01
Python爬蟲(chóng)之Selenium中frame/iframe表單嵌套頁(yè)面
這篇文章主要介紹了Python爬蟲(chóng)之Selenium中frame/iframe表單嵌套頁(yè)面,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
詳解Python如何根據(jù)給定模型計(jì)算權(quán)值
這篇文章將通過(guò)一個(gè)簡(jiǎn)單的例子,為大家展示Python如何根據(jù)給定的模型結(jié)構(gòu)來(lái)計(jì)算和提取權(quán)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-11-11
python wav模塊獲取采樣率 采樣點(diǎn)聲道量化位數(shù)(實(shí)例代碼)
這篇文章主要介紹了python wav模塊獲取采樣率 采樣點(diǎn)聲道量化位數(shù),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
Python從Excel讀取數(shù)據(jù)并使用Matplotlib繪制成二維圖像
本課程實(shí)現(xiàn)使用 Python 從 Excel 讀取數(shù)據(jù),并使用 Matplotlib 繪制成二維圖像。這一過(guò)程中,將通過(guò)一系列操作來(lái)美化圖像,最終得到一個(gè)可以出版級(jí)別的圖像。本課程對(duì)于需要書(shū)寫(xiě)實(shí)驗(yàn)報(bào)告,學(xué)位論文,發(fā)表文章,做報(bào)告的學(xué)員具有較大價(jià)值2023-02-02
Python+Turtle制作七夕愛(ài)心光波表白的示例代碼
七夕要來(lái)啦,小編在閑暇之余創(chuàng)作了一個(gè)基于Python+Turtle的愛(ài)心光波表白,文中有詳細(xì)的代碼示例,對(duì)我們七夕表白有很大的幫助,感興趣的小伙伴們快來(lái)來(lái)看看吧2023-08-08
詳解python爬蟲(chóng)系列之初識(shí)爬蟲(chóng)
這篇文章主要介紹了python爬蟲(chóng)系列之初識(shí)爬蟲(chóng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
python中實(shí)現(xiàn)定時(shí)任務(wù)的幾種方案
本文呢給大家總結(jié)以下幾種方案實(shí)現(xiàn)定時(shí)任務(wù),可根據(jù)不同需求去使用不同方案,文章通過(guò)代碼示例介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以參考下2023-10-10
10個(gè)Python Excel自動(dòng)化腳本分享
在數(shù)據(jù)處理和分析的過(guò)程中,Excel文件是我們?nèi)粘9ぷ髦谐R?jiàn)的格式,本文將分享10個(gè)實(shí)用的Excel自動(dòng)化腳本,希望可以幫助大家更輕松地掌握這些技能2025-02-02

