Java使用百度人脸识别API攻略
程序员文章站
2022-07-12 18:39:45
...
1、首先在百度AI官网获取API Key、 Secret Key
创建新应用,即可免费自动获取。
强调一点:不要用我的API Key和Secrect Key!不要用我的API Key和Secrect Key!不要用我的API Key和Secrect Key!
2、查阅文档
https://cloud.baidu.com/doc/FACE/index.html
获取Java代码模板
创建获取token的类
package cn.tedu.chatBoardboot.faceDetect;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
import org.json.JSONObject;
/**
* 获取token类
*@author Edward
*@date 2020年6月21日---上午11:27:35
*/
public class AuthService {
/**
* 获取权限token
* @return 返回示例:
* {
* "access_token": "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567",
* "expires_in": 2592000
* }
*/
public static String getAuth() {
// 官网获取的 API Key 更新为你注册的
String clientId = "5IHjmjQEpo6G6xUL4XGlyp1z";
// 官网获取的 Secret Key 更新为你注册的
String clientSecret = "LOob7wI8xds3FfM1QxxYw9yT1Tv3IzKc";
return getAuth(clientId, clientSecret);
}
/**
* 获取API访问token
* 该token有一定的有效期,需要自行管理,当失效时需重新获取.
* @param ak - 百度云官网获取的 API Key
* @param sk - 百度云官网获取的 Securet Key
* @return assess_token 示例:
* "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
*/
public static String getAuth(String ak, String sk) {
// 获取token地址
String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
String getAccessTokenUrl = authHost
// 1. grant_type为固定参数
+ "grant_type=client_credentials"
// 2. 官网获取的 API Key
+ "&client_id=" + "5IHjmjQEpo6G6xUL4XGlyp1z"
// 3. 官网获取的 Secret Key
+ "&client_secret=" + "LOob7wI8xds3FfM1QxxYw9yT1Tv3IzKc";
try {
URL realUrl = new URL(getAccessTokenUrl);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.err.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String result = "";
String line;
while ((line = in.readLine()) != null) {
result += line;
}
/**
* 返回结果示例
*/
System.err.println("result:" + result);
JSONObject jsonObject = new JSONObject(result);
String access_token = jsonObject.getString("access_token");
return access_token;
} catch (Exception e) {
System.err.printf("获取token失败!");
e.printStackTrace(System.err);
}
return null;
}
}
两个key需要自行替换
创建人脸检测与属性分析的类:
package cn.tedu.chatBoardboot.faceDetect;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import org.springframework.stereotype.Component;
import cn.tedu.chatBoardboot.util.Base64Util;
import cn.tedu.chatBoardboot.util.GsonUtils;
import cn.tedu.chatBoardboot.util.HttpUtil;
/**
* 人脸检测与属性分析
*@author Edward
*@date 2020年6月21日---下午2:46:00
*/
@Component
public class FaceDetect {
/**
* 重要提示代码中所需工具类
* FileUtil,Base64Util,HttpUtil,GsonUtils请从
* https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
* https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
* https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
* https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
* 下载
*/
public static String faceDetect(String uri) {
// 请求url
String url = "https://aip.baidubce.com/rest/2.0/face/v3/detect";
// 测试成功! 先把Json回到页面上,看看如何处理。
File image = new File(uri);
ByteArrayOutputStream out = new ByteArrayOutputStream();
String Base64 = null;
try {
BufferedImage img = ImageIO.read(image);
ImageIO.write(img, "jpg", out);
byte[]bytes = out.toByteArray();
Base64=Base64Util.encode(bytes);
} catch (IOException e1) {
e1.printStackTrace();
}
try {
Map<String, Object> map = new HashMap<>();
map.put("image", Base64);
map.put("face_field", "age,beauty,expression,race,gender,glasses,emotion,face_type,mask");
map.put("image_type", "BASE64");
String param = GsonUtils.toJson(map);
// 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
String accessToken = AuthService.getAuth();
String result = HttpUtil.post(url, accessToken, "application/json", param);
System.out.println(result);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String uri = "C:\\Users\\Administrator\\Desktop\\sweet.jpg";
FaceDetect.faceDetect(uri);
}
}
工具类需要自己去百度指定网址下载并部署到本地项目中。
上面的image和image_type以及获取token的方法需要自行替换,imageType我这里是利用百度给的工具类将图片转换成BASE64格式来操作的,也可以自行在网上找类似工具转换。
到这里就可以获取到百度返回的json数据了。
3、通过页面上传的图片地址,调用faceDetect()方法获取json结果,并返回给页面
这里有个坑,百度回给的json数据是字符串格式的,所以在前端页面需要将其转换成json对象再处理,而且这个json数据有个大坑,就是face_list里面其实只有一个元素,因此代码如下:
$("#btn-beauty").click(function() {
$.ajax({
"url" : "/users/file/beauty",
//文件上传的指定格式
//js和jq混用时,jq对象需要从数组变回单元素
"data" : new FormData($("#form-beauty")[0]),
//后两个属性表示,在前端不做处理
"contentType":false,
"processData":false,
"type" : "post",
"dataType" : "json",
"success" : function(json) {
if (json.state == 2000) {
//前端jq无法读出face_list Cannot read property 'face_list' of undefined 放弃,后端完成
//与下划线无关,timestamp也提取不出来
//情况不太一样,之前传过来的就是List但是这次传过来就是字符串
alert("data:"+json.data)
//转换成json对象
var obj = JSON.parse(json.data)
alert("error_msg:"+obj.error_msg)
//转换成功了,可以得到error_msg,但是Cannot read property 'beauty' of undefined
var face_list = obj.result.face_list
//转换成String输出
alert("face_list:"+JSON.stringify(face_list))
//face_list也拿到了
var beauty = obj.result.face_list[0].beauty
alert("beauty:"+JSON.stringify(beauty))
var age = obj.result.face_list[0].age
alert("age:"+JSON.stringify(age))
var race = obj.result.face_list[0].race.type
alert("race:"+JSON.stringify(race))
//终于搞出来了,百度这个api给的face_list居然只有一项
}else{
alert(json.message)
}
},
//当服务器响应时,只要HTTP响应码不是2xx,就会执行error
"error": function(){
alert("你的登录信息已过期,请重新登录! \n\n*注意:开发阶段,看到当前提示时,应该及时检查浏览器的Console和Network面板的信息,以确定出现错误的真正原因! ")
location.href="/web/login.html"
}
});
弄了几个小时才弄好,希望后人少进坑。
PS:
不要尝试在后端对json进行处理了,fastjson(Springboot自带)和Gson同在的时候会有冲突 会报错:.concurrent.ThreadPoolTaskExecutor
@Test
public void aaa() {
String uri = "C:\\Users\\Administrator\\Desktop\\sweet.jpg";
String result = FaceDetect.faceDetect(uri);
System.err.println(result);
JsonParser parser = new JsonParser();
JsonObject object = (JsonObject) parser.parse(result);
System.err.println(object.get("error_code").getAsString());
// 先不纠结了,就这样吧,fastjson和Gson同在的时候会有冲突 .concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
}
上一篇: Nginx---反向代理