pyqt5+opencv+yolov3的Demo

pyqt5+opencv+yolov3的Demo

前言

本文的目的是pyqt5+opencv+yolov3的Demo,利用opencv采集电脑摄像头的图像数据,利用yolov3进行检测,并利用pyqt5将功能集成到ui中。

一、ui界面编写

直接利用Qt Designer拖拽形成.ui文件,然后利用pyuic工具将ui文件转换成py文件,下为自动生成的代码。


class Ui_DetectWithUIDemo(object):
    def setupUi(self, DetectWithUIDemo):
        DetectWithUIDemo.setObjectName("DetectWithUIDemo")
        DetectWithUIDemo.resize(800, 600)
        self.label = QtWidgets.QLabel(DetectWithUIDemo)
        self.label.setGeometry(QtCore.QRect(300, 0, 191, 61))
        self.label.setObjectName("label")
        self.label_Detect = QtWidgets.QLabel(DetectWithUIDemo)
        self.label_Detect.setGeometry(QtCore.QRect(130, 60, 640, 480))
        self.label_Detect.setFrameShape(QtWidgets.QFrame.Panel)
        self.label_Detect.setFrameShadow(QtWidgets.QFrame.Plain)
        self.label_Detect.setObjectName("label_Detect")
        self.pushButton = QtWidgets.QPushButton(DetectWithUIDemo)
        self.pushButton.setGeometry(QtCore.QRect(10, 100, 112, 61))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(DetectWithUIDemo)
        self.pushButton_2.setGeometry(QtCore.QRect(10, 210, 112, 61))
        self.pushButton_2.setObjectName("pushButton_2")

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

    def retranslateUi(self, DetectWithUIDemo):
        _translate = QtCore.QCoreApplication.translate
        DetectWithUIDemo.setWindowTitle(_translate("DetectWithUIDemo", "DetectWithUIDemo"))
        self.label.setText(_translate("DetectWithUIDemo", "\n"
"\n"
"

DetectWithUIDemo

"
)) self.label_Detect.setText(_translate("DetectWithUIDemo", "DetectDemoShow")) self.pushButton.setText(_translate("DetectWithUIDemo", "Start")) self.pushButton_2.setText(_translate("DetectWithUIDemo", "Close"))

二、 子线程类

子线程类继承自QThread,定义带参数的一个信号量Send_signal,重写run函数,负责图像数据的获取、识别检测、绘制图像。具体 Code如下:

class DetectThread(QThread):
    Send_signal = pyqtSignal(numpy.ndarray)
    def __init__(self):
        super(DetectThread, self).__init__()
        self.capture = cv2.VideoCapture(0)
        self.capture.set(3, 640)
        self.capture.set(4, 480)
        self.net, self.LABELS, self.COLORS = dn_cam.loadModel()

    def run(self):
        ret, self.frame = self.capture.read()
        while ret:
            ret, self.frame = self.capture.read()
            self.detectCall()
            self.msleep(10)

    def detectCall(self):
        #call detect func
        classIDs, confidences, boxes = dn_cam.detectionImage(self.frame, self.net)
        self.drawPre(self.frame, boxes, classIDs, self.LABELS, self.COLORS, confidences)

    def drawPre(self, image, boxes, classIDs, LABELS, COLORS, confidences):
        for i in range(len(classIDs)):
            (x, y) = (boxes[i][0], boxes[i][1])
            (w, h) = (boxes[i][2], boxes[i][3])
            # 在原图上绘制边框和类别
            color = [int(c) for c in COLORS[classIDs[i]]]
            cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
            text = "{}: {:.4f}".format(LABELS[classIDs[i]], confidences[i])
            cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
        print(type(image))
        # 发送pyqt信号
        self.Send_signal.emit(image)
        # return image

三、主逻辑

给按钮绑定槽函数,初始化界面。

class UI_logic(QtWidgets.QWidget, Ui_DetectWithUIDemo):
    def __init__(self):
        super(UI_logic, self).__init__()
        self.ui = Ui_DetectWithUIDemo()
        self.wiget = QtWidgets.QWidget()
        self.ui.setupUi(self.wiget)
        self.wiget.show()
        self.init_slot()
        self.net, self.LABELS, self.COLORS = dn_cam.loadModel()

    def init_slot(self):
        #按钮绑定
        self.ui.pushButton.clicked.connect(self.Button_Start_Click)
        self.ui.pushButton_2.clicked.connect(self.close)

    def Button_Start_Click(self):
        print('You have clicked Start_button')
        self.detectThread = DetectThread()
        self.detectThread.Send_signal.connect(self.Display)
        self.detectThread.start()

    def closeEvent(self, event):
        ok = QtWidgets.QPushButton()
        cancel = QtWidgets.QPushButton()
        msg = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Warning, u'Close', u'Are you sure to quit?')
        msg.addButton(ok, QtWidgets.QMessageBox.ActionRole)
        msg.addButton(cancel, QtWidgets.QMessageBox.RejectRole)
        ok.setText(u'Yes')
        cancel.setText(u'No')
        if msg.exec_() == QtWidgets.QMessageBox.RejectRole:
            event.ignore()
        else:
            self.detectThread.exit()
            self.wiget.close()

    def Display(self, show):
        self.show = cv2.resize(show, (640, 480))
        self.show = cv2.cvtColor(self.show, cv2.COLOR_BGR2RGB)
        self.showImage = QtGui.QImage(self.show.data, self.show.shape[1], \
                                      self.show.shape[0], QtGui.QImage.Format_RGB888)
        self.ui.label_Detect.setPixmap(QtGui.QPixmap.fromImage(self.showImage))

