opencv-python 小白笔记(13)

第十三节:opencv与pyqt的简单集成

  • (一)环境配置
  • (二)程序实现
  • (三)结语

下面程序是将opencv的人脸识别和车牌识别用pyqt进行集成。pyqt的框架是借鉴了其他大佬的程序。

本来是想对程序进行打包的,但一直都没成功,难搞奥~。程序都有备注,了解pyqt的小伙伴们应该都能看懂,有需要的需要的小伙伴可以在我的程序基础上进行魔改,得到自己想要的程序。

(一)环境配置

首先你需要在原来的,opencv环境下导入pyqt的库,你可以用anaconda,也可以pip安装。然后就是如果你需要打包程序,还需导入pyinstaller,方法同上。
识别车牌模型文件的百度链接
提取码:5ng2

识别人脸模型文件的百度链接
提取码:0fop

(二)程序实现

from PyQt5 import QtCore, QtGui, QtWidgets
import sys
import cv2


class Ui_MainWindow(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.timer_camera = QtCore.QTimer()  # 定义定时器,用于控制显示视频的帧率
        self.timer_camera1 = QtCore.QTimer()  # 定义定时器,用于控制显示视频的帧率
        self.cap = cv2.VideoCapture()  # 视频流
        self.CAM_NUM = 0  # 为0时表示视频流来自笔记本内置摄像头

        self.set_ui()  # 初始化程序界面
        self.slot_init()  # 初始化槽函数

    '''程序界面布局'''

    def set_ui(self):
        self.__layout_main = QtWidgets.QHBoxLayout()  # 总布局
        self.__layout_fun_button = QtWidgets.QVBoxLayout()  # 按键布局
        self.__layout_data_show = QtWidgets.QVBoxLayout()  # 数据(视频)显示布局
        self.button_open_camera = QtWidgets.QPushButton('打开相机,识别人脸')  # 建立用于打开摄像头,识别人脸的按键
        self.button_open_camera1 = QtWidgets.QPushButton('打开相机,识别车牌')  # 建立用于打开摄像头,识别人脸的按键
        self.button_close = QtWidgets.QPushButton('退出')  # 建立用于退出程序的按键
        self.button_open_camera.setMinimumHeight(51)  # 设置按键大小
        self.button_open_camera1.setMinimumHeight(51)  # 设置按键大小
        self.button_close.setMinimumHeight(51)
        self.setWindowTitle('Detect')
        self.button_close.move(11, 101)  # 移动按键

        '''信息显示'''
        self.label_show_camera = QtWidgets.QLabel()  # 定义显示视频的Label
        self.label_show_camera.setFixedSize(641, 481)  # 给显示视频的Label设置大小为641x481
        '''把按键加入到按键布局中'''
        self.__layout_fun_button.addWidget(self.button_open_camera)  # 把打开摄像头,识别人脸的按键放到按键布局中
        self.__layout_fun_button.addWidget(self.button_open_camera1)  # 把打开摄像头,识别人脸的按键放到按键布局中
        self.__layout_fun_button.addWidget(self.button_close)  # 把退出程序的按键放到按键布局中
        '''把某些控件加入到总布局中'''
        self.__layout_main.addLayout(self.__layout_fun_button)  # 把按键布局加入到总布局中
        self.__layout_main.addWidget(self.label_show_camera)  # 把用于显示视频的Label加入到总布局中
        '''总布局布置好后就可以把总布局作为参数传入下面函数'''
        self.setLayout(self.__layout_main)  # 到这步才会显示所有控件

    '''初始化所有回调函数'''

    def slot_init(self):
        self.button_open_camera.clicked.connect(self.button_open_camera_clicked)  # 若该按键被点击,则调用button_open_camera_clicked()
        self.button_open_camera1.clicked.connect(self.button_open_camera_clicked1)  # 若该按键被点击,则调用button_open_camera_clicked()
        self.timer_camera.timeout.connect(self.show_camera)  # 若定时器结束,则调用show_camera()
        self.timer_camera1.timeout.connect(self.show_camera1)  # 若定时器结束,则调用show_camera1()
        self.button_close.clicked.connect(self.close)  # 若该按键被点击,则调用close(),注意这个close是父类QtWidgets.QWidget自带的,会关闭程序

    '''回调函数之一'''

    def button_open_camera_clicked(self):
        if self.timer_camera.isActive() == False:  # 若定时器未启动
            flag = self.cap.open(self.CAM_NUM)  # 参数是0,表示打开笔记本的内置摄像头,参数是视频文件路径则打开视频
            if flag == False:  # flag表示open()成不成功
                msg = QtWidgets.QMessageBox.warning(self, 'warning', "请检查相机于电脑是否连接正确", buttons=QtWidgets.QMessageBox.Ok)
            else:
                self.timer_camera.start(30)  # 定时器开始计时30ms,结果是每过30ms从摄像头中取一帧显示
                self.button_open_camera.setText('关闭相机')
        else:
            self.timer_camera.stop()  # 关闭定时器
            self.cap.release()  # 释放视频流
            self.label_show_camera.clear()  # 清空视频显示区域
            self.button_open_camera.setText('打开相机')

    def button_open_camera_clicked1(self):
        if self.timer_camera1.isActive() == False:  # 若定时器未启动
            flag = self.cap.open(self.CAM_NUM)  # 参数是0,表示打开笔记本的内置摄像头,参数是视频文件路径则打开视频
            if flag == False:  # flag表示open()成不成功
                msg = QtWidgets.QMessageBox.warning(self, 'warning', "请检查相机于电脑是否连接正确", buttons=QtWidgets.QMessageBox.Ok)
            else:
                self.timer_camera1.start(30)  # 定时器开始计时30ms,结果是每过30ms从摄像头中取一帧显示
                self.button_open_camera1.setText('关闭相机')
        else:
            self.timer_camera1.stop()  # 关闭定时器
            self.cap.release()  # 释放视频流
            self.label_show_camera.clear()  # 清空视频显示区域
            self.button_open_camera1.setText('打开相机')

    def show_camera(self):#识别人脸
        flag, self.image = self.cap.read()  # 从视频流中读取

        show = cv2.resize(self.image, (640, 480))  # 把读到的帧的大小重新设置为 640x480
        show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)  # 视频色彩转换回RGB,这样才是现实的颜色
        cv2.flip(show,1,show)#水平翻转

        faceCascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
        gray = cv2.cvtColor(show, cv2.COLOR_BGR2GRAY)
        gray = cv2.medianBlur(gray, 5)  # 中值滤波,这个中值滤波,小伙伴可以尝试将它去掉看看
        img = cv2.GaussianBlur(gray, (3, 3), 0)  # 高斯滤波降噪处理,是不是感觉有图像处理的地方,就有高斯滤波
        th1 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 17,
                                    6)  # 自适应二值化  # 自适应二值化处理
        # 人脸检测,1.22分别为图片缩放比例和需要检测的有效点数
        faceRects = faceCascade.detectMultiScale(th1, scaleFactor=1.1, minNeighbors=4)  # 这几个参数我调了好几次,个人感觉只能这样了

        if len(faceRects) > 0:
            # 历遍每次检测的所有脸
            for face in faceRects:
                x, y, w, h = face  # face是一个元祖,返回了分类器的检测结果,包括起始点的坐标和高度宽度
                cv2.rectangle(show, (x - 5, y - 5), (x + w + 5, y + h + 5), (0, 255, 0), 3)  # 绘制人脸检测的线框(还是原谅色)
                font = cv2.FONT_HERSHEY_SIMPLEX  # 创建摄像头前置的文字框
                cv2.putText(show, 'face', (x - 30, y - 30), font, 1, (0, 255, 0), 3)#原谅色



        showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0],
                                 QtGui.QImage.Format_RGB888)  # 把读取到的视频数据变成QImage形式
        self.label_show_camera.setPixmap(QtGui.QPixmap.fromImage(showImage))  # 往显示视频的Label里 显示QImage

    def show_camera1(self):#识别车牌
        flag, self.image = self.cap.read()  # 从视频流中读取

        show = cv2.resize(self.image, (640, 480))  # 把读到的帧的大小重新设置为 640x480
        show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)  # 视频色彩转换回RGB,这样才是现实的颜色
        cv2.flip(show,1,show)#水平翻转

        platenumber = cv2.CascadeClassifier("haarcascade_russian_plate_number.xml")
        gray = cv2.cvtColor(show, cv2.COLOR_BGR2GRAY)
        gray = cv2.medianBlur(gray, 5)  # 中值滤波,这个中值滤波,小伙伴可以尝试将它去掉看看
        img = cv2.GaussianBlur(gray, (3, 3), 0)  # 高斯滤波降噪处理,是不是感觉有图像处理的地方,就有高斯滤波
        th1 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 17,
                                    6)  # 自适应二值化  # 自适应二值化处理


        numberPlates = platenumber.detectMultiScale(th1, 1.1, 10)

        for (x, y, w, h) in numberPlates:
            ratio = w / float(h)
            print(ratio)
            if ratio > 2.7 and ratio < 3.3:  # 这里过滤一下
                cv2.rectangle(show, (x, y), (x + w, y + h), (255, 0, 0), 3)
                cv2.putText(show, "Number Plate", (x, y - 5),
                            cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 255, 0), 3)#原谅色
                imgRoi = img[y:y + h, x:x + w]
                cv2.imshow("ROI", imgRoi)


        showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0],
                                 QtGui.QImage.Format_RGB888)  # 把读取到的视频数据变成QImage形式
        self.label_show_camera.setPixmap(QtGui.QPixmap.fromImage(showImage))  # 往显示视频的Label里 显示QImage


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)  # 固定的,表示程序应用
    ui = Ui_MainWindow()  # 实例化Ui_MainWindow
    ui.show()  # 调用ui的show()以显示。同样show()是源于父类QtWidgets.QWidget的
    sys.exit(app.exec_())  # 不加这句,程序界面会一闪而过

opencv-python 小白笔记(13)_第1张图片
上面是程序开始运行的主界面,下面是跑程序的结果展示
跑程序的视频

(三)结语

学习opencv有很多的方法,我的建议是你可以加一些群,可以充分利用B站,CSDN,和百度。

在我的博客中,我不会讲解opencv的算法实现(当然我也不太会),我只会讲解一些函数的调用,不理解就多改一些参数,多尝试尝试,慢慢你就理解来。相信你总有一天可以说opencv不过“Ctrl+C,Crtl+V”

PS:如果有什么错误的地方,还请大家批评指正,不过错了也没啥关系,反正也没什么人看
最后,希望小伙伴们都能有所收获。码字不易,喜欢的话,关注一波在走吧

你可能感兴趣的:(opencv-python笔记,人脸相关,opencv,图像识别,pyqt)