欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于人脸识别的课堂签到管理系统

程序员文章站 2023-02-02 14:34:24
实习第五天,彻底解决了昨天画面卡顿的问题,在此基础上学习了背景图的添加,如何关闭签到,实现人脸库管理创建添加用户组。网络请求人脸检测线程与窗口获取画面线程通信:通过信号与槽在窗口中设计一个自定义信号,且信号存在参数(画面数据)关联线程的一个函数(槽函数)当窗口获取一次画面,就自定义产生一次信号,调用槽函数,获取到画面在线程中读取画面数据,由线程的run函数进行网络请求,窗口的信号与线程的槽函数关联就只是数据的传递,而不是直接执行网络请求。线程网络请求后,获取到百度AI的检测,需要在窗口中进....

实习第五天,完善多线程彻底解决了昨天画面卡顿的问题,在此基础上学习了背景图的添加,如何关闭签到,实现人脸库管理创建添加用户组。


网络请求人脸检测线程与窗口获取画面线程通信:
通过信号与槽
在窗口中设计一个自定义信号,且信号存在参数(画面数据)
关联线程的一个函数(槽函数)
当窗口获取一次画面,就自定义产生一次信号,调用槽函数,获取到画面

在线程中读取画面数据,由线程的run函数进行网络请求,窗口的信号与线程的槽函数关联就只是数据的传递,而不是直接执行网络请求。线程网络请求后,获取到百度AI的检测,需要在窗口中进行显示,需要由线程把数据传递给窗口:信号槽

完成关闭当前签到

  • 打开人脸检测:
    启动摄像头----摄像头进行工作
    启动定时器----显示画面
    创建线程------网络请求获取人脸检测数据
    定时器2-------获取摄像头需要检测的画面

  • 关闭人脸检测:
    关闭定时器2(检测画面获取的定时器)
    线程结束(停止检测工作)

人脸库管理功能:
创建一个库
添加人脸
删除人脸
修改


今日份详细代码

main.py代码如下:

import sys
from PyQt5.QtWidgets import QApplication
from mywindow import mywindow
#程序的解释执行文件
if __name__ == '__main__':
    #创建应用程序对象
    app = QApplication(sys.argv)
    #创建窗口
    ui = mywindow()
    #显示窗口
    ui.show()
    #应用执行
    app.exec_()
    sys.exit(0)

mywindow.py代码如下:

import base64
import cv2
import requests
from PyQt5.QtGui import QPixmap

from mainwindow import Ui_MainWindow
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QMessageBox, QInputDialog
from PyQt5.QtCore import QTimer, QDateTime, QDate, QTime, pyqtSignal
from cameravideo import camera
from detect import detect_thread

'''
子类,继承Ui_MainWindow与QMainWindow
Ui_MainWindow:
    包含是界面的设计,窗口中的窗口部件
QMainWindow:
     包含是整个界面窗口,窗口的操作
mywindow:
    完整的窗口类
'''


