基于人脸识别的课堂签到管理系统
实习第五天,完善多线程彻底解决了昨天画面卡顿的问题,在此基础上学习了背景图的添加,如何关闭签到,实现人脸库管理创建添加用户组。
网络请求人脸检测线程与窗口获取画面线程通信:
通过信号与槽
在窗口中设计一个自定义信号,且信号存在参数(画面数据)
关联线程的一个函数(槽函数)
当窗口获取一次画面,就自定义产生一次信号,调用槽函数,获取到画面
在线程中读取画面数据,由线程的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