百度AI人脸识别与检测七:学生人脸识别打卡签到系统之学生人脸信息的添加

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

前文参考:

百度AI人脸识别与检测一:学生人脸识别签到系统简介及百度AI开放平台账号注册和人脸实例应用创建
百度AI人脸识别与检测二:学生人脸识别打卡签到系统主界面功能需求和设计以及通过Python实现界面运行
百度AI人脸识别与检测三:学生人脸识别打卡签到系统通过OpenCV实现电脑摄像头数据在Label控件上的实时显示
百度AI人脸识别与检测四:学生人脸识别打卡签到系统之百度AI人脸检测及相应程序异常处理
百度AI人脸识别与检测五:学生人脸识别打卡签到系统之百度AI人脸识别
百度AI人脸识别与检测六:学生人脸识别打卡签到系统之班级的增删查

上次博客林君学长带大家了解了如何通过百度API对应的官方文档访问细则,进行学生人脸识别打卡签到系统的中班级的增删查的相应功能,相信各位小伙伴通过一天时间的消化,在对百度AI开放平台上面API文档访问和返回细则有了一定的了解,同时也明白了如何将百度AI上面的人脸识别模块移植到我们的人脸识别打卡签到系统上面。
上一章的内容,我们完成了项目中班级的一系列操作,包括班级的增删查;而本章的学习内容便要在班级中通过我们的软件系统实现班级中学生人脸信息的增加,由于学生的增加涉及到新页面的建立,因此将学生增加作为单独的一章进行讲解,而将学生人脸信息的删除和查询放在该系列的第八章中进行讲解,小伙伴们记得及时翻阅啦!



一、学生人脸信息需求分析

1、人脸信息录入需求分析

在进行学生人脸信息的时候,首先应该进行需求和功能分析,班级中的学生应该具有哪些特征?如何将这些特征展示出来。对于学生人脸信息的录入,首先应该包括学生人本的照片、学生的姓名、以及学生处于哪一个班级,因此,在上一章我们说到的通过MessageBOX信息框进行展示肯定是不行的,因为涉及到摄像头对学生人脸的录入,同时应该有输入框输入学生的姓名,照片对应的编码(也就是ID,学号),已经选择框从班级列表中选择班级。
(1)、需求分析

  • 视频框:在新的页面设计一个视频显示框,通过摄像头对学生图像进行人脸捕捉
  • 学号输入框:输入学生学号
  • 姓名输入框:输入学生姓名
  • 班级选择框:从班级列表中选择学生对应的班级

(2)、功能分析

通过新的页面,完成学生信息的添加;在主界面中通过绑定菜单中“增加学生”按钮事件到新添加的页面然后进行一系列的操作,便完成本章的内容。
提示:应该需要考虑到程序的健壮性!

2、人脸信息页面创建

(1)、在Pycharm终端输入pyqt5designer.exe打开PyQT的窗口设计软件。
在这里插入图片描述
不同的环境打开PyQt软件的界面方式不同,有的可能需要在安装包的路径中寻找到下载的exe文件进行打开,这里不做具体说明!可以在Pycharm中添加pyqt5designer拓展工具,然后也可以进行页面打开!
(2)、选择Dialog中的任意一个都可以,但不能选择主界面,因为软件项目中已经具有主界面了!
在这里插入图片描述
(3)通过自己对需求的构思,完成自己学生人脸信息添加页面的布局构思,林君学长简单的布局如下图所示:
在这里插入图片描述
(4)、完成后,将UI文件保存在项目中,命名为add_student.ui
在这里插入图片描述
(5)、将学生添加的UI文件转换为py文件,命名如下:

pyuic5 add_student.ui -o add_student.py

在这里插入图片描述
在这里插入图片描述
(6)、将转换的界面py文件进行实例化
新建名称为add_student_window.py的文件,并写入以下实例化布局代码:

from add_student import Ui_Dialog
from PyQt5.QtWidgets import QDialog

class add_student_window(Ui_Dialog,QDialog):
    def __init__(self,list,parent=None):
        super(add_student_window,self).__init__(parent)
        self.setupUi(self)