class mywindow(Ui_MainWindow, QMainWindow):
    detect_data_signal = pyqtSignal(bytes)

    def __init__(self):
        super(mywindow, self).__init__()
        self.setupUi(self)  # 创建界面内容
        self.label.setScaledContents(True)
        #QPixmap("2.jpg")
        self.label.setPixmap(QPixmap("./3.jpg"))
        # 创建一个定时器对象
        self.datetime = QTimer(self)
        # 启动获取系统日期时间定时器,定时时间为500ms,500ms产生一次信号
        self.datetime.start(500)
        # 创建窗口就应该完成访问令牌的申请(获取)
        self.get_accesstoken()

        # 信号与槽的关联
        # self.actionopen:指定对象
        # triggered:信号
        # connect:关联(槽函数)
        # self.on_actionclose:关联的函数是什么
        self.actionopen.triggered.connect(self.on_actionopen)
        # 停止签到
        self.actionclose.triggered.connect(self.on_actionclose)

        # 添加用户组信号槽
        self.actionaddgroup.triggered.connect(self.add_group)

       # 关联时间日期的定时器信号与槽函数
        self.datetime.timeout.connect(self.date_time)
        # self.pushButton_3.clicked.connect(self.get_accesstoken)


    # self.pushButton.clicked.connect(self.get_face)
    # 创建线程完成检测

    # 函数功能获取日期与时间,添加到对应编辑器中
    def date_time(self):
        # 获取日期
        date = QDate.currentDate()
        # print(date)
        # self.dateEdit.setDate(date)
        self.label_2.setText(date.toString())
        # 获取时间
        time = QTime.currentTime()
        # print(time)
        # self.timeEdit.setTime(time)
        self.label_3.setText(time.toString())
        # 获取日期时间
        # datetime = QDateTime.currentDateTime()
        # print(datetime)

    ''' 
       信号槽功能:
       当某个组件设计了信号槽功能时,当信号产生,会主动调用槽函数,去完成对应的一个功能
       信号:当以某种特定的操作,操作这个组件时,就会主动产生对应操作的信号
    '''

    def on_actionclose(self):
        #关闭获取检测数据
        self.facedetecttime.stop()
        #self.facedetecttime.timeout.disconnect(self.get_cameradata)
        #self.detect_data_signal.disconnect(self.detectThread.get_base64)
        #self.detectThread.transmit_data.disconnect(self.get_detectdata)
        #关闭检测线程
       # print(self.detectThread.isRunning())
        self.detectThread.OK = False
        self.detectThread.quit()
        self.detectThread.wait()
        #print(self.detectThread.isRunning())
        #self.plainTextEdit_2.clear()
        # print("on_actionclose")
        # 关闭定时器,不再去获取摄像头数据
        self.timeshow.stop()
        self.timeshow.timeout.disconnect(self.show_cameradata)
        # 关闭摄像头
        self.cameravideo.close_camera()
        #设置为初始状态
        self.label.setPixmap(QPixmap("./3.jpg"))
        #设置为初始状态
        #self.label.setText("摄像头画面显示")

    def on_actionopen(self):
        # print("on_actionopen")
        # 启动摄像头
        self.cameravideo = camera()
        # 启动定时器,进行定时,每隔多长时间进行一次获取摄像头数据并进行显示
        self.timeshow = QTimer(self)
        self.timeshow.start(10)
        # 10ms的定时器启动,每到10ms就会产生一个信号timeout
        self.timeshow.timeout.connect(self.show_cameradata)
        #timeshow定时器用作显示画面
        # 创建检测线程
        self.create_thread()

        # 开启检测启动时,创建定时器,500ms,用作获取要检测的画面
        self.facedetecttime = QTimer(self)
        self.facedetecttime.start(1000)
        self.facedetecttime.timeout.connect(self.get_cameradata)
        #关联一个窗口中的信号与创建的线程中的函数
        self.detect_data_signal.connect(self.detectThread.get_base64)
        #facedetecttime设置检测画面获取
        self.detectThread.transmit_data.connect(self.get_detectdata)

    #获取槽函数, 获取检测数据
    def get_detectdata(self,data):
        if data['error_msg'] == 'SUCCESS':
            # 在data字典中,键为'result'对应的值才是返回的检测结果
            # data['result']就是检测结果
            # 人脸数目
            self.plainTextEdit_2.clear()
            face_num = data['result']['face_num']
            if face_num == 0:
                self.plainTextEdit_2.appendPlainText("当前没有人脸出现")
                return
            else:
                self.plainTextEdit_2.appendPlainText("存在及人脸出现")
            # 人脸信息: data['result']['face_list']是列表,每个数据就是一个人脸
            # 每个人脸信息: data['result']['face_list'][0~i]人脸信息字典
            for i in range(face_num):
                # 通过for循环,分别取出列表的每一个数据
                # data['result']['face_list'][i]就是每一个人脸信息的字典
                age = data['result']['face_list'][i]['age']
                beauty = data['result']['face_list'][i]['beauty']
                gender = data['result']['face_list'][i]['gender']['type']
                expression = data['result']['face_list'][i]['expression']['type']
                face_shape = data['result']['face_list'][i]['face_shape']['type']
                glasses = data['result']['face_list'][i]['glasses']['type']
                mask = data['result']['face_list'][i]['mask']['type']
                emotion = data['result']['face_list'][i]['emotion']['type']
                # 往窗口中添加文本,参数就是需要的文本信息
                self.plainTextEdit_2.appendPlainText(str(i + 1) + "学生人脸信息")
                self.plainTextEdit_2.appendPlainText("年龄是:" + str(age))
                self.plainTextEdit_2.appendPlainText("颜值分数是:" + str(beauty))
                self.plainTextEdit_2.appendPlainText("性别是:" + str(gender))
                self.plainTextEdit_2.appendPlainText("表情是:" + str(expression))
                self.plainTextEdit_2.appendPlainText("脸型是:" + str(face_shape))
                self.plainTextEdit_2.appendPlainText("是否佩戴眼镜:" + str(glasses))
                self.plainTextEdit_2.appendPlainText("情绪是:" + str(emotion))
                if mask == 0:
                    mask = "否"
                else:
                    mask = "是"
                self.plainTextEdit_2.appendPlainText("是否佩戴口罩:" + str(mask))

    #创建线程完成检测
    def create_thread(self):
        self.detectThread = detect_thread(self.access_token)
        self.detectThread.start()

    def get_cameradata(self):
        # 摄像头获取画面
        camera_data = self.cameravideo.read_camera()
        # 转换为把摄像头画面转换成图片,然后设置base64编码格式数据
        _, enc = cv2.imencode('.jpg', camera_data)
        base64_image = base64.b64encode(enc.tobytes())
        # 产生信号,传递数据
        self.detect_data_signal.emit(bytes(base64_image))

    # 是作为摄像头,获取数据,显示画面功能
    # 只要能够不断调用这个函数,不断的从摄像头获取数据进行显示
    # 可以通过信号,信号关联当前函数,只要信号产生,函数就会被调用
    # 信号需要不断产生,可以通过定时器,定时时间到达就会产生信号

    def show_cameradata(self):
        # self.cameravideo = camera()
        # 获取摄像头数据,转换数据
        pic = self.cameravideo.camera_to_pic()
        # 显示数据,显示画面
        self.label.setPixmap(pic)

    # 获取进行网络请求的访问令牌
    def get_accesstoken(self):
        # print("get")
        # client_id 为官网获取的AK, client_secret 为官网获取的SK
        # host是字符串,存储授权的服务地址---获取accesstoken的地址
        host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=exGfN5ZtUhTgZGHZVV8v821I&client_secret=iXyHXkgxqCwzDigifG5Bq9FQY4nCPDaS'
        # 发送网络请求
        response = requests.get(host)
        if response:
            # print(response.json())
            data = response.json()
            self.access_token = data.get('access_token')
            # self.access_token = response['access_token']
            # print(self.access_token)

    def add_group(self):
        #打开对话框进行输入用户组
        group,ret = QInputDialog.getText(self,"添加用户组","请输入用户组(由数字、字母、下划线组成)")
        # print(group)
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/add"

        params = {
            "group_id": group
        }
        access_token = self.access_token
        request_url = request_url + "?access_token=" + access_token
        headers = {'content-type': 'application/json'}
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            message = response.json()
            if message['error_msg'] == 'SUCCESS':
                QMessageBox.about(self,"用户组创建结果","用户组创建成功")
            else:
                QMessageBox.about(self, "用户组创建结果", "用户组创建失败\n" + message['error_msg'])