四、全部代码

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

# Form implementation generated from reading ui file 'DetectWithUIDemo.ui'
#
# Created by: PyQt5 UI code generator 5.14.1
#
# WARNING! All changes made in this file will be lost!
import numpy
from PyQt5 import QtCore, QtGui, QtWidgets

import cv2, sys
from pythonDic import onecamDetect as dn_cam
from PyQt5.QtCore import QThread, pyqtSignal


class Ui_DetectWithUIDemo(object):
    def setupUi(self, DetectWithUIDemo):
        DetectWithUIDemo.setObjectName("DetectWithUIDemo")
        DetectWithUIDemo.resize(800, 600)
        self.label = QtWidgets.QLabel(DetectWithUIDemo)
        self.label.setGeometry(QtCore.QRect(300, 0, 191, 61))
        self.label.setObjectName("label")
        self.label_Detect = QtWidgets.QLabel(DetectWithUIDemo)
        self.label_Detect.setGeometry(QtCore.QRect(130, 60, 640, 480))
        self.label_Detect.setFrameShape(QtWidgets.QFrame.Panel)
        self.label_Detect.setFrameShadow(QtWidgets.QFrame.Plain)
        self.label_Detect.setObjectName("label_Detect")
        self.pushButton = QtWidgets.QPushButton(DetectWithUIDemo)
        self.pushButton.setGeometry(QtCore.QRect(10, 100, 112, 61))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(DetectWithUIDemo)
        self.pushButton_2.setGeometry(QtCore.QRect(10, 210, 112, 61))
        self.pushButton_2.setObjectName("pushButton_2")

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

    def retranslateUi(self, DetectWithUIDemo):
        _translate = QtCore.QCoreApplication.translate
        DetectWithUIDemo.setWindowTitle(_translate("DetectWithUIDemo", "DetectWithUIDemo"))
        self.label.setText(_translate("DetectWithUIDemo", "\n"
"\n"
"

DetectWithUIDemo

"
)) self.label_Detect.setText(_translate("DetectWithUIDemo", "DetectDemoShow")) self.pushButton.setText(_translate("DetectWithUIDemo", "Start")) self.pushButton_2.setText(_translate("DetectWithUIDemo", "Close")) # class UI_logic(QtWidgets.QWidget, Ui_DetectWithUIDemo): def __init__(self): super(UI_logic, self).__init__() self.ui = Ui_DetectWithUIDemo() self.wiget = QtWidgets.QWidget() self.ui.setupUi(self.wiget) self.wiget.show() self.init_slot() self.net, self.LABELS, self.COLORS = dn_cam.loadModel() def init_slot(self): #按钮绑定 self.ui.pushButton.clicked.connect(self.Button_Start_Click) self.ui.pushButton_2.clicked.connect(self.close) def Button_Start_Click(self): print('You have clicked Start_button') self.detectThread = DetectThread() self.detectThread.Send_signal.connect(self.Display) self.detectThread.start() def closeEvent(self, event): ok = QtWidgets.QPushButton() cancel = QtWidgets.QPushButton() msg = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Warning, u'Close', u'Are you sure to quit?') msg.addButton(ok, QtWidgets.QMessageBox.ActionRole) msg.addButton(cancel, QtWidgets.QMessageBox.RejectRole) ok.setText(u'Yes') cancel.setText(u'No') if msg.exec_() == QtWidgets.QMessageBox.RejectRole: event.ignore() else: self.detectThread.exit() self.wiget.close() def Display(self, show): self.show = cv2.resize(show, (640, 480)) self.show = cv2.cvtColor(self.show, cv2.COLOR_BGR2RGB) self.showImage = QtGui.QImage(self.show.data, self.show.shape[1], \ self.show.shape[0], QtGui.QImage.Format_RGB888) self.ui.label_Detect.setPixmap(QtGui.QPixmap.fromImage(self.showImage)) class DetectThread(QThread): Send_signal = pyqtSignal(numpy.ndarray) def __init__(self): super(DetectThread, self).__init__() self.capture = cv2.VideoCapture(0) self.capture.set(3, 640) self.capture.set(4, 480) self.net, self.LABELS, self.COLORS = dn_cam.loadModel() def run(self): ret, self.frame = self.capture.read() while ret: ret, self.frame = self.capture.read() self.detectCall() self.msleep(10) def detectCall(self): #call detect func classIDs, confidences, boxes = dn_cam.detectionImage(self.frame, self.net) self.drawPre(self.frame, boxes, classIDs, self.LABELS, self.COLORS, confidences) def drawPre(self, image, boxes, classIDs, LABELS, COLORS, confidences): for i in range(len(classIDs)): (x, y) = (boxes[i][0], boxes[i][1]) (w, h) = (boxes[i][2], boxes[i][3]) # 在原图上绘制边框和类别 color = [int(c) for c in COLORS[classIDs[i]]] cv2.rectangle(image, (x, y), (x + w, y + h), color, 2) text = "{}: {:.4f}".format(LABELS[classIDs[i]], confidences[i]) cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) print(type(image)) # 发送pyqt信号 self.Send_signal.emit(image) # return image if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) demo = UI_logic() sys.exit(app.exec_())

五、实验结果

Demo能够稳定运行,但是还是存在一些问题,仅仅做个Demo吧!
pyqt5+opencv+yolov3的Demo_第1张图片
pyqt5+opencv+yolov3的Demo_第2张图片

你可能感兴趣的:(无聊之间,python,opencv,pyqt,图像识别)