3、完成主界面与人脸信息录入界面的跳转

(1)、在function_window.py文件头部导入实例化的界面窗口

from add_student_window import add_student_window

在这里插入图片描述

(2)、在function_window.py文件末尾,添加界面跳转方法,Python代码如下所示:

   #增加学生信息
    def add_student(self):
        '''
        人脸注册
        '''
        list=self.get_class()#获取班级,将班级信息传递到我们新建的界面之中
        # 创建一个窗口,进行用户信息录入
        window = add_student_window(list['result']['group_id_list'],self)#将获取到的班级传递到新的界面,后续有用
        #新创建窗口,通过exec()函数一直在执行,窗口不进行关闭
        window_status=window.exec_()
        #判断
        if window_status !=1:
            return

(3)、为菜单栏中的“增加学生”按钮绑定事件
function_window.py文件中,添加如下语句

self.actionaddStu.triggered.connect(self.add_student)#增加学生人脸信息事件绑定

添加位置如下:
在这里插入图片描述
(4)、运行软件程序,选择学生信息管理菜单中的增加学生,进行界面跳转。正确跳转如下所示:
在这里插入图片描述
界面跳转实现了,下面就通过对API文档的阅读,完成我们的基本功能吧!


二、百度AI平台人脸注册API详阅

1、人脸注册API查看地址

百度AI开放平台人脸注册API文档查阅地址…

2、人脸注册访问规则详阅

(1)、访问规则代码展示


# encoding:utf-8

import requests

'''
人脸注册
'''

request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add"

params = "{"image":"027d8308a2ec665acb1bdf63e513bcb9","image_type":"FACE_TOKEN","group_id":"group_repeat","user_id":"user1","user_info":"abc","quality_control":"LOW","liveness_control":"NORMAL"}"
access_token = '[调用鉴权接口获取的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:
    print (response.json())

(2)访问参数
以上的参数有些参数并不是必须要有的,下面给出一定要有的参数,其他参数可以参考API文档中的内容

  • image:捕捉到的学生人脸图像
  • image_type:图像类型,本系列采用的类型为BASE64
  • group_id:用户组id,也就是班级名称
  • user_id:用户id,也就是学生学号
  • user_info:用户信息,也就是学生姓名以及其他相关信息,项目中主要值学生姓名

其他参考如下:
在这里插入图片描述

3、人脸注册返回规则详阅

(1)返回信息实例


{
  "face_token": "2fa64a88a9d5118916f9a303782a97d3",
  "location": {
      "left": 117,
      "top": 131,
      "width": 172,
      "height": 170,
      "rotation": 4
  }
}

(2)、以上参数说明
在这里插入图片描述
判断是否创建成功主要通过返回的error_code进行识别定义,error_code=0,则表示创建成功!


三、签到系统中学生人脸信息录入实现

1、完成学生人脸录入界面的相应功能

(1)、完成学生人脸的截取,由于摄像头捕捉技术在上面几章已经讲过,因此,在这里直接给出代码。在add_student_window.py文件中将内容替换为如下代码:

import base64

import cv2
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QPixmap

from add_student import Ui_Dialog
from PyQt5.QtWidgets import QDialog
from cameraVideo import camera

class add_student_window(Ui_Dialog,QDialog):
    def __init__(self,list,parent=None):
        super(add_student_window,self).__init__(parent)
        self.setupUi(self)
        self.list=list#收取主界面传递过来的班级列表
        self.show_class()#将班级列表显示在下拉框中
        self.label.setScaledContents(True)#使得图像自适应
        self.label.setPixmap(QPixmap("./image/my.jpg"))
        self.cameravideo = camera()#导入相机函数
        self.time = QTimer()#启用定时器,实时显示人脸视频
        self.time.timeout.connect(self.show_camera)#计时器绑定画面显示函数
        self.time.start(50)#每隔50ms获取一次画面
        self.pushButton_6.clicked.connect(self.get_cameradata)#获取画面按钮事件绑定
    def show_camera(self):
        # 获取摄像头数据
        pic = self.cameravideo.camera_to_pic()#获取一帧图像
        # 显示数据、显示画面
        self.label.setPixmap(pic)

    def get_cameradata(self):
        camera_data1 = self.cameravideo.read_camera()
        # 把摄像头画面转化为一张图片,然后设置编码为base64编码
        _, enc = cv2.imencode('.jpg', camera_data1)
        base64_image = base64.b64encode(enc.tobytes())
        self.base64_image=base64_image#全局变量,用于保存画面base64格式画面
        self.time.stop()#计时器停止
        self.cameravideo.colse_camera()#摄像机关闭
    def show_class(self):
        self.comboBox.clear()
        for i in self.list:
            self.comboBox.addItem(i)#将获取到的班级列表显示在下拉框中

