前言:
折腾了一晚上,有感于百度支持文档尚未完全兼容Python3,和笔记本续航不行。彻底搞懂之后,在这里写一个小例子,方便大家参考调试。
一:首先,先说几个大家关注的方面:
报错信息整理,比官方文档更全面的小站:http://aixiaoshuai.mydoc.io/
222209 |
face token not exist |
face_token不存在 1.请检查确认face_token是否正确 2.请检查image_type参数值是否为FACE_TOKEN 3.请确认image参数填写的值为face_token 如果为图片的base64数据,则image_type参数值是BASE64 |
param参数中的[image_type]建议用BASE64,这是最省事的办法。这篇教程以此为基础展开。
转换常见图片格式至BASE64方法:
def img_to_BASE64(slef,path):
with open(path,'rb') as f:
base64_data = base64.b64encode(f.read())
return base64_data
获取Access_TOKEN方法:
def get_accessToken(self):
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + self.AK + '&client_secret=' + self.SK
response = requests.get(host, headers=self.headers)
json_result = json.loads(response.text)
return json_result['access_token']
注意:access_token
的有效期为30天,切记需要每30天进行定期更换,或者每次请求都拉取新token;
笔者实际操作中,采取每次请求都拉取新token。优点你懂。
获取过程中可能遇到的问题解释:
invalid_clientunknown client id API Key不正确
invalid_clientClient authentication failed Secret Key不正确
在Python 3里,我们这样定义一个结构,这里与官方文档不同:
#典型结构sample,不需要加\
sample = {"image":"test.JPG","image_type":"FACE_TOKEN","face_field":"faceshape,facetype"}
二:API调用
字段 | 必选 | 类型 | 说明 |
---|---|---|---|
face_num | 是 | int | 检测到的图片中的人脸数量 |
face_list | 是 | array | 人脸信息列表,具体包含的参数参考下面的列表。 |
+face_token | 是 | string | 人脸图片的唯一标识 |
+location | 是 | array | 人脸在图片中的位置 |
++left | 是 | double | 人脸区域离左边界的距离 |
++top | 是 | double | 人脸区域离上边界的距离 |
++width | 是 | double | 人脸区域的宽度 |
++height | 是 | double | 人脸区域的高度 |
++rotation | 是 | int64 | 人脸框相对于竖直方向的顺时针旋转角,[-180,180] |
+face_probability | 是 | double | 人脸置信度,范围【0~1】,代表这是一张人脸的概率,0最小、1最大。 |
+angel | 是 | array | 人脸旋转角度参数 |
++yaw | 是 | double | 三维旋转之左右旋转角[-90(左), 90(右)] |
++pitch | 是 | double | 三维旋转之俯仰角度[-90(上), 90(下)] |
++roll | 是 | double | 平面内旋转角[-180(逆时针), 180(顺时针)] |
+age | 否 | double | 年龄 ,当face_field包含age时返回 |
+beauty | 否 | int64 | 美丑打分,范围0-100,越大表示越美。当face_fields包含beauty时返回 |
+expression | 否 | array | 表情,当 face_field包含expression时返回 |
++type | 否 | string | none:不笑;smile:微笑;laugh:大笑 |
++probability | 否 | double | 表情置信度,范围【0~1】,0最小、1最大。 |
+face_shape | 否 | array | 脸型,当face_field包含face_shape时返回 |
++type | 否 | double | square: 正方形 triangle:三角形 oval: 椭圆 heart: 心形 round: 圆形 |
++probability | 否 | double | 置信度,范围【0~1】,代表这是人脸形状判断正确的概率,0最小、1最大。 |
+gender | 否 | array | 性别,face_field包含gender时返回 |
++type | 否 | string | male:男性 female:女性 |
++probability | 否 | double | 性别置信度,范围【0~1】,0代表概率最小、1代表最大。 |
+glasses | 否 | array | 是否带眼镜,face_field包含glasses时返回 |
++type | 否 | string | none:无眼镜,common:普通眼镜,sun:墨镜 |
++probability | 否 | double | 眼镜置信度,范围【0~1】,0代表概率最小、1代表最大。 |
+eye_status | 否 | array | 双眼状态(睁开/闭合) face_field包含eye_status时返回 |
++left_eye | 否 | double | 左眼状态 [0,1]取值,越接近0闭合的可能性越大 |
++right_eye | 否 | double | 右眼状态 [0,1]取值,越接近0闭合的可能性越大 |
+emotion | 否 | array | 情绪 face_field包含emotion时返回 |
++type | 否 | string | angry:愤怒 disgust:厌恶 fear:恐惧 happy:高兴 sad:伤心 surprise:惊讶 neutral:无情绪 |
++probability | 否 | double | 情绪置信度,范围0~1 |
+race | 否 | array | 人种 face_field包含race时返回 |
++type | 否 | string | yellow: 黄种人 white: 白种人 black:黑种人 arabs: 阿拉伯人 |
++probability | 否 | double | 人种置信度,范围【0~1】,0代表概率最小、1代表最大。 |
+face_type | 否 | array | 真实人脸/卡通人脸 face_field包含face_type时返回 |
++type | 否 | string | human: 真实人脸 cartoon: 卡通人脸 |
++probability | 否 | double | 人脸类型判断正确的置信度,范围【0~1】,0代表概率最小、1代表最大。 |
+landmark | 否 | array | 4个关键点位置,左眼中心、右眼中心、鼻尖、嘴中心。face_field包含landmark时返回 |
+landmark72 | 否 | array | 72个特征点位置 face_field包含landmark72时返回 |
+landmark150 | 否 | array | 150个特征点位置 face_field包含landmark150时返回 |
+quality | 否 | array | 人脸质量信息。face_field包含quality时返回 |
++occlusion | 否 | array | 人脸各部分遮挡的概率,范围[0~1],0表示完整,1表示不完整 |
+++left_eye | 否 | double | 左眼遮挡比例,[0-1] ,1表示完全遮挡 |
+++right_eye | 否 | double | 右眼遮挡比例,[0-1] , 1表示完全遮挡 |
+++nose | 否 | double | 鼻子遮挡比例,[0-1] , 1表示完全遮挡 |
+++mouth | 否 | double | 嘴巴遮挡比例,[0-1] , 1表示完全遮挡 |
+++left_cheek | 否 | double | 左脸颊遮挡比例,[0-1] , 1表示完全遮挡 |
+++right_cheek | 否 | double | 右脸颊遮挡比例,[0-1] , 1表示完全遮挡 |
+++chin | 否 | double | 下巴遮挡比例,,[0-1] , 1表示完全遮挡 |
++blur | 否 | double | 人脸模糊程度,范围[0~1],0表示清晰,1表示模糊 |
++illumination | 否 | double | 取值范围在[0~255], 表示脸部区域的光照程度 越大表示光照越好 |
++completeness | 否 | int64 | 人脸完整度,0或1, 0为人脸溢出图像边界,1为人脸都在图像边界内 |
返回的文件,它的结构是这个样子(示例):
{
"face_num": 1,
"face_list": [
{
"face_token": "35235asfas21421fakghktyfdgh68bio",
"location": {
"left": 117,
"top": 131,
"width": 172,
"height": 170,
"rotation": 4
},
"face_probability": 1,
"angle" :{
"yaw" : -0.34859421849251
"pitch" 1.9135693311691
"roll" :2.3033397197723
}
"landmark": [
{
"x": 161.74819946289,
"y": 163.30244445801
},
...
],
"landmark72": [
{
"x": 115.86531066895,
"y": 170.0546875
},
...
],
"age": 29.298097610474,
"beauty": 55.128883361816,
"expression": {
"type": "smile",
"probability" : 0.5543018579483
},
"gender": {
"type": "male",
"probability": 0.99979132413864
},
"glasses": {
"type": "sun",
"probability": 0.99999964237213
},
"race": {
"type": "yellow",
"probability": 0.99999976158142
},
"face_shape": {
"type": "triangle",
"probability": 0.5543018579483
}
"quality": {
"occlusion": {
"left_eye": 0,
"right_eye": 0,
"nose": 0,
"mouth": 0,
"left_cheek": 0.0064102564938366,
"right_cheek": 0.0057411273010075,
"chin": 0
},
"blur": 1.1886881756684e-10,
"illumination": 141,
"completeness": 1
}
}
]
}
上传到这里就OK了,将持续更新热门的问题。如果你按照这个方式获取不到数据包,私信我。
由以上数据结构,我们这样解析获取到的数据包:
#定义接收到的包为json_result
print(json_result['result']['face_list'][0]['age'])#显示年龄
废话不多说,全部代码:
#encoding:UTF-8
#
#realkris
#Last modified: 2.13.2019 by realkris
#
import base64
import json
import requests
class BaiduPicIndentify:
def __init__(self,img):
self.AK = "你的AK"
self.SK = "你的SK"
self.img_src = img
self.headers = {
"Content-Type": "application/json; charset=UTF-8"
}
def get_accessToken(self):
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + self.AK + '&client_secret=' + self.SK
response = requests.get(host, headers=self.headers)
json_result = json.loads(response.text)
return json_result['access_token']
def img_to_BASE64(slef,path):
with open(path,'rb') as f:
base64_data = base64.b64encode(f.read())
return base64_data
def detect_face(self):
# 人脸检测与属性分析
img_BASE64 = self.img_to_BASE64(self.img_src)
request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"
post_data = {
"image": img_BASE64,
"image_type": "BASE64",
"face_field": "gender,age,beauty,gender,race,expression,emotion",
"face_type": "LIVE"
}
access_token = self.get_accessToken()
request_url = request_url + "?access_token=" + access_token
response = requests.post(url=request_url, data=post_data, headers=self.headers)
json_result = json.loads(response.text)
if json_result['error_msg']!='pic not has face':
print("图片中包含", json_result['result']['face_num'],"张脸")
print("估计年龄:", json_result['result']['face_list'][0]['age'])
print("颜值评分:", json_result['result']['face_list'][0]['beauty'])
if __name__=='__main__':
img_src=input('本地图片名:')
baiduDetect = BaiduPicIndentify(img_src)
baiduDetect.detect_face()
示例返回:
虽然效果并没达到笔者的用途预期。不过还是挺值得一试的。