基于人脸识别的课堂签到管理系统【学习五】

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


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

在线程中读取画面数据,由线程的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
在这里插入图片描述
会出现的显示效果(有提示:用户组创建成功)
在这里插入图片描述
用户创建成功后,可以在百度智能云管理中心看见创建成功的用户组
在这里插入图片描述

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

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


  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值