#------------------------------------------------------------------------#

    # 进行人脸检测功能
    def get_face(self):
        '''
        #这是打开对话框获取
        #获取一张图片或一帧画面
        #通过对话框的形式获取一个图片的路径
        path, ret = QFileDialog.getOpenFileName(self, "open picture", ".", "图片格式(*.jpg)")
        print(path)
        #把图片转换成base64编码
        fp = open(path, 'rb')
        base64_image = base64.b64encode(fp.read())
        '''
        # 摄像头获取画面
        camera_data = self.cameravideo.read_camera()
        # 转换为把摄像头画面转换成图片,然后设置base64编码格式数据
        _, enc = cv2.imencode('.jpg', camera_data)
        base64_image = base64.b64encode(enc.tobytes())
        # 发送请求的地址
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"
        # 请求参数,是一个字典,存储了百度AI要识别的图片信息,要识别的属性内容
        params = {"image": base64_image,  # 图片信息字符串
                  "image_type": "BASE64",  # 图片信息的格式
                  "face_field": "gender,age,beauty,expression,face_shape,glasses,mask,emotion",
                  # 请求识别人脸的属性,在各个属性字符串用逗号隔开
                  "max_face_num": 10
                  }
        # 访问令牌
        access_token = self.access_token
        # 把请求地址和访问令牌组成可用的网络请求地址
        request_url = request_url + "?access_token=" + access_token
        # 设置请求格式体
        headers = {'content-type': 'application/json'}
        # 发送网络post请求,请求百度API进行人脸检测,返回检测结果
        # 发送网络请求,会等待一定时间,所以会导致程序在这里阻塞执行
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            # print(response.json())
            data = response.json()
            if data['error_msg'] == 'SUCCESS':
                # 在data字典中,键为'result'对应的值才是返回的检测结果
                # data['result']就是检测结果
                # 人脸数目
                self.plainTextEdit_2.clear()
                face_num = data['result']['face_num']
                if face_num == 0:
                    self.plainTextEdit_2.appendPlainText("当前没有人脸出现")
                    return
                else:
                    self.plainTextEdit_2.appendPlainText("存在及人脸出现")
                # 人脸信息: data['result']['face_list']是列表,每个数据就是一个人脸
                # 每个人脸信息: data['result']['face_list'][0~i]人脸信息字典
                for i in range(face_num):
                    # 通过for循环,分别取出列表的每一个数据
                    # data['result']['face_list'][i]就是每一个人脸信息的字典
                    age = data['result']['face_list'][i]['age']
                    beauty = data['result']['face_list'][i]['beauty']
                    gender = data['result']['face_list'][i]['gender']['type']
                    expression = data['result']['face_list'][i]['expression']['type']
                    face_shape = data['result']['face_list'][i]['face_shape']['type']
                    glasses = data['result']['face_list'][i]['glasses']['type']
                    mask = data['result']['face_list'][i]['mask']['type']
                    emotion = data['result']['face_list'][i]['emotion']['type']
                    # 往窗口中添加文本,参数就是需要的文本信息
                    self.plainTextEdit_2.appendPlainText(str(i + 1) + "学生人脸信息")
                    self.plainTextEdit_2.appendPlainText("年龄是:" + str(age))
                    self.plainTextEdit_2.appendPlainText("颜值分数是:" + str(beauty))
                    self.plainTextEdit_2.appendPlainText("性别是:" + str(gender))
                    self.plainTextEdit_2.appendPlainText("表情是:" + str(expression))
                    self.plainTextEdit_2.appendPlainText("脸型是:" + str(face_shape))
                    self.plainTextEdit_2.appendPlainText("是否佩戴眼镜:" + str(glasses))
                    self.plainTextEdit_2.appendPlainText("情绪是:" + str(emotion))
                    if mask == 0:
                        mask = "否"
                    else:
                        mask = "是"
                    self.plainTextEdit_2.appendPlainText("是否佩戴口罩:" + str(mask))
                    # print(age)
                    # print(beauty)
                    # print(gender)
                    # print(expression)
                    # print(face_shape)
                    # print(glasses)
                    # print(emotion)
                    # print(mask)
                    # print(data['result'])   # 在data字典中,键为‘result’对应的值才是返回的检测结果