(2)、点击选择该画面,相机捕捉结果如下:
在这里插入图片描述
(2)、定义获取学生信息输入框的功能方法
add_student_window.py文件尾部添加名为get_student_data的方法,获取到输入框的信息:

   #获取学生基本信息
    def get_student_data(self):
        self.class_id=self.comboBox.currentText()#获取班级
        self.student_id=self.lineEdit.text()#获取学号
        self.student_name=self.lineEdit_2.text()#获取姓名
        self.accept()#点击确认后关闭对话框
    #关闭窗口
    def close_window(self):
        #关闭对话框
        self.close()

(3)、绑定确定和取消按钮事件

 self.pushButton_2.clicked.connect(self.get_student_data)#点击确定,获取对应信息
 self.pushButton_3.clicked.connect(self.close_window)#点击关闭,窗口关闭

位置如下所示:
在这里插入图片描述

2、构建添加学生人脸信息方法

(1)、在function_window.py文件中,找到上面创建的add_student方法,将此方法进行修改,完成学生人脸信息方法添加,具体代码如下所示:

#增加学生信息
    def add_student(self):
        '''
        人脸注册
        '''
        list=self.get_class()#获取班级,将班级信息传递到我们新建的界面之中
        # 创建一个窗口,进行用户信息录入
        window = add_student_window(list['result']['group_id_list'],self)#将获取到的班级传递到新的界面,后续有用
        #新创建窗口,通过exec()函数一直在执行,窗口不进行关闭
        window_status=window.exec_()
        #判断
        if window_status !=1:
            return
        base64_image = window.base64_image
        # 参数请求中,需要获取人脸编码,添加的组的id,添加的用户,新用户id信息
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add"

        params = {
            "image": base64_image,  # 人脸图片
            "image_type": "BASE64",  # 图片编码格式
            "group_id": window.class_id,  # 班级名称
            "user_id": window.student_id,  # 学生学号
            "user_info": window.student_name# 学生姓名
        }
        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:
            data = response.json()
            if data['error_code'] == 0:
                QMessageBox.about(self, "增加结果", "学生增加成功!")
            else:
                QMessageBox.about(self, "增加结果", "学生增加失败!")

3、实例演示

(1)、运行程序,选择学生信息管理,点击增加学生,最后选择摄像头捕捉画面,输入学号、姓名、班级,点击确定,完成学生人脸及信息的录入,如下所示:
在这里插入图片描述
(2)、添加成功如下所示:
在这里插入图片描述
(3)、百度AI开放平台上面添加结果:
在这里插入图片描述
可以看到,添加学生信息成功!
(4)、最后运行软件签到功能看一下签到结果:
在这里插入图片描述
成功检测到刚刚添加的成员,这里有一点点问题哈,签到中姓名一栏出现成了学号,这个后面进行解决,今天就到这里啦,记得点赞、关注、评论哇!

4、修改后代码

(1)、function_window.py文件修改后代码如下:

import base64

