基于人脸识别的课堂签到管理系统(五)---启动/结束签到,以及在百度智能云创建用户组

基于人脸识别的课堂签到管理系统(五)---启动/结束签到,以及在百度智能云创建用户组

一.前言概述

网络请求人脸检测线程与窗口获取画面线程通信:

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

在线程中读取画面数据,由线程的run函数进行网络请求,
窗口的信号与线程的槽函数关联就只是数据的传递,而不是直接执行网络请求

线程网络请求后,获取到百度AI的检测,需要在窗口中进行显示
需要由线程把数据传递给窗口:信号槽

打开人脸检测:

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

关闭人脸检测:

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

人脸库管理功能:

创建一个库
添加人脸
删除人脸
修改

二.签到功能

2.1 启动签到

首先是对昨天的代码的修改。在数据传递过程中,数据类型是bytes,而之前定义的是string类型,所以只需修改成byte类型就可以成功上传画面信息

detect_data_signal = pyqtSignal(bytes)

在这里插入图片描述`

    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))

在这里插入图片描述接下来只需将画面信息每隔500ms发送给detect.py

#当开启启动签到时,创建定时器,500ms,用作获取要检测的画面

        self.facedetecttime = QTimer(self)
        self.facedetecttime.start(500)
        self.facedetecttime.timeout.connect(self.get_cameradata)

在这里插入图片描述同样的,可以从detect.py中将百度返回的人脸信息传递回mywindow.py中
在detect.py中自定义一个信号槽

transmit_data = pyqtSignal(dict)

在这里插入图片描述当窗口产生信号,调用槽函数,就把传递的数据,存放在线程的变量中

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

在这里插入图片描述将编码格式为base64的图片发送给百度,获取人脸信息

 def detect_face(self,base64_image):
        '''
        #对话框获取图片
        #获取一张图片(一帧画面)
        #getOpenFileName通过对话框的形式获取一个图片(.JPG)路径
        path,ret = QFileDialog.getOpenFileName(self,"open picture",".","图片格式(*.jpg)")
        #把图片转换成base64编码格式
        fp = open(path,'rb')
        base64_imag = base64.b64encode(fp.read())
        print(base64_imag)
        '''
        # 摄像头获取画面
        # 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,emotion,mask",  # 请求识别人脸的属性, 各个属性在字符串中用,逗号隔开
            "max_face_num": 10
        }
        # 访问令牌
        access_token = self.access_token
        # 把请求地址和访问令牌组成可用的网络请求
        request_url = request_url + "?access_token=" + access_token
        # 参数:设置请求的格式体
        headers = {'content-type': 'application/json'}
        # 发送网络post请求,请求百度AI进行人脸检测,返回检测结果
        # 发送网络请求,就会存在一定的等待时间,程序就在这里阻塞执行,所以会存在卡顿现象
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            data = response.json()
            #data是请求数据的结果,需要进行解析,单独拿出所需的数据内容,分开
            self.transmit_data.emit(dict(data))

然后就可以通过定义的信号槽,将人脸信息返回到mywindow.py中

 # facedetecttime定时器设置检测画面获取
self.detect_data_signal.connect(self.detectThread.get_base64)

在这里插入图片描述并将获取到的人脸信息,打印到“学生人脸信息”中

#槽函数,获取检测数据
    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']
                emotion = data['result']['face_list'][i]['emotion']['type']
                mask = data['result']['face_list'][i]['mask']['type']
                # 往窗口中添加文本,参数就是需要的文本信息
                self.plainTextEdit_2.appendPlainText("-----------------")
                self.plainTextEdit_2.appendPlainText("第" + str(i + 1) + "个学生信息:")
                self.plainTextEdit_2.appendPlainText("-----------------")
                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))
                self.plainTextEdit_2.appendPlainText("-----------------")

这样当我们启动签到时,窗口就可以流畅地显示画面,同时在窗口右侧打印学生人脸信息。

2.2 结束签到

结束签到就需要将我们在启动签到时所设置地定时器全部关掉

#关闭定时器,不再设置检测画面获取
self.facedetecttime.stop()
#关闭定时器,不再去获取摄像头的数据
self.timeshow.stop()
self.timeshow.timeout.disconnect(self.show_cameradata)

同时还需要将detect.py,所启用地多线程关闭
这里通过定义一个变量OK,来完成while条件循序,当OK为True,则循环运行

OK = True
while self.OK:
    if self.condition:
        self.detect_face(self.base64_image)
        self.condition = False
print("while finish")

当OK为False,线程关闭

#关闭检测线程
self.detectThread.OK = False
self.detectThread.quit()
self.detectThread.wait()
print(self.detectThread.isRunning())

最后关闭摄像头,画面设置为初始状态,清除学生人脸信息

# 关闭摄像头
self.cameravideo.close_camera()
#画面设置为初始状态
self.label.setPixmap(QPixmap("1.jpg"))
# 清除学生人脸信息(False)
self.plainTextEdit_2.setPlainText("  ")

三.创建用户

完成了启动和结束签到了后,我们就需要建立一个人脸库,通过百度提供的技术文档可以直接调用创建用户组的函数代码

    def add_group(self):
        #打开对话框,进行输入用户组
        group,ret = QInputDialog.getText(self,"添加用户组","请输入用户组(由数字、字母、下划线组成)")

        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'])

但为了后续的方便的创建用户组,在函数中添加了QInputDialog,QMessageBox对话框来输入创建的用户组的名字以及是否创建成功
在这里插入图片描述

四.程序展示

启动程序,这里我对界面UI进行了改变,并在摄像头显示画面处设置了一张图片
在这里插入图片描述点击签到,选择启动签到,可以明显感觉画面流畅了许多,同时左侧的学生人脸信息打印出了百度返回的人脸信息
在这里插入图片描述点击结束签到,画面回到初始状态,但这里学生人脸信息的清除未能成功
在这里插入图片描述点击人脸库管理,选择创建用户组,弹出对话框,输入用户组名字
在这里插入图片描述这里说下百度的技术文档要求不能重名,如果是同一名字的创建用户组要求则会失败
在这里插入图片描述

在这里插入图片描述

五.相关下载

代码下载:Face_Recognition_Project_5.zip

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值