cameravideo.py代码如下:

import cv2
import numpy as np
from PyQt5.QtGui import QPixmap, QImage

'''
摄像头操作:创建类对象完成摄像头操作,使用可以把打开摄像头与创建类对象操作合并
     __init__函数完成摄像头的配置打开
'''


class camera():
    # 摄像头的配置打开与创建类对象合并
    def __init__(self):
        # VideoCapture类对视频或调用摄像头进行读取操作
        # 参数 filename;device
        # 0表示默认的摄像头,进行打开
        #创建摄像头对象,打开摄像头
        #self.capture表示打开摄像头的对象
        self.capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)
        if self.capture.isOpened():
            print("isopenned")
        #定义一个多维数组,用来存储获取的
        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
        # 调用cvtColor完成后才是RGB格式的画面数据
        self.currentframe = cv2.cvtColor(pic, cv2.COLOR_BGR2RGB)
        # 设置宽高
        #self.currentframe = cv2.cvtColor(self.currentframe, (640, 480))

        # 转换为界面能够显示的格式
        # 获取画面的宽度与高度
        height, width = self.currentframe.shape[:2]
        # 先转换为QImage类型图片(画面),创建QImage类对象,使用摄像头画面数据
        # QImage(data,width,height,format)创建:数据,宽度,高度,格式
        qimg = QImage(self.currentframe, width, height, QImage.Format_RGB888)
        qpixmap = QPixmap.fromImage(qimg)
        return qpixmap

    # 摄像头关闭
    def close_camera(self):
        self.capture.release()