import cv2
import requests
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QMainWindow, QMessageBox, QInputDialog
from cameraVideo import camera
from mainWindow import Ui_MainWindow
from detect import detect_thread
from add_student_window import add_student_window
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)#关闭签到事件绑定
        self.actionaddclass.triggered.connect(self.add_class)#添加班级按钮事件绑定
        self.actionfindclass.triggered.connect(self.display_class)#查询班级按钮事件绑定
        self.actiondelclass.triggered.connect(self.delete_calss)#删除班级按钮事件绑定
        self.actionaddStu.triggered.connect(self.add_student)#增加学生人脸信息事件绑定
        self.access_token=self.get_accessToken()#获取Access_token访问令牌,并复制为全局变量
        self.start_state=True
    '''
        打开签到
    '''
    def open_Sign(self):
        if self.start_state==True:
            # 启动摄像头
            self.cameravideo = camera()
            # 启动定时器进行定时,每隔多长时间进行一次获取摄像头数据进行显示
            self.timeshow = QTimer(self)
            self.timeshow.start(10)
            # 每隔10毫秒产生一个信号timeout
            self.timeshow.timeout.connect(self.show_cameradata)
            self.detect = detect_thread(self.access_token)  # 创建线程
            self.detect.start()  # 启动线程
            # 签到500毫秒获取一次,用来获取检测的画面
            self.faceshow = QTimer(self)
            self.faceshow.start(500)
            self.faceshow.timeout.connect(self.get_cameradata)
            self.detect.transmit_data.connect(self.get_data)
            self.detect.transmit_data1.connect(self.get_seach_data)
            self.start_state=False
        else:
            QMessageBox.about(self, "提示", "正在检测,请先关闭!")

    '''
        关闭签到
    '''
    def close_Sign(self):
        if self.start_state==False:
            self.faceshow.stop()  # 计时器停止
            self.detect.ok = False  # 停止run函数运行
            self.detect.quit()  # 关闭线程
            # 关闭定时器,不再获取摄像头的数据
            self.timeshow.stop()
            self.timeshow.timeout.disconnect(self.show_cameradata)
            # 关闭摄像头
            self.cameravideo.colse_camera()
            self.start_state=True
            # 判断定时器是否关闭,关闭,则显示为自己设定的图像
            if self.timeshow.isActive() == False:
                self.label.setPixmap(QPixmap("image/1.jpg"))
                self.plainTextEdit_2.clear()
            else:
                QMessageBox.about(self, "警告", "关闭失败,存在部分没有关闭成功!")
        else:
            QMessageBox.about(self, "提示", "请先开始检测!")
    #获取人脸检测数据并显示到文本框中
    def get_data(self,data):
        if data['error_code']!=0:
            self.plainTextEdit_2.setPlainText(data['error_msg'])
            return
        elif data['error_msg'] == 'SUCCESS':
            self.plainTextEdit_2.clear()
            # 在data字典中键为result对应的值才是返回的检测结果
            face_num = data['result']['face_num']
            # print(face_num)
            if face_num == 0:
                self.plainTextEdit_2.setPlainText("当前没有人或人脸出现!")
                return
            else:
                self.plainTextEdit_2.clear()
                self.plainTextEdit_2.appendPlainText("检测到人脸!")
                self.plainTextEdit_2.appendPlainText("——————————————")
            # 人脸信息获取['result']['face_list']是列表,每个数据就是一个人脸信息,需要取出每个列表信息(0-i)
            for i in range(face_num):
                age = data['result']['face_list'][i]['age']  # 年龄
                # print(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']  # 是否戴眼镜
                emotion = data['result']['face_list'][i]['emotion']['type']  # 情绪
                mask = data['result']['face_list'][i]['mask']['type']  # 是否戴口罩
                # 往窗口中添加文本,参数就是需要的文本信息
                # print(age,gender,expression,beauty,face_shape,emotion,glasses,mask)
                self.plainTextEdit_2.appendPlainText("第" + str(i + 1) + "个学生人脸信息:")
                self.plainTextEdit_2.appendPlainText("——————————————")
                self.plainTextEdit_2.appendPlainText("年龄:" + str(age))
                if gender == 'male':
                    gender = "男"
                else:
                    gender = "女"
                self.plainTextEdit_2.appendPlainText("性别:" + str(gender))
                self.plainTextEdit_2.appendPlainText("表情:" + str(expression))
                self.plainTextEdit_2.appendPlainText("颜值分数:" + str(beauty))
                self.plainTextEdit_2.appendPlainText("脸型:" + str(face_shape))
                self.plainTextEdit_2.appendPlainText("情绪:" + str(emotion))
                if glasses == "none":
                    glasses="否"
                elif glasses == "common":
                    glasses="是:普通眼镜"
                else:
                    glasses="是:太阳镜"
                self.plainTextEdit_2.appendPlainText("是否佩戴眼镜:" + str(glasses))
                if mask == 0:
                    mask = "否"
                else:
                    mask = "是"
                self.plainTextEdit_2.appendPlainText("是否佩戴口罩:" + str(mask))
                self.plainTextEdit_2.appendPlainText("——————————————")
        else:
            print("人脸获取失败!")

    '''
        获取图像,并转换为base64格式
    '''
    def get_cameradata(self):
        camera_data1 = self.cameravideo.read_camera()
        # 把摄像头画面转化为一张图片,然后设置编码为base64编码
        _, enc = cv2.imencode('.jpg', camera_data1)
        base64_image = base64.b64encode(enc.tobytes())
        #产生信号,传递数据
        self.detect.get_imgdata(base64_image)
    '''
        摄像头数据显示
    '''
    def show_cameradata(self):
        #获取摄像头数据
        pic=self.cameravideo.camera_to_pic()
        #在lebel框中显示数据、显示画面
        self.label.setPixmap(pic)

    '''
        获取Access_token访问令牌
    '''
    def get_accessToken(self):

        # client_id 为官网获取的AK, client_secret 为官网获取的SK
        host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=TKGXdKC7WPWeADGHmFBN8xAr&client_secret=lsr1tAuxv3tRGmOgZTGgNyri667dfKGg'
        # 进行网络请求,使用get函数
        response = requests.get(host)
        if response:
            data = response.json()
            self.access_token = data['access_token']
            return self.access_token
        else:
            QMessageBox(self,"提示","请检查网络连接!")


    def get_seach_data(self,data):
        self.plainTextEdit.setPlainText(data)


    #添加班级
    def add_class(self):
        # 打开输入框,进行输入用户组
        group, ret = QInputDialog.getText(self, "添加班级", "请输入班级名称(由数字、字母、下划线组成)")
        if group == "":
            print("取消添加班级")
        else:
            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:
                print(response.json())
                message = response.json()
                if message['error_code'] == 0:#根据规则,返回0则为班级添加成功
                    QMessageBox.about(self, "班级创建结果", "班级创建成功")
                else:
                    QMessageBox.about(self, "班级创建结果", "班级创建失败")

    #班级查询
    def get_class(self):
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/getlist"
        params = {
            "start":0,
            "length":100
        }
        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:
            return response.json()
    #将查询到的结果显示在MessageBOX框上面
    def display_class(self):
        list=self.get_class()
        str=''
        for i in list['result']['group_id_list']:
            str=str+'\n'+i
        QMessageBox.about(self,"班级列表",str)
    #班级删除
    def delete_calss(self):
        #打开输入框,进行输入用户组
        list = self.get_class()#首先获取用户组信息
        group,ret=QInputDialog.getText(self, "存在的班级", "班级信息"+str(list['result']['group_id_list']))
        if group == "":
            print("取消删除班级")
        else:
            request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/delete"

            params = {
                "group_id": group#要删除用户组的id
            }
            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:
                print(response.json())
                message = response.json()
                if message['error_code'] == 0:
                    QMessageBox.about(self, "班级删除结果", "班级删除成功")
                else:
                    QMessageBox.about(self, "班级删除结果", "班级删除失败")
    #增加学生信息
    def add_student(self):
        '''
        人脸注册
        '''
        list=self.get_class()#获取班级,将班级信息传递到我们新建的界面之中
        # 创建一个窗口,进行用户信息录入
        window = add_student_window(list['result']['group_id_list'],self)#将获取到的班级传递到新的界面,后续有用
        #新创建窗口,通过exec()函数一直在执行,窗口不进行关闭
        window_status=window.exec_()
        #判断
        if window_status !=1:
            return
        base64_image = window.base64_image
        # 参数请求中,需要获取人脸编码,添加的组的id,添加的用户,新用户id信息
        request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add"

        params = {
            "image": base64_image,  # 人脸图片
            "image_type": "BASE64",  # 图片编码格式
            "group_id": window.class_id,  # 班级名称
            "user_id": window.student_id,  # 学生学号
            "user_info": window.student_name# 学生姓名
        }
        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:
            data = response.json()
            if data['error_code'] == 0:
                QMessageBox.about(self, "增加结果", "学生增加成功!")
            else:
                QMessageBox.about(self, "增加结果", "学生增加失败!")

