前几天在CSDN看到博主 快乐的√4 使用python调用百度人脸检测API的文章,链接如下: https://blog.csdn.net/qq_44809707/article/details/110430370

根据百度AI平台官方文档,只提供了PHP、JAVA、Python等调用方法,出于好奇,决定尝试使用R来实现一下,具体方法将在一下文章中完成。

实现过程

1. 到百度智能云平台申请密钥

链接:https://ai.baidu.com/

或直接登录到控制台:https://console.bce.baidu.com/

  • 在控制台右侧边栏中找到人脸识别
  • 创建应用

  • 创建应用后,图中的API Key 和 Secret Key后面将要用到。

2. R代码实现

语言:R语言

平台:Rstudio

所需包:httr、base64enc

必读官方文档:

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中的请求参数如下,可根据自己需求自定义:

请求参数

参数必选类型说明
imagestring图片信息(总数据大小应小于10M),图片上传方式根据image_type来判断
image_typestring图片类型BASE64:图片的base64值,base64编码后的图片数据,编码后的图片大小不超过2M; URL:图片的 URL地址( 可能由于网络等原因导致下载图片时间过长); FACE_TOKEN: 人脸图片的唯一标识,调用人脸检测接口时,会为每个人脸图片赋予一个唯一的FACE_TOKEN,同一张图片多次检测得到的FACE_TOKEN是同一个。
face_fieldstring包括age,beauty,expression,face_shape,gender,glasses,landmark,landmark150, quality,eye_status,emotion,face_type,mask,spoofing信息 逗号分隔. 默认只返回face_token、人脸框、概率和旋转角度
max_face_numuint32最多处理人脸的数目,默认值为1,根据人脸检测排序类型检测图片中排序第一的人脸(默认为人脸面积最大的人脸),最大值120
face_typestring人脸的类型LIVE表示生活照:通常为手机、相机拍摄的人像图片、或从网络获取的人像图片等 IDCARD表示身份证芯片照:二代身份证内置芯片中的人像照片 WATERMARK表示带水印证件照:一般为带水印的小图,如公安网小图 CERT表示证件照片:如拍摄的身份证、工卡、护照、学生证等证件图片 默认LIVE
liveness_controlstring活体控制 检测结果中不符合要求的人脸会被过滤 NONE: 不进行控制 LOW:较低的活体要求(高通过率 低攻击拒绝率) NORMAL: 一般的活体要求(平衡的攻击拒绝率, 通过率) HIGH: 较高的活体要求(高攻击拒绝率 低通过率) 默认NONE
face_sort_typeint人脸检测排序类型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)
}

最终输出类似结果下图:

测试下明星的颜值

  1. 杨幂

结果如下:

  1. 邓论

结果如下:

注意:以上得到的结果来自于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 国际许可协议 进行许可,转载须给出适当的署名,提供指向本许可协议的链接,同时标明是否(对原始作品)作了修改。


最后修改:2021 年 03 月 21 日 10 : 56 PM
如果觉得我的文章对你有用,请随意赞赏