detect.py代码如下:

from PyQt5.QtCore import QThread, QTimer, pyqtSignal
import requests
import cv2
import base64


# Thread就是PyQt5提供的线程类
# 由于是一个已经完成了的类,功能已经写好,线程的功能需要我们自己完成
# 需要自己完成需要的线程类,创建一个新的线程类(功能可以自己定义),继承QThread,新写的类就是线程类,具备线程功能

# 线程进行执行只会执行线程类中的run函数,如果有新的功能需要实现,重写一个run函数
class detect_thread(QThread):
    transmit_data = pyqtSignal(dict)
    #设计布尔值,为了退出while循环
    OK = True
    def __init__(self, token):
        super(detect_thread, self).__init__()
        self.access_token = token
        self.condition = False

    # run函数执行结束,代表线程结束
    def run(self):
        print("run")
        '''
        self.time = QTimer()
        self.time.start(1000)
        self.time.timeout.connect(self.detect_face)
        '''
        while self.OK:
            if self.condition:
                self.detect_face(self.base64_image)
                self.condition = False
        #print("while finish")

    def get_base64(self, base64_image):
        # 当窗口调用产生信号,调用这个槽函数,就把传递的数据,存放在线程变量中
        self.base64_image = base64_image
        self.condition = True

    # 进行人脸检测
    def detect_face(self, base64_image):
        '''
        这是打开对话框获取
        #获取一张图片或一帧画面
        #通过对话框的形式获取一个图片的路径
        path, ret = QFileDialog.getOpenFileName(self, "open picture", ".", "图片格式(*.jpg)")
        print(path)
        #把图片转换成base64编码
        fp = open(path, 'rb')
        base64_image = base64.b64encode(fp.read())
        '''
        # 发送请求的地址
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"
        # 请求参数,是一个字典,存储了百度AI要识别的图片信息,要识别的属性内容
        params = {"image": base64_image,  # 图片信息字符串
                  "image_type": "BASE64",  # 图片信息的格式
                  "face_field": "gender,age,beauty,expression,face_shape,glasses,mask,emotion",
                  # 请求识别人脸的属性,在各个属性字符串用逗号隔开
                  "max_face_num": 10
                  }
        # 访问令牌
        access_token = self.access_token
        # 把请求地址和访问令牌组成可用的网络请求地址
        request_url = request_url + "?access_token=" + access_token
        # 设置请求格式体
        headers = {'content-type': 'application/json'}
        # 发送网络post请求,请求百度API进行人脸检测,返回检测结果
        # 发送网络请求,会等待一定时间,所以会导致程序在这里阻塞执行
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            # print(response.json())
            data = response.json()
            self.transmit_data.emit(dict(data))
            #print(data)

mainwindow.py代码如下

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

