百度AI人脸识别与检测三:学生人脸识别打卡签到系统通过OpenCV实现电脑摄像头数据在Label控件上的实时显示

《百度AI人脸识别与检测》专栏为项目专栏,从零到一,从无到有开发一个学生人脸识别签到系统;主要用到的技术有百度开放平台中的人脸检测、人脸识别、Python图形界面开发PyQt5、线程的管理、以及通过python调用百度接口实现人脸检测、百度开放平台中人脸检测技术文档的理解等,由浅入深、由局部到整体的一个项目学习过程,如果你想对人脸识别感兴趣,对python的图形界面设计感兴趣,可以订阅本专栏,因为对你可能有帮助哦!

前文参考:

百度AI人脸识别与检测一:学生人脸识别签到系统简介及百度AI开放平台账号注册和人脸实例应用创建
百度AI人脸识别与检测二:学生人脸识别打卡签到系统主界面功能需求和设计以及通过Python实现界面运行

上次博客,我们将学生人脸识别打卡签到系统的界面设计完成,并且通过python代码实现了界面的运行显示,也就是说,学生人脸识别打卡签到系统的界面设计部分已经完成,接下来要做的就是按照界面上的功能需求,实现这些功能。

既然是人脸识别打开签到,就离不开摄像头画面数据的获取,而本项目主要通过电脑本身的摄像头进行打卡签到系统的模拟,因此,除了摄像头打开,还要将摄像头的数据进行实时显示,这就是本次博客需要将的内容,将摄像头捕获到的画面进行实时显示,并显示在界面设计上的画面显示框中,一起学习吧!



一、摄像头的打开和实时数据获取

在做项目的同时,我们需要注意到函数的分类与类的创建,在类中创建函数是每个程序员需要掌握的必要技能,通过类的对象调用函数,不仅能够对函数进行封装,还能够进行内容参数的加密

1、创建操作摄像头的类

1)、创建cameraVideo.py文件,该文件中主要用来进行摄像头系列操作
在这里插入图片描述
2)、创建类camera并进行类的初始化

'''
创建类对象
open函数完成摄像头的配置打开
'''
class camera():
    '''
    类初始化,相当于构造函数
    '''
    def __init__(self):
        pass

2、创建打开摄像头函数

由于我们点击开始签到按钮摄像头画面就要进行实时显示,因此,我们需要将打开摄像头的操作写进初始化函数中,只要调用该函数,摄像头就自动进行打开并进行实时画面的显示

'''
创建类对象
open函数完成摄像头的配置打开
'''
import cv2
import numpy as np

class camera():
    '''
    类初始化,相当于构造函数
    '''
    def __init__(self):
        self.open_camera()
    '''
        以下函数通过opencv打开笔记本电脑默认摄像头
    '''
    def open_camera(self):
        # 0表示内置默认摄像头,self.capture为全局变量
        self.capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
        # isopend()函数返回一个布尔值,来判断是否打开摄像头
        if self.capture.isOpened():
            print("摄像头打开成功")
        # 定义一个多维数组,用来存储获取的画面数据
        self.currentframe = np.array([])

3、实现摄像头画面获取

1)、摄像头数据获取
在上面的self.capture得到结果中,我们需要进行结果的读取,通过self.capture.read() 读取摄像头画面,并且实现按帧读取,每一帧就是一副图像,当这些图像连接起来,就是一条视频图像,返回的结果为ret,pic_data,pic_data就是我们需要的结果,而ret主要用来判断去取状态,如果摄像头有数据,返回True,没有则返回Flase;因此我们需要得到它,并且将他返回

'''
创建类对象
open函数完成摄像头的配置打开
'''
import cv2
import numpy as np

class camera():
    '''
    类初始化,相当于构造函数
    '''
    def __init__(self):
        self.open_camera()
    '''
        以下函数通过opencv打开笔记本电脑默认摄像头
    '''
    def open_camera(self):
        # 0表示内置默认摄像头,self.capture为全局变量
        self.capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
        # isopend()函数返回一个布尔值,来判断是否打开摄像头
        if self.capture.isOpened():
            print("摄像头打开成功")
        # 定义一个多维数组,用来存储获取的画面数据
        self.currentframe = np.array([])

    '''
        获取摄像头数据
    '''
    def read_camera(self):
        ret,pic_data=self.capture.read()
        if not ret:
            print("获取摄像头数据失败")
            return None
        return pic_data

2)、摄像头图像格式转换
因为在界面Label框中进行显示的图像格式是QPixmap的图像格式,而OpenCV读取的图像格式为像素数组格式的图像,因此需要进行转换才能在Label上进行显示:返回参数为qpix(用于Label框显示的格式图像)

'''
创建类对象
open函数完成摄像头的配置打开
'''
import cv2
import numpy as np
from PyQt5.QtGui import QImage, QPixmap


