vscode编写一个简单的人脸检测GUI程序(1)

这个程序我是用的vscode写的(vscode是真的好用,简洁,喜欢这个编辑器哈哈),关于如何给vscode配置pyqt5以及如何解决配置过程遇到的问题,这些我在下一个博客进行解释。

这篇博客皆是我的原创,请尊重鄙人的劳动成果(谢谢),如果转载,请附上博客链接。

(1)第一步,布局GUI界面

我们使用QTDisginer设计GUI界面,其中摄像头的显示使用QLabel控件,按钮使用QRadioButton控件,对按钮进行解释的文本我写在QLineEdit里面。使用QTextEdit来显示视频的参数,同时使用QLineEdit的控件对刚刚那个控件进行解释。

(2)第二步,实列化主程序

if __name__ == "__main__":
    app = QApplication(sys.argv)
    md = MainCode()
    md.show()
    sys.exit(app.exec_())

 

sys模块的解释

sys.argv

功能:在外部向程序内部传递参数

 

sys.exit(n)

功能:执行到主程序末尾,解释器自动退出,但是如果需要中途退出程序,可以调用sys.exit函数,带有一个可选的整数参数返回给调用它的程序,表示你可以在主程序中捕获对sys.exit的调用。(0是正常退出,其他为异常)

更加具体的使用方法可以参考https://www.cnblogs.com/cherishry/p/5725184.html。

 

application类

QApplication类:用于管理图形用户界面应用程序的控制流和主要设置。它包含主事件循环,对来自窗口系统和其他资源的所有事件进行处理和调度;它也对应用程序的初始化和结束进行处理,并且提供对话管理;还对绝大多数系统范围和应用程序范围的设置进行处理。

更加具体的解释参考https://blog.csdn.net/qq_21342281/article/details/85322927

(3)第三步将视频的帧图像导入Qlabel中。

 def Face_Datection(self):
        faceCascade = cv2.CascadeClassifier(
            'D:\\Anaconda\\pkgs\\libopencv-3.4.2-h20b85fd_0\\Library\\etc\\haarcascades\\haarcascade_frontalface_default.xml')  # 加载级联分类器
        ret, img = self.cap.read()  # 读取摄像头的帧
        img = cv2.flip(img, 1) #镜像图
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换成灰度图片
        self.faces = faceCascade.detectMultiScale(
            gray,  # 检测图片
            scaleFactor=1.1,  
            minNeighbors=3,
            minSize=(20, 20)
        )
        for (x, y, w, h) in self.faces:
            cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)  # 画矩形
            roi_gray = gray[y:y + h, x:x + w]
            roi_color = img[y:y + h, x:x + w]
        return  img


def show_picture(self):
        if self.vidoe_show_status == True:
            img = self.Face_Datection()
            showImage = QtGui.QImage(img.data, img.shape[1],img.shape[0],  QtGui.QImage.Format_RGB888)
            self.video_show.setPixmap(QtGui.QPixmap.fromImage(showImage))
        else:
            img = np.ones([640,480,1], dtype = np.uint8)* 255 #用numpy创建纯白的图片
            showImage = QtGui.QImage(img.data, img.shape[1],img.shape[0],  QtGui.QImage.Format_Grayscale8)
            self.video_show.setPixmap(QtGui.QPixmap.fromImage(showImage))

第1步

使用Face_Datection()函数对图像中的人脸进行检测,并标记人脸。其中我们使用使用cap.read()函数将视频流拍到的图片先读取出来,之后将BGR图像转化为灰度图,以便后面可以快速的检测出人脸。

第2步

使用show_picture()函数将已经标记好人脸的图片显示在QLabel控件上面。其中video_show_status的bool类型数据,作用是用来判断当前是否显示图像。

如果video_show_status的值为True,则需要显示视频拍到的图像在Qlabel控件上面。因为接收的图像为BGR(opencv接收的彩色图像为BGR),需要使用QImage函数将它转为RGB图像。之后再通过QPixmap显示出来。

下面这个连接是QImage()函数的最后一个参数的详细解析,根据这个链接你可以由自己读取到的图片自由选择参数。https://blog.csdn.net/weixin_39485901/article/details/88047291

下面这个链接是讲解我的代码为什么要先Qimage在使用QPixmap原因https://blog.csdn.net/qq_39654127/article/details/81906232

 

(4)图片已经能够显示在QLbel控件上,但是我们需要不断更新图片以保证出现视频的效果。

