基于百度AI开放平台的人脸识别实验

本文介绍如何使用百度AI开放平台进行人脸识别实验。
具体过程包括创建应用、部署环境、准备数据集、实验等。

文章目录


基于百度AI开放平台的人脸识别实验

1 准备工作

1.1 创建应用

在百度人脸识别云平台注册账号(使用百度账号即可),网站地址
登录后在控制台中创建人脸检测应用,则会生成相应的App ID、API Key、Secret Key,开发时需要用到。

1.2 获取accesss_token

使用平台进行人脸识别有两种方式,一是通过HTTP API调用,二是通过SDK调用。在使用API调用时,必须在URL中带上accesss_token参数。
(什么是Access_token?
生成签名:也称为Access_token,是调用API时的鉴权凭证,具体可参考Token获取方法
下面给出获取accesss_token的示例代码。

  1. Bash命令代码:
#!/bin/bash
curl -i -k 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=【百度云应用的AK】&client_secret=【百度云应用的SK】'
  1. Python代码:
import urllib
import ssl
from urllib import request
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=al01NPevkzYGs3rrMyuHRQCV&client_secret=EDfImDb8GpmOZh3uGKOOu3xRa05UfgoQ'	# client_id=API Key, client_secret= Secret Key
request = urllib.request.Request(host)
request.add_header('Content-Type', 'application/json; charset=UTF-8')
response = urllib.request.urlopen(request, context=context)
# 获取请求结果
content = response.read()
if (content): 
print(content)

1.3 安装人脸识别SDK

人脸识别SDK包括Java、PHP、Python、C#、C++、Nodejs语言,本次实验使用python sdk进行开发。有两种方式安装如下:

  1. 通过控制台安装,命令如下:
    pip install baidu-aip
  2. 通过官网下载sdk文件。在官网下载sdk文件(如图2),然后进入下载好的文件目录,并使用如下命令安装:
    python setup.py install

2 实验

百度AI开放平台的人脸识别提供了多种功能,如人脸检测、人脸对比、人脸搜索和人脸库管理等。
本次实验进行了人脸检测和人脸对比的功能测试。

2.1 准备数据

本次实验使用从CSDN网站上下载的人脸图像作为测试数据。数据包括两种,第一种包括18000张各种状态的人脸图像(如图2所示),第二种包括15项不同人的图像,每项含有11张同一个人人脸的不同形态(如图3所示)。

基于百度AI开放平台的人脸识别实验

图2 各种状态的人脸图像 ![在这里插入图片描述](https://www.icode9.com/i/ll/?i=20201214225147650.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpbmdweQ==,size_16,color_FFFFFF,t_70) 图3 某个人不同形态的图像

2.2 人脸检测

百度ai平台提供的人脸检测功能如下:

  1. 人脸检测:检测图片中的人脸并标记出位置信息;
  2. 人脸关键点:展示人脸的核心关键点信息,及150个关键点信息。
  3. 人脸属性值:展示人脸属性信息,如年龄、性别等。
  4. 人脸质量信息:返回人脸各部分的遮挡、光照、模糊、完整度、置信度等信息。
    其中典型应用场景如人脸属性分析,基于人脸关键点的加工分析,人脸营销活动等。

2.2.1 API方式

通过api调用人脸识别接口,步骤如下:

  1. 获取accesss_token参数。见1.2节。
  2. 参数设置。其中平台提供的请求参数如表1所示。
参数 必选 类型 说明
image string 图片信息(总数据大小应小于10M),图片上传方式根据image_type来判断
image_type string 图片类型
BASE64:图片的base64值,base64编码后的图片数据,编码后的图片大小不超过2M;
URL:图片的 URL地址( 可能由于网络等原因导致下载图片时间过长);
FACE_TOKEN: 人脸图片的唯一标识,调用人脸检测接口时,会为每个人脸图片赋予一个唯一的FACE_TOKEN,同一张图片多次检测得到的FACE_TOKEN是同一个。
face_field string 包括age,beauty,expression,face_shape,gender,glasses,landmark,landmark72,landmark150,race,quality,eye_status,emotion,face_type信息;
逗号分隔, 默认只返回face_token、人脸框、概率和旋转角度
max_face_num uint32 最多处理人脸的数目,默认值为1,仅检测图片中面积最大的那个人脸;
最大值10,检测图片中面积最大的几张人脸。
face_type string 人脸的类型
LIVE表示生活照:通常为手机、相机拍摄的人像图片、或从网络获取的人像图片等;
IDCARD表示身份证芯片照:二代身份证内置芯片中的人像照片;
WATERMARK表示带水印证件照:一般为带水印的小图,如*网小图;
CERT表示证件照片:如拍摄的身份证、工卡、护照、学生证等证件图片;默认LIV
liveness_control string 活体控制,检测结果中不符合要求的人脸会被过滤;
NONE: 不进行控制;
LOW:较低的活体要求(高通过率 低攻击拒绝率);
NORMAL: 一般的活体要求(平衡的攻击拒绝率, 通过率);
HIGH: 较高的活体要求(高攻击拒绝率 低通过率);默认NONE
  1. 请求代码。关键代码如下,详细见附件1-face_recognition.py。
img64 = imgdata(img_path)	#获得图像的base64格式数据
params = {'image':img64,'image_type':"BASE64",
    'face_field':"age,beauty,expression,faceshape,emotion,facetype"}
params = urllib.parse.urlencode(params).encode("utf-8")
#人脸检测请求url
request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"
request_url = request_url + "?access_token="+ access_token
request = urllib.request.Request(url=request_url,data=params)
request.add_header('Content-Type', 'application/json')
response = urllib.request.urlopen(request)
content = response.read()
if content:
print(content)
  1. 返回参数。如图4所示部分参数,全部参数见官网:https://ai.baidu.com/docs#/Face-Detect-V3/top。

基于百度AI开放平台的人脸识别实验

图4 人脸检测返回参数示例

本次使用图像如图5,得到的返回结果如图6所示。结果中给出了脸部的具体位置信息,脸部的表情,脸型等等。

基于百度AI开放平台的人脸识别实验

图5 测试脸部图像

基于百度AI开放平台的人脸识别实验

图6 人脸检测返回结果

2.2.2 SDK方式

由于使用sdk调用人脸检测接口,速度较API快。具体代码详见附件-sdk_face_recognition.py。
这次实验增加了画人脸侧框函数,需要安装python-opencv模块。安装教程
人脸检测的结果如图7所示。
从结果看出,平台提供的人脸检测接口能有效检测出图片中的人物位置。

基于百度AI开放平台的人脸识别实验

图7 人脸检测结果示例

2.3 人脸对比

百度ai提供的人脸对比可以用来比对多张图片中的人脸相似度并返回两两比对的得分,可用于判断两张脸是否是同一人的可能性大小。
其提供的接口功能如下:

  1. 两张人脸图片相似度对比:比对两张图片中人脸的相似度,并返回相似度分值;
  2. 多种图片类型:支持生活照、证件照、身份证芯片照、带网纹照四种类型的人脸对比;
  3. 活体检测控制:基于图片中的破绽分析,判断其中的人脸是否为二次翻拍(举例:如用户A用手机拍摄了一张包含人脸的图片一,用户B翻拍了图片一得到了图片二,并用图片二伪造成用户A去进行识别操作,这种情况普遍发生在金融开户、实名认证等环节。);
  4. 质量检测控制:分析图片的中人脸的模糊度、角度、光照强度等特征,判断图片质量;
    主要的典型应用场景如人证合一验证,用户认证等,可与您现有的人脸库进行比对验证等。
    人脸对比的返回参数如表2所示。
参数名 必选 类型 说明
score float 人脸相似度得分(满分100分)
face_list array 人脸信息列表
+face_token string 人脸的唯一标志

本次实验使用了同一个人的两张图像如图8所示,检测结果如图9所示。从结果中看出这两个图像的相似度得分为92.8分,相似度较高,因此符合预期结果。
基于百度AI开放平台的人脸识别实验

图8 人脸对比测试图 ![ 基于百度AI开放平台的人脸识别实验 ](https://www.icode9.com/i/ll/?i=20201214225326712.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpbmdweQ==,size_16,color_FFFFFF,t_70) 图9 对比结果

此外进行了一个对比实验,即使用不同两个人的图像如图10所示,结果如图11和图12。
图11显示了图像-1和图像-2的对比结果,从结果中看出这两个人相似度得分仅为8.3分,因此符合预期结果。
图12显示了图像-1和图像-3的对比结果,从结果中看出这两个人相似度得分达到64.4分,分析分数较高的原因是图像-1和图像-3均有胡须,并且脸型相似,因此整体相似度较高。
综上所述,平台提供的接口基本可以分辨出不同的人的图像。

基于百度AI开放平台的人脸识别实验

图10 对比实验 ![ 基于百度AI开放平台的人脸识别实验 ](https://www.icode9.com/i/ll/?i=20201214225341591.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpbmdweQ==,size_16,color_FFFFFF,t_70) 图11 图像-1和图像-2的对比结果 ![ 基于百度AI开放平台的人脸识别实验 ](https://www.icode9.com/i/ll/?i=20201214225347134.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpbmdweQ==,size_16,color_FFFFFF,t_70) 图12 图像-1和图像-3的对比结果

3 下一步工作

下一步将进行人脸库管理,人脸搜索的实验。具体介绍见官网

参考文献

[1] 百度AI开放平台. https://ai.baidu.com/docs#/Face-Python-SDK/b9c843ac.
[2] luckyfairy17调用百度AipFace做人脸检测[EB/OL]. https://blog.csdn.net/luckyfairy17/article/details/82898861. 2018.9.29.

附件

  • 代码-base_work.py
# -*- coding: utf-8 -*-
# @Author: bruce
# @Date:   2019-04-03 10:52:02
# @Last Modified by:   bruce
# @Last Modified time: 2019-04-04 13:59:29
# @Email: talkwithh@163.com
'''
提供人脸识别的基础功能函数
包括:获取access_token,预处理图像,处理返回结果等
API Key(client_id):al01NPevkzYGs3rrMyuHRQCV
Secret Key(client_secret):EDfImDb8GpmOZh3uGKOOu3xRa05UfgoQ
'''
import urllib
import ssl
import json
import base64
from urllib import request

# 获取access_token
# client_id 为官网获取的AK, client_secret 为官网获取的SK
def get_token():
    context = ssl._create_unverified_context()
    host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=al01NPevkzYGs3rrMyuHRQCV&client_secret=EDfImDb8GpmOZh3uGKOOu3xRa05UfgoQ'
    request = urllib.request.Request(host)
    request.add_header('Content-Type', 'application/json; charset=UTF-8')
    response = urllib.request.urlopen(request, context=context)
    # 获取请求结果
    content = response.read()
    # 转换为字符
    content = bytes.decode(content)
    # 转换为字典
    content = eval(content[:-1])
    return content['access_token']

# 读取图像内容,转换为base64编码
def imgdata(file_path):
    with open(file_path, 'rb') as fp:
        img64 = base64.b64encode(fp.read())
    return str(img64,'utf-8')

#json化结果并保存
def save_results(results,save_path):
    result = json.dumps(results,indent=4)
    with open(save_path,'a') as fp:
        json.dump(results,fp)
        fp.write('\n\n')

print(result)
  • 代码-face_recognition.py
# -*- coding: utf-8 -*-
# @Author: bruce
# @Date:   2019-04-02 10:45:03
# @Last Modified by:   bruce
# @Last Modified time: 2019-04-04 15:17:53
# @Email: talkwithh@163.com
'''
百度人脸识别测试。
方式:调用接口。
范围:人脸检测、人脸搜索等
'''
import urllib
import ssl
import json
from urllib import request
from base_work import get_token,imgdata,save_results

#2019.4.2获得,期限30天
access_token='[24.ceec3749d8b26df02469beb2f95ccc6a.2592000.1556763268.282335-15550323]'
#主函数
def main(img_path,save_path):

    #人脸检测
    face_detect_result = face_detect(img_path)
    save_results(face_detect_result,save_path+'api_face_detect.json')

#人脸检测
def face_detect(img_path):
    # 需要解释
    # context = ssl._create_unverified_context()
    # access_token = get_token()

    img64 = imgdata(img_path)
    params = {'image':img64,'image_type':"BASE64",
    'face_field':"age,beauty,expression,faceshape,emotion,facetype"}
    params = urllib.parse.urlencode(params).encode("utf-8")

    #人脸检测请求url
    request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"

    request_url = request_url + "?access_token="+ access_token
    request = urllib.request.Request(url=request_url,data=params)
    request.add_header('Content-Type', 'application/json')
    response = urllib.request.urlopen(request)
    content = response.read()
    content = bytes.decode(content)

    if content:
        content = eval(content)
    return content

if __name__ == '__main__':
    img_path = '../datas/img/美女1.jpg'
    save_path = '../datas/results/'
main(img_path,save_path)
  • 代码-sdk_face_recognition.py
# -*- coding: utf-8 -*-
# @Author: bruce
# @Date:   2019-04-03 10:39:14
# @Last Modified by:   bruce
# @Last Modified time: 2019-04-04 15:59:24
# @Email: talkwithh@163.com
'''
百度人脸识别测试
方式:python-sdk获取
范围:人脸识别、人脸对比、人脸库管理、人脸搜索等
'''
import os,json
import cv2
import math
import matplotlib
# matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from base_work import imgdata,save_results
from aip import AipFace

#设置图像类型
imageType ="BASE64"

#新建AipFace对象
""" 你的 APPID AK SK """
def create_aipFace():
    APP_ID = '15550323'
    API_KEY = 'al01NPevkzYGs3rrMyuHRQCV'
    SECRET_KEY = 'EDfImDb8GpmOZh3uGKOOu3xRa05UfgoQ'
    client = AipFace(APP_ID, API_KEY, SECRET_KEY)
    return client
#主函数
def main(img_path,save_path):
    #初始化AipFace对象
    client = create_aipFace()
    #创建存储文件夹
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    #人脸检测
    face_img_path1 = img_path + 'person_faces/60.jpg'
    face_img_path2 = img_path + 'person_faces/1.jpg'
    img_save = img_path + 'savefig/'
    # detect_result = face_detect(client,face_img_path2)
    # save_results(detect_result,save_path+'face_detect.json')
    # show_face(face_img_path2,detect_result,img_save+'detect_1.png')

    #人脸对比
    match_img_path = img_path+'yale_face/01/'
    match_result = face_match(client,img_path+'yale_face/02/'+'s1.bmp',img_path+'yale_face/03/'+'s1.bmp')
    save_results(match_result,save_path+'face_match.json')

#人脸检测
def face_detect(client,img_path):
    #读取图像,转换为base64类型
    img_base64 = imgdata(img_path)
    #参数设置
    options = {}
    options["face_field"] = "age,beauty,expression,faceshape,facetype"
    options["max_face_num"] = 2
    options["face_type"] = "LIVE"

    result = client.detect(img_base64,imageType,options)
    return result

#人脸对比
def face_match(client,img_path_1,img_path_2):
    #读取图像,转换为base64类型
    img_base64_1 = imgdata(img_path_1)
    img_base64_2 = imgdata(img_path_2)
    #参数设置
    options = [{'image':img_base64_1,'image_type':imageType},{'image':img_base64_2,'image_type':imageType}]

    result = client.match(options)

    return result

#显示人脸检测框
def show_face(img_path,result,img_save):
    cv2.namedWindow("imgage") #创建窗口
    # 读取原图
    # cap = cv2.VideoCapture(img_path)
    # ret, img = cap.read()
    img = cv2.imread(img_path)

    #解析位置信息
    face_num = result['result']['face_num']

    for num in range(0,int(face_num)):
        location = result['result']['face_list'][num-1]['location']
        # print(location)
        # print(location['face_list'][0])

        Theta = location['rotation'] / 60 # 注意:60度是多次测试的结果,需要弄清楚rotation啥意思,相对于哪里的旋转角度
        A = (int(location['left']),int(location['top']))
        B = (int(location['left'])+int(location['width']*math.cos(Theta)),int(location['top'])+int(location['width']*math.sin(Theta)))
        AC_Len = math.sqrt(location['width']**2 + location['height']**2)
        AC_Theta = math.atan(location['height']/location['width'])+location['rotation']/60
        C = (int(location['left']) + int(AC_Len*math.cos(AC_Theta)), int(location['top'])+int(AC_Len*math.sin(AC_Theta)))
        D = (int(location['left'])-int(location['height']*math.sin(Theta)), int(location['top']) + int(location['height']*math.cos(Theta)))
        cv2.line(img, A, B, (0, 0, 255), 2)
        cv2.line(img, B, C, (0, 0, 255), 2)
        cv2.line(img, C, D, (0, 0, 255), 2)
        cv2.line(img, D, A, (0, 0, 255), 2)

        # left_top = (int(location['left']),int(location['top']))
        # right_bottom = (left_top[0]+int(location['width']),left_top[1]+int(location['height']))
        # cv2.rectangle(img,left_top, right_bottom, (0,0,255),2)

    cv2.imshow('imgage', img)
    cv2.waitKey(0)
    #存储图像
    cv2.imwrite(img_save,img,[int(cv2.IMWRITE_JPEG_QUALITY),70])
    cv2.destroyWindow("imgage")     #关闭窗口


if __name__ == '__main__':
    img_path = '../datas/img/'

    save_path = '../datas/results/'
    main(img_path,save_path)
上一篇:机器学习笔记 使用Face recognition、OpenCV、Python和深度学习进行人脸识别


下一篇:人脸聚类框架(Face Cluster Framework)