class camera():
    '''
    类初始化,相当于构造函数
    '''
    def __init__(self):
        self.open_camera()
    '''
        以下函数通过opencv打开笔记本电脑默认摄像头
    '''
    def open_camera(self):
        # 0表示内置默认摄像头,self.capture为全局变量
        self.capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
        # isopend()函数返回一个布尔值,来判断是否打开摄像头
        if self.capture.isOpened():
            print("摄像头打开成功")
        # 定义一个多维数组,用来存储获取的画面数据
        self.currentframe = np.array([])

    '''
        获取摄像头数据
    '''
    def read_camera(self):
        ret,pic_data=self.capture.read()
        if not ret:
            print("获取摄像头数据失败")
            return None
        return pic_data

    '''
        摄像头图像格式转换
    '''
    def camera_to_pic(self):
        pic=self.read_camera()
        #摄像头是BGR转换为RGB
        self.currentframe=cv2.cvtColor(pic,cv2.COLOR_BGR2RGB)
        #设置宽高
        #self.currentframe=cv2.cvtColor(self.currentframe,(521,411))
        height,width=self.currentframe.shape[:2]
        #转换格式(界面能够显示的格式)
        #先转换为QImage图片(画面)
        #QImage(data,width,height,format)创建:数据、快读、高度、格式
        qimg=QImage(self.currentframe,width,height,QImage.Format_RGB888)
        qpix=QPixmap.fromImage(qimg)
        return qpix

3)、关闭摄像头
点击关闭签到的同时,需要将摄像头进行关闭,释放摄像头

'''
创建类对象
open函数完成摄像头的配置打开
'''
import cv2
import numpy as np
from PyQt5.QtGui import QImage, QPixmap


class camera():
    '''
    类初始化,相当于构造函数
    '''
    def __init__(self):
        self.open_camera()
    '''
        以下函数通过opencv打开笔记本电脑默认摄像头
    '''
    def open_camera(self):
        # 0表示内置默认摄像头,self.capture为全局变量
        self.capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
        # isopend()函数返回一个布尔值,来判断是否打开摄像头
        if self.capture.isOpened():
            print("摄像头打开成功")
        # 定义一个多维数组,用来存储获取的画面数据
        self.currentframe = np.array([])

    '''
        获取摄像头数据
    '''
    def read_camera(self):
        ret,pic_data=self.capture.read()
        if not ret:
            print("获取摄像头数据失败")
            return None
        return pic_data

    '''
        摄像头图像格式转换
    '''
    def camera_to_pic(self):
        pic=self.read_camera()
        #摄像头是BGR转换为RGB
        self.currentframe=cv2.cvtColor(pic,cv2.COLOR_BGR2RGB)
        #设置宽高
        #self.currentframe=cv2.cvtColor(self.currentframe,(521,411))
        height,width=self.currentframe.shape[:2]
        #转换格式(界面能够显示的格式)
        #先转换为QImage图片(画面)
        #QImage(data,width,height,format)创建:数据、快读、高度、格式
        qimg=QImage(self.currentframe,width,height,QImage.Format_RGB888)
        qpix=QPixmap.fromImage(qimg)
        return qpix
    '''
        关闭摄像头
    '''
    def colse_camera(self):
        #释放摄像头
        self.capture.release()

以上每一步的代码都覆盖前面一步的代码,因此,关闭摄像头的代码为该py文件的全部代码,如果需要代码作为参考,可以直接观看以上步骤的代码,实现OpenCV对摄像头的操作

二、Label控件中摄像头数据的实时显示

上面对摄像头的操作部分已经完毕,接下来,我们需要对打开签到和关闭签到进行按钮事件的绑定,实现打开按钮,Label可以进行笔记本摄像头数据的实时获取,关闭签到可以释放笔记本摄像头!

1、打开签到按钮事件的绑定

1)、打开function_window.py文件,编写打开签到实现的功能函数

from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QMainWindow
from cameraVideo import camera
from mainWindow import Ui_MainWindow
class function_window(Ui_MainWindow,QMainWindow):
    '''
    初始化函数
    '''
    def __init__(self):
        super(function_window, self).__init__()
        self.setupUi(self)
    '''
        打开签到
    '''
    def open_Sign(self):
        #启动摄像头
        self.cameravideo = camera()

打开签到,直接启动摄像头
在这里插入图片描述

2)、实现摄像头数据显示Label框的函数

