前几天在CSDN看到博主 快乐的√4 使用python调用百度人脸检测API的文章,链接如下: https://blog.csdn.net/qq_44809707/article/details/110430370
根据百度AI平台官方文档,只提供了PHP、JAVA、Python等调用方法,出于好奇,决定尝试使用R来实现一下,具体方法将在一下文章中完成。
实现过程
1. 到百度智能云平台申请密钥
或直接登录到控制台:https://console.bce.baidu.com/
- 在控制台右侧边栏中找到人脸识别
- 创建应用
- 创建应用后,图中的API Key 和 Secret Key后面将要用到。
2. R代码实现
语言:R语言
平台:Rstudio
所需包:httr、base64enc
必读官方文档:
- 鉴权认证机制(获取Access Token) https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhu
- 人脸检测:https://ai.baidu.com/ai-doc/FACE/yk37c1u4t
1. 获取Access Token
根据官方文档说明,我们将使用以下URL来,POST请求来获得Access Token。
找到百度API官网刚才记下来的API Key 和 Secret Key,并使用readline命令储存到以下两个值中。然后拼接API key 和 Secret Key到URL中。
api_key <- readline(prompt = "Please paste the API Key: ")
secret_key <- readline(prompt = "Please paste the Secret Key: ")
url1 <- paste0("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=", api_key, "&client_secret=", secret_key)
获取Access Token
library(httr) # 加载所需包,若没有请用install.packages("httr")安装
response <- POST(url = url1) # 记录返回值
根据以上文档截图,服务器讲返回JSON文本,并包含如图中的参数,为了方便读取,排除无用信息,我们使用httr包中的content()来读取JSON文本,返回值是一个list,我们将读取list中的access_token项,如下:
access_token <- content(response)$access_token # 储存access_token
2. 将你要上传分析的图片转为base64格式
由于文档要求,请求的图片需经过Base64编码,我们将使用base64enc包中的base64encode()来处理图片。
library(base64enc)
image_name <- readline("Please enter the image name (xxx.jpg/xxx.png): ")
img_base64 <- base64enc::base64encode(what = image_name)
3. 上传图片并取回数据
请求方法如文档所示:
Body中的请求参数如下,可根据自己需求自定义:
请求参数
参数 | 必选 | 类型 | 说明 | ||
---|---|---|---|---|---|
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,landmark150, quality,eye_status,emotion,face_type,mask,spoofing信息 逗号分隔. 默认只返回face_token、人脸框、概率和旋转角度 | ||
max_face_num | 否 | uint32 | 最多处理人脸的数目,默认值为1,根据人脸检测排序类型检测图片中排序第一的人脸(默认为人脸面积最大的人脸),最大值120 | ||
face_type | 否 | string | 人脸的类型LIVE表示生活照:通常为手机、相机拍摄的人像图片、或从网络获取的人像图片等 IDCARD表示身份证芯片照:二代身份证内置芯片中的人像照片 WATERMARK表示带水印证件照:一般为带水印的小图,如公安网小图 CERT表示证件照片:如拍摄的身份证、工卡、护照、学生证等证件图片 默认LIVE | ||
liveness_control | 否 | string | 活体控制 检测结果中不符合要求的人脸会被过滤 NONE: 不进行控制 LOW:较低的活体要求(高通过率 低攻击拒绝率) NORMAL: 一般的活体要求(平衡的攻击拒绝率, 通过率) HIGH: 较高的活体要求(高攻击拒绝率 低通过率) 默认NONE | ||
face_sort_type | 否 | int | 人脸检测排序类型0:代表检测出的人脸按照人脸面积从大到小排列 1:代表检测出的人脸按照距离图片中心从近到远排列 默认为0 |
说明:face_field参数,默认只返回人脸框、概率和旋转角度,age等更多属性,请在此参数中添加。
接下来,上传图片并取回数据
url2 <- url2 <- paste0("https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=", access_token) # 拼接请求URL和token
raw_data <- POST(url = url2, body = list(image = img_base64,
image_type = "BASE64",
face_field = "gender,age,beauty,gender,race,emotion,face_shape",
face_type = "LIVE"))
raw_data_2 <- content(raw_data) # 使用content读取返回的JSON
如果请求正确(error code 为 0),将得到类似如下的list:
4. 分析并输出有用数据
根据上面取得到raw data,我们将进一步读取和分析,取出有用的数据,并增加注解使输出值更便于理解。
# 添加if 判断 error code是否为0,返回error code和error msg
if (raw_data_2$error_code == 0) {
# 是人脸的概率
face_probability <- raw_data_2$result$face_list[[1]]$face_probability
cat("图片是人脸的概率:", face_probability*100, "%", "\n")
# 性别
gender <- raw_data_2$result$face_list[[1]]$gender
if (gender$type == "female") {
cat("性别:女 - 准确性:", gender[[2]]*100, "%", "\n")
} else if (gender$type == "male") {
cat("性别:男 - 准确性:", gender[[2]]*100, "%", "\n")
}
# 年龄预测
age <- raw_data_2$result$face_list[[1]]$age
cat("预测年龄为:", age, "\n")
# 人种肤色
race <- raw_data_2$result$face_list[[1]]$race$type
cat("预测人种肤色:", race, "\n")
# 预测心情·
emotion <- raw_data_2$result$face_list[[1]]$emotion
if (emotion$type == "angry") {
cat("预测心情:愤怒\n")
}
if (emotion$type == "disgust") {
cat("预测心情:厌恶\n")
}
if (emotion$type == "fear") {
cat("预测心情:恐惧\n")
}
if (emotion$type == "happy") {
cat("预测心情:高兴\n")
}
if (emotion$type == "sad") {
cat("预测心情:伤心 \n")
}
if (emotion$type == "surprise") {
cat("预测心情:惊讶 \n")
}
if (emotion$type == "neutral") {
cat("预测心情:中性,无表情\n")
}
if (emotion$type == "pouty") {
cat("预测心情:撅嘴\n")
}
if (emotion$type == "grimace") {
cat("预测心情:鬼脸\n")
}
# 颜值打分
beauty <- raw_data_2$result$face_list[[1]]$beauty
cat("颜值打分(0-100分):", beauty, "\n")
# 脸型判断
face_shape <- raw_data_2$result$face_list[[1]]$face_shape
if (face_shape$type == "square") {
cat("脸型:方脸\n")
}
if (face_shape$type == "triangle") {
cat("脸型:三角形\n")
}
if (face_shape$type == "oval") {
cat("脸型:椭圆\n")
}
if (face_shape$type == "heart") {
cat("脸型:心形\n")
}
if (face_shape$type == "round") {
cat("脸型:圆形\n")
}
} else {
cat("错误\n")
cat("Error Code:", raw_data_2$error_code, "\n")
cat("Error message:", raw_data_2$error_msg)
}
最终输出类似结果下图:
测试下明星的颜值
- 杨幂
结果如下:
- 邓论
结果如下:
注意:以上得到的结果来自于AI的算法,并不能保证完全准确性哦。另外,提高图片的清晰度似乎可以增加判断准确性。
完整代码
library(httr)
library(jsonlite)
library(base64enc)
# 输入API key 和 Secret Key
api_key <- readline(prompt = "Please paste the API Key: ")
secret_key <- readline(prompt = "Please paste the Secret Key: ")
# 拼接URL
url1 <- paste0("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=",
api_key, "&client_secret=", secret_key)
# 获取Access Token
response <- POST(url = url1)
access_token <- content(response)$access_token
# 将图片转换为base64格式
image_name <- readline("Please enter the image name (xxx.jpg/xxx.png): ")
library(base64enc)
img_base64 <- base64enc::base64encode(what = image_name)
# 上传图片并取回数据
url2 <- url2 <- paste0("https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=",
access_token) # 拼接请求URL和token
raw_data <- POST(url = url2, body = list(image = img_base64,
image_type = "BASE64",
face_field = "gender,age,beauty,gender,race,emotion,face_shape",
face_type = "LIVE"))
raw_data_2 <- content(raw_data) # 使用content读取返回的JSON
# 添加if 判断 error code是否为0,返回error code和error msg
if (raw_data_2$error_code == 0) {
# 是人脸的概率
face_probability <- raw_data_2$result$face_list[[1]]$face_probability
cat("图片是人脸的概率:", face_probability*100, "%", "\n")
# 性别
gender <- raw_data_2$result$face_list[[1]]$gender
if (gender$type == "female") {
cat("性别:女 - 准确性:", gender[[2]]*100, "%", "\n")
} else if (gender$type == "male") {
cat("性别:男 - 准确性:", gender[[2]]*100, "%", "\n")
}
# 年龄预测
age <- raw_data_2$result$face_list[[1]]$age
cat("预测年龄为:", age, "\n")
# 人种肤色
race <- raw_data_2$result$face_list[[1]]$race$type
cat("预测人种肤色:", race, "\n")
# 预测心情·
emotion <- raw_data_2$result$face_list[[1]]$emotion
if (emotion$type == "angry") {
cat("预测心情:愤怒\n")
}
if (emotion$type == "disgust") {
cat("预测心情:厌恶\n")
}
if (emotion$type == "fear") {
cat("预测心情:恐惧\n")
}
if (emotion$type == "happy") {
cat("预测心情:高兴\n")
}
if (emotion$type == "sad") {
cat("预测心情:伤心 \n")
}
if (emotion$type == "surprise") {
cat("预测心情:惊讶 \n")
}
if (emotion$type == "neutral") {
cat("预测心情:中性,无表情\n")
}
if (emotion$type == "pouty") {
cat("预测心情:撅嘴\n")
}
if (emotion$type == "grimace") {
cat("预测心情:鬼脸\n")
}
# 颜值打分
beauty <- raw_data_2$result$face_list[[1]]$beauty
cat("颜值打分(0-100分):", beauty, "\n")
# 脸型判断
face_shape <- raw_data_2$result$face_list[[1]]$face_shape
if (face_shape$type == "square") {
cat("脸型:方脸\n")
}
if (face_shape$type == "triangle") {
cat("脸型:三角形\n")
}
if (face_shape$type == "oval") {
cat("脸型:椭圆\n")
}
if (face_shape$type == "heart") {
cat("脸型:心形\n")
}
if (face_shape$type == "round") {
cat("脸型:圆形\n")
}
} else {
cat("错误\n")
cat("Error Code:", raw_data_2$error_code, "\n")
cat("Error message:", raw_data_2$error_msg)
}
版权属于:Zf's Blog(除特别注明外)
本文永久链接:https://blog.jeffhuang.xyz/index.php/archives/86/
本站文章采用 知识共享署名4.0 国际许可协议 进行许可,转载须给出适当的署名,提供指向本许可协议的链接,同时标明是否(对原始作品)作了修改。