1.到旷视官网上注册申请key和secret
2.人脸库图像准备,我的人脸库用图片如下:(图片文件名不能有中文,否则会调用错误)
3.根据官方api文档写几个post相关的函数
def detect_face(filepath):#检测图片里人脸信息
http_url ="https://api-cn.faceplusplus.com/facepp/v3/detect"
files = {"image_file": open(filepath, "rb")}
data = {"api_key":key, "api_secret": secret}
response = requests.post(http_url, data=data, files=files)
req_dict = response.json()
print(req_dict)
return req_dict
def set_face(outer_id):#创建face_set人脸库
url = 'https://api-cn.faceplusplus.com/facepp/v3/faceset/create'
params = {
'api_key':key,
'api_secret':secret,
'outer_id':outer_id
}
response = requests.post(url,data = params)
req_dict = response.json()
print(req_dict)
return req_dict
def addface(outer_id,facetokens):#将face加入到faceset
url = 'https://api-cn.faceplusplus.com/facepp/v3/faceset/addface'
params = {
'api_key':key,
'api_secret':secret,
#'faceset_token':faceset,
'outer_id':outer_id,
'face_tokens':facetokens
}
r = requests.post(url,data = params)
req_dict = r.json()
print(req_dict)
return req_dict
def face_search(image_file1,outer_id):#查找face库里有无对应人脸,默认返回result是最大脸结果
url = 'https://api-cn.faceplusplus.com/facepp/v3/search'
files = {"image_file": open(image_file1, "rb")}
params = {
'api_key':key,
'api_secret':secret,
#'faceset_token':faceset_token,
'outer_id':outer_id
}
r = requests.post(url,files = files,data = params)
req_dict = r.json()
print(req_dict)
return req_dict
def face_search2(facetoken,outer_id):#根据facetoken来返回结果
url = 'https://api-cn.faceplusplus.com/facepp/v3/search'
params = {
'api_key':key,
'api_secret':secret,
'face_token':facetoken,
'outer_id':outer_id
}
r = requests.post(url,data = params)
req_dict = r.json()
print(req_dict)
return req_dict
def getfaceset():#获取faceset信息
url = 'https://api-cn.faceplusplus.com/facepp/v3/faceset/getfacesets'
params = {
'api_key':key,
'api_secret':secret,
}
response = requests.post(url,data = params)
req_dict = response.json()
print(req_dict)
return req_dict
def deletefaceset(outer_id):#删除faceset
url = 'https://api-cn.faceplusplus.com/facepp/v3/faceset/delete'
params = {
'api_key':key,
'api_secret':secret,
'outer_id':outer_id,
'check_empty':0
}
response = requests.post(url,data = params)
req_dict = response.json()
print(req_dict)
return req_dict
def face_SetUserID(face_token,user_id):#为检测出的某一个人脸添加标识信息,该信息会在Search接口结果中返回,用来确定用户身份。
url = 'https://api-cn.faceplusplus.com/facepp/v3/face/setuserid'
params = {
'api_key':key,
'api_secret':secret,
'face_token':face_token,
'user_id':user_id
}
r = requests.post(url,data = params)
req_dict = r.json()
print(req_dict)
return req_dict
4.调用旷视api
1)创建人脸库faceset:创建faceset要用到Faceset的Face detect的api,
首先,使用FaceSet Create API创建人脸库,然后使用Detect API历遍人脸图片目录,并把对应的facetoken保存在人脸库里并附加1个对应的‘userid’方便后续调用。
def makedataset(dataset_path='./database',outer_id='人脸库'):
img_paths=os.listdir(dataset_path)
user_ids=[img_path.split('.')[0] for img_path in img_paths] #解析人名
img_paths=[os.path.join(dataset_path,img_path) for img_path in img_paths]#解析图片地址
#1.创建Faceset,outerid为’人脸库‘
set_face(outer_id)#创建人脸库faceset
#2.人脸库中加入人脸token
for (user_id,img_path) in zip(user_ids,img_paths):
face_json = detect_face(img_path)#检测图片中人脸
face_token= face_json['faces'][0]['face_token']#获取人脸face_token
addface(outer_id,face_token)#把face_token追加到人脸库faceset
face_SetUserID(face_token,user_id)#给face_token绑定1个user_id
2)人脸检测和识别 :原face search的api只返回最大脸的识别结果,如果图片中所有的都要识别,则需要把图片里所有的检测出的face_token送入search api
def find_all_faces(img_path,outer_id='人脸库'):#找到图片里所有脸并标出
face_json=detect_face(img_path)
faces=face_json['faces']
for face in faces:
face['result']=face_search2(face['face_token'],outer_id)['results'][0]
return faces
def find_biggest_face(img_path,outer_id='人脸库'):#找到图片里脸最大的并标出
face_json=face_search(img_path,outer_id='人脸库')
faces=[face_json['faces'][0]]
faces[0]['result']=face_json['results'][0]
return faces
3)检测结果绘制:由于opencv不支持中文显示,所以这里要使用pillow的库来处理
def draw_result(img,faces):#绘制结果(PIL库可以显示中文)
textSize=20
if (isinstance(img, np.ndarray)): #判断是否OpenCV图片类型
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img)
fontText = ImageFont.truetype("/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc", textSize, encoding="utf-8")
for face in faces:
loc=face['face_rectangle']
result=face['result']
if loc['width']>35:#只处理宽度大于40的人脸
draw.rectangle((loc['left'], loc['top'], loc['left']+loc['width'], loc['top']+loc['height']), None, (0,255,0),width=4)
if result['confidence']>60:#根据置信率贴标
text_show=name_dict[result['user_id']]+' '+str(result['confidence'])+'%'
draw.text((loc['left'], loc['top']-textSize-4), text_show, (0,255,0), font=fontText)
else:
draw.text((loc['left'], loc['top']-textSize-4), '其他人', (0,255,0), font=fontText)
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
检测效果图:
完整代码:
#--------------------利用旷视api进行人脸检测和识别---------------------
import requests
from json import JSONDecoder
import os
import cv2
from PIL import Image,ImageDraw,ImageFont
import numpy as np
#定义key和sercet,需要到旷视网上申请注册
key = ""
secret = ""
#定义userid和人名的关系
name_dict={"HuangXiaoming":"黄晓明","DengChao":"邓超","HeJiong":"何炅","TongDawei":"佟大为","WangYuan":"王源","YangYing":"杨颖","YiYangqianxi":"易烊千玺","WangJunkai":"王俊凯"}
def detect_face(filepath):#传入图片文件
http_url ="https://api-cn.faceplusplus.com/facepp/v3/detect"
files = {"image_file": open(filepath, "rb")}
data = {"api_key":key, "api_secret": secret}
response = requests.post(http_url, data=data, files=files)
req_dict = response.json()
print(req_dict)
return req_dict
def set_face(outer_id):#创建face_set
url = 'https://api-cn.faceplusplus.com/facepp/v3/faceset/create'
params = {
'api_key':key,
'api_secret':secret,
'outer_id':outer_id
}
response = requests.post(url,data = params)
req_dict = response.json()
print(req_dict)
return req_dict
def addface(outer_id,facetokens):#将face加入到faceset
url = 'https://api-cn.faceplusplus.com/facepp/v3/faceset/addface'
params = {
'api_key':key,
'api_secret':secret,
#'faceset_token':faceset,
'outer_id':outer_id,
'face_tokens':facetokens
}
r = requests.post(url,data = params)
req_dict = r.json()
print(req_dict)
return req_dict
def face_search(image_file1,outer_id):#查找face库里有无对应人脸,默认返回result是最大脸结果
url = 'https://api-cn.faceplusplus.com/facepp/v3/search'
files = {"image_file": open(image_file1, "rb")}
params = {
'api_key':key,
'api_secret':secret,
#'faceset_token':faceset_token,
'outer_id':outer_id
}
r = requests.post(url,files = files,data = params)
req_dict = r.json()
print(req_dict)
return req_dict
def face_search2(facetoken,outer_id):#根据facetoken来返回结果
url = 'https://api-cn.faceplusplus.com/facepp/v3/search'
params = {
'api_key':key,
'api_secret':secret,
'face_token':facetoken,
'outer_id':outer_id
}
r = requests.post(url,data = params)
req_dict = r.json()
print(req_dict)
return req_dict
def getfaceset():#获取faceset信息
url = 'https://api-cn.faceplusplus.com/facepp/v3/faceset/getfacesets'
params = {
'api_key':key,
'api_secret':secret,
}
response = requests.post(url,data = params)
req_dict = response.json()
print(req_dict)
return req_dict
def deletefaceset(outer_id):#删除faceset
url = 'https://api-cn.faceplusplus.com/facepp/v3/faceset/delete'
params = {
'api_key':key,
'api_secret':secret,
'outer_id':outer_id,
'check_empty':0
}
response = requests.post(url,data = params)
req_dict = response.json()
print(req_dict)
return req_dict
def face_SetUserID(face_token,user_id):#为检测出的某一个人脸添加标识信息,该信息会在Search接口结果中返回,用来确定用户身份。
url = 'https://api-cn.faceplusplus.com/facepp/v3/face/setuserid'
params = {
'api_key':key,
'api_secret':secret,
'face_token':face_token,
'user_id':user_id
}
r = requests.post(url,data = params)
req_dict = r.json()
print(req_dict)
return req_dict
def makedataset(dataset_path='./database',outer_id='人脸库'):
img_paths=os.listdir(dataset_path)
user_ids=[img_path.split('.')[0] for img_path in img_paths] #解析人名
img_paths=[os.path.join(dataset_path,img_path) for img_path in img_paths]#解析图片地址
#1.创建Faceset,outerid为’人脸库‘
set_face(outer_id)
#2.人脸库中加入人脸token
for (user_id,img_path) in zip(user_ids,img_paths):
face_json = detect_face(img_path)
face_token= face_json['faces'][0]['face_token']
addface(outer_id,face_token)
face_SetUserID(face_token,user_id)
def draw_result(img,faces):#绘制结果(PIL库可以显示中文)
textSize=20
if (isinstance(img, np.ndarray)): #判断是否OpenCV图片类型
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img)
fontText = ImageFont.truetype("/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc", textSize, encoding="utf-8")
for face in faces:
loc=face['face_rectangle']
result=face['result']
if loc['width']>35:#只处理宽度大于40的人脸
draw.rectangle((loc['left'], loc['top'], loc['left']+loc['width'], loc['top']+loc['height']), None, (0,255,0),width=4)
if result['confidence']>60:#根据置信率贴标
text_show=name_dict[result['user_id']]+' '+str(result['confidence'])+'%'
draw.text((loc['left'], loc['top']-textSize-4), text_show, (0,255,0), font=fontText)
else:
draw.text((loc['left'], loc['top']-textSize-4), '其他人', (0,255,0), font=fontText)
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
def find_all_faces(img_path,outer_id='人脸库'):#找到图片里所有脸并标出
face_json=detect_face(img_path)
faces=face_json['faces']
for face in faces:
face['result']=face_search2(face['face_token'],outer_id)['results'][0]
return faces
def find_biggest_face(img_path,outer_id='人脸库'):#找到图片里脸最大的并标出
face_json=face_search(img_path,outer_id='人脸库')
faces=[face_json['faces'][0]]
faces[0]['result']=face_json['results'][0]
return faces
if __name__ == "__main__":
#makedataset(outer_id='人脸库')
#dataset=getfaceset()
#deletefaceset('人脸库')
img_paths=os.listdir('./face_test')
img_paths=[os.path.join('./face_test',img_path) for img_path in img_paths]
index=0
for img_path in img_paths:
faces=find_all_faces(img_path,outer_id='人脸库')
#faces=find_biggest_face(img_path,outer_id='人脸库')
img=cv2.imread(img_path)
img_result=draw_result(img,faces)
cv2.imwrite('./result/'+str(index)+'.jpg',img_result)
index=index+1
#cv2.imshow('',img_result)
#cv2.waitKey(0)