from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QMainWindow
from cameraVideo import camera
from mainWindow import Ui_MainWindow
class function_window(Ui_MainWindow,QMainWindow):
    '''
    初始化函数
    '''
    def __init__(self):
        super(function_window, self).__init__()
        self.setupUi(self)
    '''
        打开签到
    '''
    def open_Sign(self):
        #启动摄像头
        self.cameravideo = camera()
    '''
        摄像头数据显示
    '''
    def show_cameradata(self):
        #获取摄像头数据
        pic=self.cameravideo.camera_to_pic()
        #在lebel框中显示数据、显示画面
        self.label.setPixmap(pic)

在这里插入图片描述
那么该函数只是进行摄像头一帧图像的显示,而我们需求是要进行实时显示,因此,我们需要在打开摄像头的函数中加入定时器,没多少毫秒进行一帧数据的显示,连接起来就是视频流了
3)、添加定时器,实现摄像头数据的实时显示,每隔10毫秒,调用一次图摄像头画面显示函数

from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QMainWindow
from cameraVideo import camera
from mainWindow import Ui_MainWindow
class function_window(Ui_MainWindow,QMainWindow):
    '''
    初始化函数
    '''
    def __init__(self):
        super(function_window, self).__init__()
        self.setupUi(self)
    '''
        打开签到
    '''
    def open_Sign(self):
        #启动摄像头
        self.cameravideo = camera()
        # 启动定时器进行定时,每隔多长时间进行一次获取摄像头数据进行显示
        self.timeshow = QTimer(self)
        self.timeshow.start(10)
        # 每隔10毫秒产生一个信号timeout
        self.timeshow.timeout.connect(self.show_cameradata)
    '''
        摄像头数据显示
    '''
    def show_cameradata(self):
        #获取摄像头数据
        pic=self.cameravideo.camera_to_pic()
        #在lebel框中显示数据、显示画面
        self.label.setPixmap(pic)

在这里插入图片描述
4)、现在我们对界面的打开签到按钮进行事件绑定吧,绑定到打开签到功能函数上面

from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QMainWindow
from cameraVideo import camera
from mainWindow import Ui_MainWindow
class function_window(Ui_MainWindow,QMainWindow):
    '''
    初始化函数
    '''
    def __init__(self):
        super(function_window, self).__init__()
        self.setupUi(self)
        self.label.setScaledContents(True)#设置图像自适应label显示框
        self.pushButton.clicked.connect(self.open_Sign)
    '''
        打开签到
    '''
    def open_Sign(self):
        #启动摄像头
        self.cameravideo = camera()
        # 启动定时器进行定时,每隔多长时间进行一次获取摄像头数据进行显示
        self.timeshow = QTimer(self)
        self.timeshow.start(10)
        # 每隔10毫秒产生一个信号timeout
        self.timeshow.timeout.connect(self.show_cameradata)
    '''
        摄像头数据显示
    '''
    def show_cameradata(self):
        #获取摄像头数据
        pic=self.cameravideo.camera_to_pic()
        #在lebel框中显示数据、显示画面
        self.label.setPixmap(pic)

在这里插入图片描述

现在运行我们的程序,点击打开签到试一下:
在这里插入图片描述
在这里插入图片描述
我们可以看到,摄像头实时画面的获取已经在label框中进行显示了,而且只有10毫秒的延迟,这种延迟可以成为实时显示了,但目前还不能进行关闭,因此,我们只能点击设计的X按钮进行关闭,下面我们来实现停止签到实现摄像头的关闭

2、关闭签到按钮事件的绑定

1)、关闭签到函数功能函数实现
摄像头的关闭需要注意,应该先关闭定时器,然后关闭定时器的链接函数,不进行摄像头画面的获取,最后再关闭摄像头,注意这样一个顺序

from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QMainWindow
from cameraVideo import camera
from mainWindow import Ui_MainWindow
class function_window(Ui_MainWindow,QMainWindow):
    '''
    初始化函数
    '''
    def __init__(self):
        super(function_window, self).__init__()
        self.setupUi(self)
        self.label.setScaledContents(True)#设置图像自适应label显示框
        self.pushButton.clicked.connect(self.open_Sign)
    '''
        打开签到
    '''
    def open_Sign(self):
        #启动摄像头
        self.cameravideo = camera()
        # 启动定时器进行定时,每隔多长时间进行一次获取摄像头数据进行显示
        self.timeshow = QTimer(self)
        self.timeshow.start(10)
        # 每隔10毫秒产生一个信号timeout
        self.timeshow.timeout.connect(self.show_cameradata)
    '''
        摄像头数据显示
    '''
    def show_cameradata(self):
        #获取摄像头数据
        pic=self.cameravideo.camera_to_pic()
        #在lebel框中显示数据、显示画面
        self.label.setPixmap(pic)
    '''
        关闭签到
    '''
    def close_Sign(self):
        #关闭定时器,不再获取摄像头的数据
        self.timeshow.stop()
        self.timeshow.timeout.disconnect(self.show_cameradata)
        # 关闭摄像头
        self.cameravideo.colse_camera()