那么这里我选择使用QT中的定时器QTimer。

        self.timer = QTimer(self) #实列化一个计时器
        self.cap = cv2.VideoCapture(0)  #打开摄像头
        self.cap.set(3, 640)  # set Width
        self.cap.set(4, 480)  # set Height
        self.timer.timeout.connect(self.show_picture)  #连接显示上一步图片的函数
        self.timer.timeout.connect(self.set_video_data)#这个连接的是显示视频数据的函数,譬
                                                        #如视频打开的时间,视频中的人数。
        self.timer.start(40) #使用start函数将timer开始,并且每过40毫秒触发一次定时器,start触
                             #发timeout,timeout触发其所connect的函数

(5)如果你也想实现实时报告视频的数据(视频时长,视频中的人数)接着看。

前面提过我们使用QTextEdit控件来显示视频的参数。

这里的set_video_data()就是上面程序的那个函数,我们使用定时器不段更新数据,并使用set_video_data()将它显示出来。

def set_video_data(self):
        if self.vidoe_show_status == True: #判断此时摄像头的状态,打开就实时报告数据。
            self.endtime = datetime.datetime.now()  #记录摄像头运行到此时的时间
            running_time = (self.endtime - self.starttime).seconds #startime是随着我们打开摄像头时开始计时的。
            self.textEdit.setPlainText("视频打开的时间:%f\n视频中出现的人数:%d\n " % (running_time,len(self.faces)))   #setPlainText是显示文本信息的函数。

关于具体程序计时方法,请看这个博客https://www.cnblogs.com/rookie-c/p/5827694.html

 

那么到这里这个程序已经基本完成了。以下是全部程序,不建议新手(虽然我也是新手)直接复制代码,建议先看我上面的代码讲解,再来实现下面的代码。

#coding:utf-8
import cv2
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow,QFileDialog
from PyQt5.QtCore import QTimer
from PyQt5 import QtGui
import Ui_welcom
import time
import datetime
from mail import Mail
import numpy as np


class MainCode(QMainWindow, Ui_welcom.Ui_Dialog):
    email_warning_status = True
    faces = []  
    vidoe_show_status = False
    starttime = 0
    endtime = 0
    def __init__(self):
        QMainWindow.__init__(self)
        Ui_welcom.Ui_Dialog.__init__(self)
        self.setupUi(self)
        self.close_video.setChecked(True)
        self.open_video.clicked.connect(self.switch_video_show)
        self.close_video.clicked.connect(self.switch_video_show)
        self.timer = QTimer(self)
        self.cap = cv2.VideoCapture(0)  #打开摄像头
        self.cap.set(3, 640)  # set Width
        self.cap.set(4, 480)  # set Height
        self.timer.timeout.connect(self.show_picture)
        self.timer.timeout.connect(self.set_video_data)
        self.timer.start(40)
        
        

    def set_video_data(self):
        if self.vidoe_show_status == True:
            self.endtime = datetime.datetime.now()
            running_time = (self.endtime - self.starttime).seconds
            self.textEdit.setPlainText("视频打开的时间:%f\n视频中出现的人数:%d\n " % (running_time,len(self.faces)))


    
    def switch_video_show(self):
        if self.open_video.isChecked() == True:
            self.starttime = datetime.datetime.now()
            self.close_video.setChecked(False)
            self.vidoe_show_status = True
        else:
            self.open_video.setChecked(False)
            self.vidoe_show_status = False

   

    def show_picture(self):
        if self.vidoe_show_status == True:
            img = self.Face_Datection()
            showImage = QtGui.QImage(img.data, img.shape[1],img.shape[0],  QtGui.QImage.Format_RGB888)
            self.video_show.setPixmap(QtGui.QPixmap.fromImage(showImage))
        else:
            img = np.ones([640,480,1], dtype = np.uint8)* 255
            showImage = QtGui.QImage(img.data, img.shape[1],img.shape[0],  QtGui.QImage.Format_Grayscale8)
            self.video_show.setPixmap(QtGui.QPixmap.fromImage(showImage))
        

    def Face_Datection(self):
        faceCascade = cv2.CascadeClassifier(
            'D:\\Anaconda\\pkgs\\libopencv-3.4.2-h20b85fd_0\\Library\\etc\\haarcascades\\haarcascade_frontalface_default.xml')  # 加载级联分类器
        ret, img = self.cap.read()  # 读取摄像头的帧
        img = cv2.flip(img, 1)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换成灰度图片
        self.faces = faceCascade.detectMultiScale(
            gray,  # 检测图片
            scaleFactor=1.1,  
            minNeighbors=3,
            minSize=(20, 20)
        )
        for (x, y, w, h) in self.faces:
            cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)  # 画矩形
            roi_gray = gray[y:y + h, x:x + w]
            roi_color = img[y:y + h, x:x + w]
        return  img




if __name__ == "__main__":
    app = QApplication(sys.argv)
    md = MainCode()
    md.show()
    sys.exit(app.exec_())

 

你可能感兴趣的:(GUI)