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

基于face++的视频流的人脸识别

程序员文章站 2022-03-20 08:23:05
...

基于face++的视频流的人脸识别

github:https://github.com/hfut-xc-yun/hfut-my-face

1.概述

    face++是旷世科技开发的人脸识别的开源API,丰富的接口可供开发者调用,在我上一篇文章中介绍face++的使用说明中利用face++的API做了一个识别马云爸爸的小demo,这次同样使用face++API,做一个进阶demo,使用摄像头对拍摄对象进行人脸身份识别,模拟扫脸支付的一部分。主要思路是

(1)开启摄像头,读该帧图像,运用现有的CascadeClassifier分类器先确定人脸位置,并画出矩形框,这里代码请参考‘7行实现人

    脸识别’这篇博客。https://blog.csdn.net/wireless_com/article/details/64120516不过只能识别这是不是张脸以及其位置,不能确定谁的脸,

    而运用face++ 的平台就可以完成,不用自己再写网络去训练自己的脸。

(2) 把图像送入face++的search API(之前文章 讲到过)去进行匹配,前提是你的face_set有你要检测的人的照片,利用search的返回值,主要

    是唯一标识user_id(名字)。再利用opencv的画图工具显示在该帧上就可以了。


2.代码说明

if __name__ == "__main__":
    capInput = cv2.VideoCapture(1)#开摄像头1
    faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')#载入脸的特征
    face_right = 0  #识别的人脸有没有在faceset中发现,有置1
    recognize_inf = 0 #识别的人脸在faceset中发现,置1,持续显示id信息一定时间标志位
    font = cv2.FONT_HERSHEY_SIMPLEX#字体设置
    i=0#自加每20次访问API,每一帧都访问代价太高,且容易卡顿
    while(1):
        ret, img = capInput.read()#摄像头获取该帧图像
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#图像转灰度
        faces = faceCascade.detectMultiScale(gray,1.1,7)#送入Haar特征分类器
        if cv2.waitKey(1) & 0xFF == ord('q'):#键入q退出
             break
        if len(faces) == 0 :#视频中无脸出现不用请求API
            cv2.imshow('ImageCaptured', img)
        else:    
            if i >= 20 and face_right == 0:
                i = 0#清零
                cv2.imwrite('D:\\PYTHON0\\my_face_handsome\\video_face\\1.jpg',img)#写入该帧图像文件
                face_information = face_search('D:\\PYTHON0\\my_face_handsome\\video_face\\1.jpg','e55232f11a305f9165caf50ef16ae053')#该帧与faceset中人脸进行匹配
                if face_information['faces'] :#[faces]数组不能为空,能在图像中找到脸
                    confidence = face_information['results'][0]['confidence']#读取置信度
                    thresholds = face_information['thresholds']['1e-5']
                    os.remove('D:\\PYTHON0\\my_face_handsome\\video_face\\1.jpg')#删除该帧图像文件,为下一次处理准备
                    if confidence > 75 and thresholds < confidence:  #置信度阈值判断
                        user_id = face_information['results'][0]['user_id'] #获得唯一人脸id
                        recognize_inf = 1
                        face_right = 1
                    else: 
                        face_right = 0
                else:
                    face_right = 0#未能在图像中找到脸
            else:
                i = i + 1
                    
            for x, y, w, h in faces:
                img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)#人脸矩形框
            
            if face_right == 1:
                cv2.putText(img, user_id, (x,y-5), font,1, (0,0,255),1)#照片/添加的文字/左上角坐标/字体/字体大小/颜色/字体粗细
                cv2.putText(img, 'Welcome:', (x-20,y-50), font,2, (0,0,0),2)
                cv2.imshow('ImageCaptured', img)
                if recognize_inf:
                    b = (time.localtime()[5])   
                    a = (time.localtime()[5])
                    recognize_inf = 0
                if(abs(a-b)<=3):#现在该提示信息3s
                    a = (time.localtime()[5])
                else:
                    face_right = 0
            else:
                cv2.putText(img, "stranger", (x,y-5), font,1, (0,255,0),1)
                cv2.imshow('ImageCaptured', img)
            
capInput.release()        
cv2.destroyAllWindows()       



3.自问自答

1.face++的seach已经可以返回人脸位置,为什么还需要用其他分类器做呢?

因为不能每一帧都调用API,代价太高,视频也会卡顿,在这里如果你是做项目,建议去充值成为正式用户,可以获取稳定的上传流量,不然可能会因为流量限制报错。

2.为什么要在视频上保持显示人脸信息id 3s?

如果不这样,调用完API,识别读取到id后只会在这一帧上显示id信息,因为要把face_right标志位清掉,就只会显示陌生人的id信息,保持3s显示更有可用性。再有,如果只在一帧显示,走下一次程序有可能再次读取该脸信息(该脸可能未迅速离开),再次识别没有意义。

3.recognize_inf标志位作用?

为延迟3s的标志位,在这段时间内获取时间值,3s后该标准清0,并清face_right

4.为什么API返回的face元组值可能为空?

这可能也是该程序的小缺陷,因为调用API是传入已经加上人脸框的图像,这里就有可能导致seach匹配失败,认为那不是个脸,解决方法,可以在开辟空间,单独存放刚读到图像的帧,注意不能直接赋值,直接赋值没用,因为这是python,不是C语言,你懂的。

5.不能显示中文信息id?

cv.putText不能使用汉字,会有乱码,网上也有人提出解决方案,不过貌似是pyhton2.7,我尝试失败了,还有要下什么包,太麻烦就没有做,因为英文信息已经可以满足我的需求了,如果谁做出来,可以艾特我。

6.为什么要先存图像在调API,然后再删图像,so terrible

其实seach的API是可以直接传入图像数据的,按照官方API,你需要先将图像信息编码为base64,再传,我在尝试时,编码信息出现问题,我使用python自带base64编码库编码数据与网上在线编码数据不同,所有传入数据总是提示错误,询问客服也没有解决,只有选择这种折中方法,如果哪位大神使用base64上传成功,艾特我。

4.实现

基于face++的视频流的人脸识别


相关标签: 人脸识别