在这里插入图片描述
2)、关闭签到按钮事件绑定,对关闭签到按钮绑定在关闭签到函数上

from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QMainWindow
from cameraVideo import camera
from mainWindow import Ui_MainWindow
class function_window(Ui_MainWindow,QMainWindow):
    '''
    初始化函数
    '''
    def __init__(self):
        super(function_window, self).__init__()
        self.setupUi(self)
        self.label.setScaledContents(True)#设置图像自适应label显示框
        self.pushButton.clicked.connect(self.open_Sign)#打开签到事件绑定
        self.pushButton_2.clicked.connect(self.close_Sign())#关闭签到事件绑定
    '''
        打开签到
    '''
    def open_Sign(self):
        #启动摄像头
        self.cameravideo = camera()
        # 启动定时器进行定时,每隔多长时间进行一次获取摄像头数据进行显示
        self.timeshow = QTimer(self)
        self.timeshow.start(10)
        # 每隔10毫秒产生一个信号timeout
        self.timeshow.timeout.connect(self.show_cameradata)
    '''
        摄像头数据显示
    '''
    def show_cameradata(self):
        #获取摄像头数据
        pic=self.cameravideo.camera_to_pic()
        #在lebel框中显示数据、显示画面
        self.label.setPixmap(pic)
    '''
        关闭签到
    '''
    def close_Sign(self):
        #关闭定时器,不再获取摄像头的数据
        self.timeshow.stop()
        self.timeshow.timeout.disconnect(self.show_cameradata)
        # 关闭摄像头
        self.cameravideo.colse_camera()

在这里插入图片描述

3、摄像头打开和关闭测试

1)、点击打开签到,进行摄像头打开并获取实时数据
在这里插入图片描述
2)、点击关闭签到,进行摄像头的关闭
在这里插入图片描述
我们可以发现,关闭签到后,摄像头停止了,但图像画面停止在了最后获取的一帧图像,这不是我们需要的,因此,我们需要添加代码,当点击关闭签到后,我们的画面恢复原始画面或者为自己喜欢的图像
3)、设置关闭签到后,Label显示自己设定的图像

from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QMainWindow, QMessageBox
from cameraVideo import camera
from mainWindow import Ui_MainWindow
class function_window(Ui_MainWindow,QMainWindow):
    '''
    初始化函数
    '''
    def __init__(self):
        super(function_window, self).__init__()
        self.setupUi(self)
        self.label.setScaledContents(True)#设置图像自适应label显示框
        self.pushButton.clicked.connect(self.open_Sign)#打开签到事件绑定
        self.pushButton_2.clicked.connect(self.close_Sign)#关闭签到事件绑定
    '''
        打开签到
    '''
    def open_Sign(self):
        #启动摄像头
        self.cameravideo = camera()
        # 启动定时器进行定时,每隔多长时间进行一次获取摄像头数据进行显示
        self.timeshow = QTimer(self)
        self.timeshow.start(10)
        # 每隔10毫秒产生一个信号timeout
        self.timeshow.timeout.connect(self.show_cameradata)
    '''
        摄像头数据显示
    '''
    def show_cameradata(self):
        #获取摄像头数据
        pic=self.cameravideo.camera_to_pic()
        #在lebel框中显示数据、显示画面
        self.label.setPixmap(pic)
    '''
        关闭签到
    '''
    def close_Sign(self):
        #关闭定时器,不再获取摄像头的数据
        self.timeshow.stop()
        self.timeshow.timeout.disconnect(self.show_cameradata)
        # 关闭摄像头
        self.cameravideo.colse_camera()
        #判断定时器是否关闭,关闭,则显示为自己设定的图像
        if self.timeshow.isActive() == False:
            self.label.setPixmap(QPixmap("./1.jpg"))
        else:
            QMessageBox.about(self,"警告","关闭失败,存在部分没有关闭成功!")

在这里插入图片描述
再次测试,点击关闭签到之后,结果如下所示:
在这里插入图片描述
这不就点击关闭签到后,设置成了我们想要的图像了嘛,到这来,本次博客的教程就结束了,希望通过本次博客,大家能够实现摄像头的系列操作,包括打开摄像头、读取摄像头数据、关闭摄像头等等,同时,需要熟悉相关PyQt5中部分函数库的使用包括Label控件中图像的显示格式等。阅读本专栏,希望能够帮助到你!


以上就是本次博客的全部内容,遇到问题的小伙伴记得留言评论,学长看到会为大家进行解答的,这个学长不太冷!

由起点到夜晚,由山野到书房,一切问题的答案都很简单。我希望有个如你一般的人,贯彻未来,数遍生命的公路牌

陈一月的又一天编程岁月^ _ ^

  • 9
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈一月的编程岁月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值