使用百度AI接口v3进行人脸对比

一. 百度AI人脸接口介绍

1.基本介绍

接口能力

  • 两张人脸图片相似度对比:比对两张图片中人脸的相似度,并返回相似度分值;
  • 多种图片类型:支持生活照证件照身份证芯片照带网纹照四种类型的人脸对比;
  • 活体检测:基于图片中的破绽分析,判断其中的人脸是否为二次翻拍(举例:如用户A用手机拍摄了一张包含人脸的图片一,用户B翻拍了图片一得到了图片二,并用图片二伪造成用户A去进行识别操作,这种情况普遍发生在金融开户、实名认证等环节。);
  • 质量检测:返回模糊、光照等质量检测信息,用于辅助判断图片是否符合识别要求;

业务应用

用于比对多张图片中的人脸相似度并返回两两比对的得分,可用于判断两张脸是否是同一人的可能性大小。

典型应用场景:如人证合一验证用户认证等,可与您现有的人脸库进行比对验证。

 

2.请求参数和返回参数

请求参数

参数必选类型说明
imagestring图片信息(总数据大小应小于10M),图片上传方式根据image_type来判断。 两张图片通过json格式上传,格式参考表格下方示例
image_typestring图片类型 BASE64:图片的base64值,base64编码后的图片数据,需urlencode,编码后的图片大小不超过2M;URL:图片的 URL地址( 可能由于网络等原因导致下载图片时间过长);FACE_TOKEN: 人脸图片的唯一标识,调用人脸检测接口时,会为每个人脸图片赋予一个唯一的FACE_TOKEN,同一张图片多次检测得到的FACE_TOKEN是同一个。
face_typestring人脸的类型 LIVE表示生活照:通常为手机、相机拍摄的人像图片、或从网络获取的人像图片等,IDCARD表示身份证芯片照:二代身份证内置芯片中的人像照片, WATERMARK表示带水印证件照:一般为带水印的小图,如公安网小图 CERT表示证件照片:如拍摄的身份证、工卡、护照、学生证等证件图片 默认LIVE
quality_controlstring图片质量控制 NONE: 不进行控制 LOW:较低的质量要求 NORMAL: 一般的质量要求 HIGH: 较高的质量要求 默认 NONE
liveness_controlstring活体检测控制 NONE: 不进行控制 LOW:较低的活体要求(高通过率 低攻击拒绝率) NORMAL: 一般的活体要求(平衡的攻击拒绝率, 通过率) HIGH: 较高的活体要求(高攻击拒绝率 低通过率) 默认NONE

返回参数

参数名必选类型说明
scorefloat人脸相似度得分
face_listarray人脸信息列表
+face_tokenstring人脸的唯一标志

 

3.请求示例(v3版本)

请求示例

(1)HTTP方法:POST

(2)请求URL: https://aip.baidubce.com/rest/2.0/face/v3/match

(3)URL参数:

参数
access_token通过API Key和Secret Key获取的access_token,参考“Access Token获取

Header:

参数
Content-Typeapplication/x-www-form-urlencoded

完整的请求url如下:

request_url = "https://aip.baidubce.com/rest/2.0/face/v3/match?access_token=" + access_token

 

二.算法思路

1.首先根据自己的API Key和Secret Key获取对应的access_token,将access_token添加到请求url参数中。

2.将要进行对比的两张图片分别经过Base64编码成一串字符串,使用该字符串代替图像地址。需要注意的是,图片的base64编码是不包含图片头的。如data:image/jpg;base64,

3.构建要传入request请求中的json格式的数据。

4.发送post请求,返回响应结果。

 

具体过程:

1.首先根据自己的API Key和Secret Key获取对应的access_token,将access_token添加到请求url参数中。

# encoding:utf-8
import requests

# 将API_KEY和SECRET_KEY分别替换成自己的
API_KEY = 'bIK................'
SECRET_KEY = 'oCb................'

# client_id 为官网获取的AK, client_secret 为官网获取的SK
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + API_KEY + '&client_secret=' + SECRET_KEY
response = requests.get(host)
if response:
    print(response.json())


######## 输出结果 #########
"""
{
'refresh_token': 'xxxxxxx', 
'expires_in': 2592000, 
'session_key': 'xxxxxxx', 
'access_token': 'xxxxxxx', 
'scope': 'xxxxxxx'
}
"""
###########################

可以看到输出结果是一个字典,而 ‘access_token’ 即为需要的值所对应的键,故我们可通过response.json()[‘access_token’]进行获取。

 

2.将要进行对比的两张图片分别经过Base64编码成一串字符串,使用该字符串代替图像地址。需要注意的是,图片的base64编码是不包含图片头的。如data:image/jpg;base64,

filename1 = '1.jpg'
img1 = cv.imread(filename1)
f1 = open(filename1, 'rb')
img_1 = base64.b64encode(f1.read())

filename2 = '2.jpg'
img2 = cv.imread(filename2)
f2 = open(filename2, 'rb')
img_2 = base64.b64encode(f2.read())

print(str(img_1, 'utf-8'))
print(str(img_2, 'utf-8'))

通过上述代码即可得到图片对应的Base64编码,可以将其封装成一个函数:

def pic2base64(filename):
    """
    读取文件对应的图片,将其经过Base64编码成不带图片头的字符串代替图像地址。
    - 请求的图片需经过Base64编码,图片的base64编码指将图片数据编码成一串字符串,使用该字符串代替图像地址。
    - 需要注意的是,图片的base64编码是不包含图片头的,如data:image/jpg;base64
    :param filename:
    :return:
    """
    img = cv.imread(filename)
    f = open(filename, 'rb')
    res_img = base64.b64encode(f.read())
    return str(res_img, 'utf-8')

 

3.构建要传入request请求中的json格式的数据。

# pic_1和pic_2分别是Base64编码后的字符串
pic_1 = pic2base64(filename1)
pic_2 = pic2base64(filename2)


access_token = 'xxxxxxxxxxx'   # 根据自己获取的access_token
# 构建请求url
request_url = "https://aip.baidubce.com/rest/2.0/face/v3/match?access_token=" + access_token

# 构建headers,作为post的headers参数
headers = {
    'Content-Type': 'application/x-www-form-urlencoded'
}

# 构建json类型的数据,作为post请求的data参数
params = "[" \
         "{\"image\": \"%s\", " \
         "\"image_type\": \"BASE64\", " \
         "\"face_type\": \"LIVE\", " \
         "\"quality_control\": \"LOW\"}," \
         "{\"image\": \"%s\", " \
         "\"image_type\": \"BASE64\", " \
         "\"face_type\": \"LIVE\", " \
         "\"quality_control\": \"LOW\"}" \
         "]" % (pic_1, pic_2)

 

4.发送post请求,返回响应结果。

# 发起POST请求
resp = requests.post(url=request_url, data=params, headers=headers)

# 打印返回的响应信息
if resp:
    res_json = resp.json()
    print(res_json)



########## 输出结果 ###############
"""
{
    'error_code': 0, 
    'error_msg': 'SUCCESS', 
    'log_id': 7999899975001, 
    'timestamp': 1592787625, 
    'cached': 0, 
    'result': {
        'score': 36.03727722, 
        'face_list': [
            {'face_token': '5d4ad1f83294b6f5c6efa972bb9680d0'}, 
            {'face_token': '87193c64392d230cffc53f56b8d9f83c'}
        ]
    }
}

"""

故我们可以通过判断错误信息是否为SUCCESS,是则打印出最终的score;否则打印出错误信息。

resp = requests.post(url=request_url, data=params, headers=headers)

if resp:
    res_json = resp.json()
    print(res_json)
    error_msg = res_json['error_msg']
    if error_msg != 'SUCCESS':
        print("错误信息: ", error_msg)
    else:
        res_score = res_json['result']['score']
        print("最终的得分是:", res_score)

 

三.完整代码

import requests
import base64
import cv2 as cv

API_KEY = 'bIKRsY3ZQuYhby4jg0Z4QwDQ'
SECRET_KEY = 'oCbEN6p39hGvv5QDUcjuI8hFaRfM9iCx'


# client_id 为官网获取的AK, client_secret 为官网获取的SK
def get_access_token(API_KEY, SECRET_KEY):
    """
    根据API_KEY和SECRET_KEY构造url请求,获取access_token
    :param API_KEY:
    :param SECRET_KEY:
    :return:
    """
    host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + API_KEY + '&client_secret=' + SECRET_KEY
    response = requests.get(host)
    if response:
        return response.json()['access_token']
    else:
        return None


def pic2base64(filename):
    """
    读取文件对应的图片,将其经过Base64编码成不带图片头的字符串代替图像地址。
    - 请求的图片需经过Base64编码,图片的base64编码指将图片数据编码成一串字符串,使用该字符串代替图像地址。
    - 需要注意的是,图片的base64编码是不包含图片头的,如data:image/jpg;base64
    :param filename:
    :return:
    """
    img = cv.imread(filename)
    f = open(filename, 'rb')
    res_img = base64.b64encode(f.read())
    return str(res_img, 'utf-8')


# 将要比较的文件进行Base64编码成字符串
filename1 = 'James.jpg'
filename2 = 'wade.jpg'
pic_1 = pic2base64(filename1)
pic_2 = pic2base64(filename2)

# 获取access_token
access_token = get_access_token(API_KEY, SECRET_KEY)

# 若access_token不为空,则进行请求
if access_token is not None:
    request_url = "https://aip.baidubce.com/rest/2.0/face/v3/match?access_token=" + access_token
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }

    params = "[" \
             "{\"image\": \"%s\", " \
             "\"image_type\": \"BASE64\", " \
             "\"face_type\": \"LIVE\", " \
             "\"quality_control\": \"LOW\"}," \
             "{\"image\": \"%s\", " \
             "\"image_type\": \"BASE64\", " \
             "\"face_type\": \"LIVE\", " \
             "\"quality_control\": \"LOW\"}" \
             "]" % (pic_1, pic_2)

    resp = requests.post(url=request_url, data=params, headers=headers)

    # 若返回响应,则读取响应,判断是否有错误,有则打印错误信息,否则输出最终得分
    if resp:
        res_json = resp.json()
        error_msg = res_json['error_msg']
        if error_msg != 'SUCCESS':
            print("错误信息: ", error_msg)
        else:
            res_score = res_json['result']['score']
            print("最终的得分是:", res_score)

 

四.实现效果

图片说明:以下两张分别是wade.jpg和James.jpg,位于代码同级目录下。

《使用百度AI接口v3进行人脸对比》        《使用百度AI接口v3进行人脸对比》

结果:

最终的得分是: 36.03727722

点赞