(2)、add_student_window.py文件修改后代码如下所示:

import base64

import cv2
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QPixmap

from add_student import Ui_Dialog
from PyQt5.QtWidgets import QDialog
from cameraVideo import camera

class add_student_window(Ui_Dialog,QDialog):
    def __init__(self,list,parent=None):
        super(add_student_window,self).__init__(parent)
        self.setupUi(self)
        self.list=list#收取主界面传递过来的班级列表
        self.show_class()#将班级列表显示在下拉框中
        self.label.setScaledContents(True)#使得图像自适应
        self.label.setPixmap(QPixmap("./image/my.jpg"))
        self.cameravideo = camera()#导入相机函数
        self.time = QTimer()#启用定时器,实时显示人脸视频
        self.time.timeout.connect(self.show_camera)#计时器绑定画面显示函数
        self.time.start(50)#每隔50ms获取一次画面
        self.pushButton_6.clicked.connect(self.get_cameradata)#获取画面按钮事件绑定
        self.pushButton_2.clicked.connect(self.get_student_data)#点击确定,获取对应信息
        self.pushButton_3.clicked.connect(self.close_window)#点击关闭,窗口关闭
    def show_camera(self):
        # 获取摄像头数据
        pic = self.cameravideo.camera_to_pic()#获取一帧图像
        # 显示数据、显示画面
        self.label.setPixmap(pic)

    def get_cameradata(self):
        camera_data1 = self.cameravideo.read_camera()
        # 把摄像头画面转化为一张图片,然后设置编码为base64编码
        _, enc = cv2.imencode('.jpg', camera_data1)
        base64_image = base64.b64encode(enc.tobytes())
        self.base64_image=base64_image#全局变量,用于保存画面base64格式画面
        self.time.stop()#计时器停止
        self.cameravideo.colse_camera()#摄像机关闭
    def show_class(self):
        self.comboBox.clear()
        for i in self.list:
            self.comboBox.addItem(i)#将获取到的班级列表显示在下拉框中
    #获取学生基本信息
    def get_student_data(self):
        self.class_id=self.comboBox.currentText()#获取班级
        self.student_id=self.lineEdit.text()#获取学号
        self.student_name=self.lineEdit_2.text()#获取姓名
        self.accept()#点击确认后关闭对话框
    #关闭窗口
    def close_window(self):
        # 关闭对话框
        self.close()