# Form implementation generated from reading ui file 'mainwindow.ui'
#
# Created by: PyQt5 UI code generator 5.15.0
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(960, 759)
        MainWindow.setMinimumSize(QtCore.QSize(550, 480))
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setMinimumSize(QtCore.QSize(450, 400))
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        self.verticalLayout_4 = QtWidgets.QVBoxLayout()
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem)
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setObjectName("label_3")
        self.horizontalLayout_2.addWidget(self.label_3)
        spacerItem1 = QtWidgets.QSpacerItem(178, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem1)
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_2.addWidget(self.label_2)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem2)
        self.verticalLayout_4.addLayout(self.horizontalLayout_2)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setMinimumSize(QtCore.QSize(400, 300))
        self.label.setText("")
        self.label.setObjectName("label")
        self.horizontalLayout.addWidget(self.label)
        self.verticalLayout_3 = QtWidgets.QVBoxLayout()
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setObjectName("label_4")
        self.verticalLayout_3.addWidget(self.label_4)
        self.plainTextEdit = QtWidgets.QPlainTextEdit(self.centralwidget)
        self.plainTextEdit.setReadOnly(True)
        self.plainTextEdit.setObjectName("plainTextEdit")
        self.verticalLayout_3.addWidget(self.plainTextEdit)
        self.label_5 = QtWidgets.QLabel(self.centralwidget)
        self.label_5.setObjectName("label_5")
        self.verticalLayout_3.addWidget(self.label_5)
        self.plainTextEdit_2 = QtWidgets.QPlainTextEdit(self.centralwidget)
        self.plainTextEdit_2.setReadOnly(True)
        self.plainTextEdit_2.setObjectName("plainTextEdit_2")
        self.verticalLayout_3.addWidget(self.plainTextEdit_2)
        self.horizontalLayout.addLayout(self.verticalLayout_3)
        self.horizontalLayout.setStretch(0, 4)
        self.horizontalLayout.setStretch(1, 2)
        self.verticalLayout_4.addLayout(self.horizontalLayout)
        self.gridLayout.addLayout(self.verticalLayout_4, 1, 0, 1, 1)
        self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 960, 26))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        self.menu_2 = QtWidgets.QMenu(self.menubar)
        self.menu_2.setObjectName("menu_2")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.actionopen = QtWidgets.QAction(MainWindow)
        self.actionopen.setObjectName("actionopen")
        self.actionclose = QtWidgets.QAction(MainWindow)
        self.actionclose.setObjectName("actionclose")
        self.actionaddgroup = QtWidgets.QAction(MainWindow)
        self.actionaddgroup.setObjectName("actionaddgroup")
        self.menu.addAction(self.actionopen)
        self.menu.addAction(self.actionclose)
        self.menu_2.addAction(self.actionaddgroup)
        self.menubar.addAction(self.menu.menuAction())
        self.menubar.addAction(self.menu_2.menuAction())

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

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label_3.setText(_translate("MainWindow", "时间"))
        self.label_2.setText(_translate("MainWindow", "日期"))
        self.label_4.setText(_translate("MainWindow", "学生签到情况:"))
        self.label_5.setText(_translate("MainWindow", "学生人脸信息:"))
        self.menu.setTitle(_translate("MainWindow", "签到"))
        self.menu_2.setTitle(_translate("MainWindow", "人脸库管理"))
        self.actionopen.setText(_translate("MainWindow", "启动签到"))
        self.actionclose.setText(_translate("MainWindow", "停止签到"))
        self.actionaddgroup.setText(_translate("MainWindow", "添加用户组(班级)"))

今天的基本实现情况
基于人脸识别的课堂签到管理系统运行main,显示的效果
基于人脸识别的课堂签到管理系统点击签到,选择启动签到,显示的效果
基于人脸识别的课堂签到管理系统点击签到,选择停止签到,显示的效果(可以发现,退回到之前界面,但是有一个问题,学生人脸信息窗口的数据没有清空,这个功能之后和学生签到情况窗口一起实现)
基于人脸识别的课堂签到管理系统点击人脸库管理,选择添加用户组(班级)
基于人脸识别的课堂签到管理系统会出现的显示效果(这里添加用户组)
基于人脸识别的课堂签到管理系统
例如我命名为group1,再点击OK
基于人脸识别的课堂签到管理系统
会出现的显示效果(有提示:用户组创建成功)
基于人脸识别的课堂签到管理系统
用户创建成功后,可以在百度智能云管理中心看见创建成功的用户组
基于人脸识别的课堂签到管理系统

今天上午的时候,我们实现人脸检测并打印的时候,不知道为什么,明明我的摄像头采集人脸的时候,只检测了一个人脸,却打印识别到两个人,窗口不断变化,我以为代码出问题了,后来把电脑带到只有我一个人的房间就显示正常了,当时我觉得有点奇怪。姚老师说是百度检测的时候的一些问题。

作为物联网小白,各方面能力有限,今天是我们学习人脸识别的课堂签到管理系统的第五天,肯定有很多不足,会慢慢改正。


本文地址:https://blog.csdn.net/qq_44830040/article/details/107448880