Yolov5(v5.0)+pyqt5界面設(shè)計(jì)圖文教程
1.下載安裝pyqt5工具包以及配置ui界面開發(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 是通過拖拽的方式放置控件,并實(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文件的專門存儲(chǔ)
點(diǎn)擊Tools->External Tools->Qt Designer進(jìn)行圖形界面創(chuàng)建.
3.2 創(chuàng)建一個(gè)Main Window窗口
3.3 完成基本界面開發(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, "打開圖片", "", "*.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, "打開視頻", "", "*.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"打開視頻失敗", 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"打開攝像頭失敗", 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)文章
Python面向?qū)ο髮?shí)現(xiàn)數(shù)據(jù)分析的實(shí)例詳解
這篇文章主要通過幾個(gè)實(shí)例為大家詳細(xì)介紹了Python面向?qū)ο髮?shí)現(xiàn)數(shù)據(jù)分析的方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定幫助,需要的可以參考一下2023-01-01Python實(shí)例方法與類方法和靜態(tài)方法介紹與區(qū)別分析
在 Python 中,實(shí)例方法(instance method),類方法(class method)與靜態(tài)方法(static method)經(jīng)常容易混淆。本文通過代碼例子來說明它們的區(qū)別2022-10-10Python實(shí)現(xiàn)猜數(shù)字小游戲
這篇文章介紹了Python實(shí)現(xiàn)猜數(shù)字小游戲,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以收藏下,方便下次瀏覽觀看2021-12-12Python爬蟲實(shí)戰(zhàn)案例之爬取喜馬拉雅音頻數(shù)據(jù)詳解
這篇文章主要介紹了Python爬蟲實(shí)戰(zhàn)案例之取喜馬拉雅音頻數(shù)據(jù)詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12