(3)、add_student.py文件修改后代码如下所示:

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

# Form implementation generated from reading ui file 'add_student.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_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(329, 389)
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(Dialog)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.label = QtWidgets.QLabel(Dialog)
        self.label.setMinimumSize(QtCore.QSize(200, 200))
        font = QtGui.QFont()
        font.setFamily("微软雅黑")
        font.setPointSize(10)
        self.label.setFont(font)
        self.label.setTextFormat(QtCore.Qt.MarkdownText)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.verticalLayout_2.addWidget(self.label)
        self.pushButton_6 = QtWidgets.QPushButton(Dialog)
        font = QtGui.QFont()
        font.setFamily("微软雅黑")
        font.setPointSize(10)
        self.pushButton_6.setFont(font)
        self.pushButton_6.setObjectName("pushButton_6")
        self.verticalLayout_2.addWidget(self.pushButton_6)
        self.verticalLayout_6 = QtWidgets.QVBoxLayout()
        self.verticalLayout_6.setObjectName("verticalLayout_6")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label_2 = QtWidgets.QLabel(Dialog)
        self.label_2.setMinimumSize(QtCore.QSize(75, 0))
        self.label_2.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.label_2.setStyleSheet("background-color: rgb(85, 255, 255);")
        self.label_2.setAlignment(QtCore.Qt.AlignCenter)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout.addWidget(self.label_2)
        self.lineEdit = QtWidgets.QLineEdit(Dialog)
        font = QtGui.QFont()
        font.setFamily("微软雅黑")
        font.setPointSize(10)
        self.lineEdit.setFont(font)
        self.lineEdit.setObjectName("lineEdit")
        self.horizontalLayout.addWidget(self.lineEdit)
        self.verticalLayout_6.addLayout(self.horizontalLayout)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.label_3 = QtWidgets.QLabel(Dialog)
        self.label_3.setMinimumSize(QtCore.QSize(75, 0))
        self.label_3.setStyleSheet("background-color: rgb(85, 255, 255);")
        self.label_3.setAlignment(QtCore.Qt.AlignCenter)
        self.label_3.setObjectName("label_3")
        self.horizontalLayout_4.addWidget(self.label_3)
        self.lineEdit_2 = QtWidgets.QLineEdit(Dialog)
        font = QtGui.QFont()
        font.setFamily("微软雅黑")
        font.setPointSize(10)
        self.lineEdit_2.setFont(font)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.horizontalLayout_4.addWidget(self.lineEdit_2)
        self.verticalLayout_6.addLayout(self.horizontalLayout_4)
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.label_4 = QtWidgets.QLabel(Dialog)
        self.label_4.setMinimumSize(QtCore.QSize(75, 0))
        self.label_4.setStyleSheet("background-color: rgb(85, 255, 255);")
        self.label_4.setAlignment(QtCore.Qt.AlignCenter)
        self.label_4.setObjectName("label_4")
        self.horizontalLayout_5.addWidget(self.label_4)
        self.comboBox = QtWidgets.QComboBox(Dialog)
        self.comboBox.setMinimumSize(QtCore.QSize(224, 0))
        font = QtGui.QFont()
        font.setFamily("微软雅黑")
        font.setPointSize(10)
        self.comboBox.setFont(font)
        self.comboBox.setObjectName("comboBox")
        self.horizontalLayout_5.addWidget(self.comboBox)
        self.verticalLayout_6.addLayout(self.horizontalLayout_5)
        self.verticalLayout_2.addLayout(self.verticalLayout_6)
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.pushButton_2 = QtWidgets.QPushButton(Dialog)
        font = QtGui.QFont()
        font.setFamily("微软雅黑")
        font.setPointSize(10)
        self.pushButton_2.setFont(font)
        self.pushButton_2.setAutoDefault(True)
        self.pushButton_2.setDefault(True)
        self.pushButton_2.setFlat(False)
        self.pushButton_2.setObjectName("pushButton_2")
        self.horizontalLayout_2.addWidget(self.pushButton_2)
        self.pushButton_3 = QtWidgets.QPushButton(Dialog)
        font = QtGui.QFont()
        font.setFamily("微软雅黑")
        font.setPointSize(10)
        self.pushButton_3.setFont(font)
        self.pushButton_3.setObjectName("pushButton_3")
        self.horizontalLayout_2.addWidget(self.pushButton_3)
        self.verticalLayout_2.addLayout(self.horizontalLayout_2)
        self.verticalLayout_3.addLayout(self.verticalLayout_2)

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

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.label.setText(_translate("Dialog", "学生人脸画面捕捉"))
        self.pushButton_6.setText(_translate("Dialog", "选择该画面"))
        self.label_2.setText(_translate("Dialog", "学号"))
        self.label_3.setText(_translate("Dialog", "姓名"))
        self.label_4.setText(_translate("Dialog", "班级"))
        self.pushButton_2.setText(_translate("Dialog", "确定"))
        self.pushButton_3.setText(_translate("Dialog", "取消"))

