在英特尔杯项目中需要使用人脸识别实现陌生访客识别功能,为了降低系统复杂度、为后期调试减少不必要的工作量(懒~)我选择了较为成熟的百度人脸识别。
人脸识别使用了包括百度平台中的人脸库管理和人脸搜索两个功能。在使用时人脸库管理模块将实现人脸库的增删改查,人脸搜索模块在人脸库中搜索与输入图片最相似的人脸并返回结果。
目录
创建人脸识别应用
登录百度智能云https://cloud.baidu.com/product/face,在控制台中创建应用:
应用创建完成后记录该应用的API Key和Secret Key。
人脸搜索代码编写
人脸搜索API请求文档:文档
查文档可知,百度API调用具有鉴权认证机制,人脸比对请求头需要access_token参数:
# encoding:utf-8
import requests
# client_id 为官网获取的AK, client_secret 为官网获取的SK
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=【官网获取的AK】&client_secret=【官网获取的SK】'
response = requests.get(host)
if response:
print(response.json())
人脸识别简单实现
先使用python简单实现人脸识别:
以下代码的功能为将脚本所在目录中的“1.jpg”图片与人脸库中的人脸做对比。程序运行的前提是目录中必须已经保存有一张命名为“1.jpg”的图片。
import json
import base64
import requests
# 1.读取图片数据,整合图片json数据
with open("1.jpg", "rb") as f:
pic1 = f.read()
image_data = json.dumps(
{
"image": str(base64.b64encode(pic1), "utf-8"),
"image_type": "BASE64", #上传照片时采用64位编码
"group_id_list": "用户创建的人脸组",
"max_face_num": 1,#一张照片中检测人脸的最大数目
"quality_control": "NORMAL", #照片质量控制
"liveness_control": "NORMAL" #活体检测强度
}
)
# 2.拼接人脸识别API接口
get_token = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=/*上图中的API Key*/&client_secret=/*上图中的Secret Key*/"
API_url = "https://aip.baidubce.com/rest/2.0/face/v3/search?access_token="
text = requests.get(get_token).json()
print(text['access_token'])
url = API_url + text['access_token']
print(url)
# 3.请求API接口传入json数据,返回图片相似度
response = requests.post(url, image_data).json()
print(response)
score = response['result']['score']
print("相似度为:{}%".format(score))
if score > 80:
print("Yes")
else:
print("No")
字段 | 必选 | 类型 | 说明 |
---|---|---|---|
face_token | 是 | string | 人脸标志 |
user_list | 是 | array | 匹配的用户信息列表 |
group_id | 是 | string | 用户所属的group_id |
user_id | 是 | string | 用户的user_id |
user_info | 是 | string | 注册用户时携带的user_info |
score | 是 | float | 用户的匹配得分,推荐阈值80分 |
以上程序在将需要的API Key和Secret Key填至对应位置后,json参数设置成功后即可将程序脚本所在目录中文件名为“1.jpg”的照片上传至百度云平台,在网络通畅的情况下可以在一到两秒内获得上表中的结果。以下为返回结果示例:
{
"face_token": "fid",
"user_list": [
{
"group_id" : "test1",
"user_id": "u333333",
"user_info": "Test User",
"score": 99.3
}
]
}
进阶-实时人脸识别
上面的程序只能检测脚本所在文件夹中已经存在的照片,不能满足识别访客这一应用场景对于实时性的需求。
访客识别程序需要实现从摄像头捕捉实时的访客人脸照片,并与人脸库中的人脸作比较。
打开摄像头保存照片
在这里使用OpenCV驱动摄像头并进行离线人脸检测。以下为打开摄像头并保存照片的Python示例程序。
import cv2
import os
capture = cv2.VideoCapture(0)#设置摄像头
while 1:
ret,frame = capture.read()#将摄像头拍到的图像作为frame值
cv2.imshow("capture",frame)#将frame的值显示出来,有两个参数,前一个是窗口名字,后面是值
if cv2.waitKey(100)&0xff==ord('q'):#判断退出的条件,按下“q”退出
cv2.imwrite("1.jpg",frame)
print("是否要删除照片?")
k = int(input("是(1) 否(0)"))
if k==1:
os.remove("1.jpg")#删除图片文件
else :
print("人脸照片已保存!")
capture.release()#释放摄像头
cv2.destroyAllWindows()#关闭所有绘图窗口
break
现在可以将人脸识别与保存照片两个程序结合在一起重新编辑,以实现从摄像头实时捕获人脸图片并进行访客身份识别的功能。
摄像头人脸检测与身份识别
import cv2
import json
import base64
import requests
import time
import os
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades+'haarcascade_frontalface_default.xml')
# 调用摄像头
cap = cv2.VideoCapture(0)
while(True):
# 获取摄像头拍摄到的画面
ret, frame = cap.read()
faces = face_cascade.detectMultiScale(frame, 1.3, 5)
print(type(faces))
print(faces)
img = frame
for (x,y,w,h) in faces:
# 画出人脸框,蓝色,画笔宽度微
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
# 框选出人脸区域
face_area = img[y:y+h, x:x+w]
# 实时展示效果画面
cv2.imshow('frame2',img)
if not(isinstance(faces,tuple)) :
time.sleep(2)
cv2.imwrite("1.jpg",frame)
break
cap.release()
with open("1.jpg","rb") as f:
pic1 = f.read()
image_data = json.dumps(
{"image": str(base64.b64encode(pic1), "utf-8"), "image_type": "BASE64", "group_id_list": "My_family_member",
"max_face_num": 1, "quality_control": "NORMAL", "liveness_control": "NORMAL"}
)
# 2.拼接人脸识别API接口
get_token = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=‘’‘API Key’‘’&client_secret=‘’‘Secret Key’‘’"
API_url = "https://aip.baidubce.com/rest/2.0/face/v3/search?access_token="
text = requests.get(get_token).json()
print(text['access_token'])
url = API_url + text['access_token']
print(url)
# 3.请求API接口传入json数据,返回图片相似度
response = requests.post(url, image_data).json()
print(response)
if response['result']['user_list'][0]['score'] >= 70 :
print("该访客为:%s"%response['result']['user_list'][0]['user_id'])
else :
print("非法闯入!警报!!!")
print("是否将该访客人脸数据放入人脸数据库中?")
flag = int(input("Yes_1,No_0"))
if flag == 1 :
ID = input("请输入待添加人脸编号:")
image_data = json.dumps({"image": str(base64.b64encode(pic1), "utf-8"), "image_type": "BASE64", "group_id": "My_family_member", "user_id": ID,
"quality_control": "NORMAL", "liveness_control": "NORMAL", "action_type": "APPEND"})
get_token = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=‘’‘API Key&client_secret=’‘’Secret Key‘’‘"
API_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token="
text = requests.get(get_token).json()
print(text['access_token'])
url = API_url + text['access_token']
print(url)
response = requests.post(url, image_data).json()
print(response)
os.remove('1.jpg')
else :
pass
程序的工作流程为:
需要注意的是,加载人脸检测的级联分类器时需要明确模型所在的位置,一般在OpenCV安装目录下,在代码第六行可以中需要填写人脸检测模型的位置。
至此,使用百度人脸识别API完成实时人脸识别的功能已经基本实现。
人脸库管理
如果你读过刚才的读取摄像头并检测识别人脸的代码之后,会发现代码中还有一段关于人脸库管理添加访客的代码,现在对人脸库管理的功能和方法进行详细叙述。
人脸库管理要实现的功能
人脸库管理要实现的功能有
人脸注册:向人脸库中添加人脸
人脸更新:更新人脸库中指定用户下的人脸信息
人脸删除:删除指定用户的某张人脸
用户信息查询:查询人脸库中某个用户的详细信息
获取用户人脸列表:获取某个用户组中的全部人脸列表
获取用户列表:查询指定用户组中的用户列表
复制用户:将指定用户复制到另外的人脸组
删除用户:删除指定用户
创建用户组:创建一个新的用户组
删除用户组:删除指定用户组
组列表查询:查询人脸库中用户组的列表
人脸库管理代码示例
下面,给出以添加访客为例的人脸库管理代码:
import json
import base64
import requests
with open("1.jpg", "rb") as f:
pic1 = f.read()
ID = input("请输入待添加人脸姓名:")
image_data = json.dumps(
{"image": str(base64.b64encode(pic1), "utf-8"), "image_type": "BASE64", "group_id": "My_family_member", "user_id": ID,
"quality_control": "NORMAL", "liveness_control": "NORMAL"}
)
get_token = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=’‘’API Key‘’‘&client_secret=’‘’Secret Key‘’‘"
API_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token="
text = requests.get(get_token).json()
print(text['access_token'])
url = API_url + text['access_token']
print(url)
response = requests.post(url, image_data).json()
print(response)
从技术文档中可以看到,使用不同的功能需要使用各个功能对应的请求URL。反映到上面的代码中就是“API_url”对应的内容。
下面给出使用频率较高的几个功能的人脸库管理程序:
import json
import base64
import requests
import cv2
import os
import time
#功能选择
print("选择功能:")
print("1.添加授权访客")
print("2.删除授权访客")
print("3.查看人脸库中授权访客")
i = int(input())
#添加授权访客
if i == 1:
print("选中授权访客添加功能。")
print("请输入该位授权访客姓名ID:")
ID = input()
print("十秒钟后启动摄像头。请录入您的正脸完整图像!图像稳定后按“Q”保存人脸图片。")
time.sleep(10)
cap = cv2.VideoCapture(0)
while 1:
ret,frame = cap.read()
cv2.imshow("cap",frame)
if cv2.waitKey(100)&0xff==ord('q'):
cv2.imwrite("%s.jpg"%ID,frame)#保存人脸图片
print("人脸信息已保存")
cap.release()#释放摄像头
cv2.destroyAllWindows()#关闭所有绘图窗口
with open("%s.jpg"%ID,"rb") as f:
pic1 = f.read()
image_data = json.dumps(
{"image": str(base64.b64encode(pic1), "utf-8"), "image_type": "BASE64", "group_id": "My_family_member", "user_id": ID,
"quality_control": "NORMAL", "liveness_control": "NORMAL"})
#拼接人脸识别API接口
get_token = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='''API Key'''&client_secret='''Secret Key'''"
API_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token="
text = requests.get(get_token).json()
url = API_url + text['access_token']
response = requests.post(url, image_data).json()
if response['error_code'] != 0 :
print("人脸录入错误!请再次录入。")
print("错误信息:%s"%response['error_msg'])
os.remove("%s.jpg"%ID)
break
else :
print("人脸数据已上传至人脸数据库!")
break
elif i == 2 :
print("选中删除授权访客功能。")
print("请输入要删除授权访客姓名ID:")
ID = input()
print("您将要删除ID为“%s”的访客,请问是否继续?")
img = cv2.imread('yang.jpg')
cv2.imshow('待删除访客',img)
print("是(1) 否(2)")
j = int(input())
if j == 1:
print("将要删除该位访客授权。")
cv2.destroyAllWindows()
user_data = json.dumps({"group_id":"My_family_member","user_id":ID})
get_token = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='''API Key'''&client_secret='''Secret Key'''"
API_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/delete?access_token="
text = requests.get(get_token).json()
url = API_url + text['access_token']
response = requests.post(url, user_data).json()
if response['error_code']!=0:
print("授权删除失败!")
print("错误信息:%s"%response['error_msg'])
else :
print("访客删除成功")
elif i == 3 :
print("选中访客列表查看功能")
get_token = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='''API KEY'''&client_secret='''Secret Key'''"
API_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/getusers?access_token="
group_data=json.dumps({"group_id":"My_family_member"})
text = requests.get(get_token).json()
url = API_url + text['access_token']
response = requests.post(url, group_data).json()
if response :
print(response['result']['user_id_list'])
以上代码实现了添加访客、删除访客、查看访客列表的功能,其中的要点为对请求数据和返回数据的处理。
至此使用百度人工智能平台实现人脸识别和人脸库管理已经讲解完毕,使用百度平台实现人脸识别很简单,但需要我们仔细思考规划整个系统的功能怎样使整个过程更加智能化,怎么样与诸如OpenCV等配合优化用户的使用体验。