本次博客到此结束,希望通过本次博客,小伙伴们能够了解到打卡签到系统中学生人脸信息是如何添加的哦!


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

加入中科创达的第二天,当然还是入职培训,今天的培训很不一样,有授课,有课后游戏,有和小伙伴的互动。中科创达,一个开放包容的平台,希望在公司的大愿景下面,能够和小伙伴们一起实现今天书写的目标和未来。
使命:创造丰富多彩的智能世界。
愿景:让我们的智能技术应用于每一台设备。
价值观:以客户为中心,坚持以艰苦奋斗者为本,坚持以技术为核心竞争力!

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

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
【资源说明】 python开发基于深度学习AI人脸识别自动考勤系统源码-毕业设计.zip 项目说明 相信很多人都有上下班忘记考勤签到的问题,此项目结合 [Mediapipe](https://mediapipe.dev/) 可以有效解决这个问题: - 只要在 PC 运行此程序,即可通过 PC 摄像头进行 AI 人脸识别 - 若 AI 判定是本人,就能够用 ADB (支持大部分 Android)触发手机上的考勤 APP 进行自动打卡 程序原理 ```mermaid sequenceDiagram participant 人脸识别服务 participant 定时打卡脚本 participant ADB participant 考勤手机 人脸识别服务->>人脸识别服务: 用摄像头采集<br/>【我】的面部特征 Note right of 人脸识别服务: 正脸 & 侧脸 ADB->>考勤手机: 连接 Note left of 考勤手机: 有线 定时打卡脚本->>定时打卡脚本: 检查打卡时间 Note right of 定时打卡脚本: 触发打卡脚本 loop 自动打卡 定时打卡脚本->>人脸识别服务: 激活摄像头画面 人脸识别服务->>定时打卡脚本: 识别【我】是否在画面内 定时打卡脚本->>ADB: 调用 ADB 指令 ADB->>考勤手机: 解锁屏幕 ADB->>考勤手机: 启动考勤程序 ADB->>考勤手机: 模拟按键打卡 ADB->>考勤手机: 锁屏 考勤手机->>定时打卡脚本: 记录打卡时间 end ``` > 理论上不需要人脸识别也能使用,但安全性会大大降低,毕竟万一不在工位时、手机又被 ADB 解锁 ... 0x30 硬件接线 | 硬件 | 要求 | 用途 | |:---:|:---|:---| | PC 摄像头 | 内置/外设均可 | 用于 AI 人脸识别,作为触发解锁手机考勤的安全条件 | | 手机支架 | 可充电、支持数据传输 | 用于接收 ADB 指令 | > 如果你的考勤 APP **不需要**进一步做人脸识别(如钉钉等),可以把手机支架换成数据线 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!
qt是一种跨平台的应用程序开发框架,它包含了许多用于创建图形用户界面(GUI)的功能和工具。通过使用qt,开发者可以在多个操作系统上构建高性能的应用程序。而百度AI人脸识别系统则是基于百度的人工智能技术开发的一种人脸识别系统百度AI人脸识别系统集成了颜值评分、人脸比对、性别年龄识别等多种功能。它可以通过对人脸进行分析和比对,判断出人脸的年龄、性别以及颜值评分等信息。此外,它还可以通过人脸比对技术进行身份认证,用于门禁系统人脸支付等场景。 使用qt来开发百度AI人脸识别系统,可以便捷地创建用户友好的图形界面,并调用百度AI人脸识别API接口来实现人脸识别功能。开发者可以通过qt提供的丰富控件和布局管理器,设计出符合用户习惯的界面,提供良好的用户体验。 通过qt开发的百度AI人脸识别系统,可以应用于各种场景,例如安防领域的人脸识别门禁系统,民宿行业的人脸入住认证系统,还能用于医疗行业的患者身份认证等。使用这种开发方式,可以大幅度减少开发时间和成本,提高开发效率。 综上所述,使用qt开发百度AI人脸识别系统可以充分发挥qt的跨平台特性和丰富的GUI功能,方便开发者在不同操作系统上构建性能优秀的人脸识别应用程序。同时,百度AI人脸识别系统的功能丰富,可以应用于多个行业,提供更好的用户体验和安全性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

陈一月的编程岁月

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

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

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

打赏作者

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

抵扣说明:

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

余额充值