人脸识别实战教程
本教程介绍如何使用Alibaba Cloud SDK for Java进行人体属性识别、人体计数和人脸搜索任务。
背景信息
人脸人体识别技术是基于阿里云深度学习算法,结合图像或视频的人脸检测、分析、比对以及人体检测等技术,为您提供人脸人体的检测定位、人脸属性识别和人脸比对等能力。可以为开发者和企业提供高性能的在线API服务,应用于人脸AR、人脸识别和认证、大规模人脸检索、照片管理等各种场景。
前提条件
在开始之前,请确保完成以下步骤:
- 开通人脸人体能力,请参见上述开发前准备。
- 在您的Java工程中添加人脸人体能力的pom依赖:
<!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-facebody -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-facebody</artifactId>
<version>1.0.8</version>
</dependency>
人脸属性识别
RecognizeFace可以识别检测人脸的性别、年龄、表情、眼镜四种属性。返回人脸的1024维深度学习特征,基于这个特征并按照特征比较规则,您可实现高性能的人脸识别。
例如需要识别以下图片中的人脸属性。
示例代码如下:
import com.aliyun.CommonConfig;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.facebody.model.v20191230.RecognizeFaceRequest;
import com.aliyuncs.facebody.model.v20191230.RecognizeFaceResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;
public class RecognizeFaceDemo {
private static DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai", "<access key id>", "<access key secret>");
private static IAcsClient client = new DefaultAcsClient(profile);
public static void main(String[] args) {
String recognizeFaceURL = "https://visionapi-test.oss-cn-shanghai.aliyuncs.com/recognize_1.jpg";
recognizeFace(recognizeFaceURL);
}
/**
* 人脸属性识别
* @param imageURL 图片URL地址
*/
private static void recognizeFace(String imageURL)
{
RecognizeFaceRequest recognizeFaceRequest = new RecognizeFaceRequest();
recognizeFaceRequest.setImageURL(imageURL);
try {
RecognizeFaceResponse recognizeFaceResponse = client.getAcsResponse(recognizeFaceRequest);
System.out.println("人脸属性识别:");
System.out.println(new Gson().toJson(recognizeFaceResponse));
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
}
}
代码返回结果类似如下:
{
"requestId": "9E461AFC-B125-4B04-8644-4D39C495B61A",
"data": {
"faceCount": 1,
"landmarkCount": 105,
"denseFeatureLength": 1024,
"faceRectangles": [
604,
124,
128,
160
],
"faceProbabilityList": [
55.0
],
"poseList": [
-8.399615,
-10.90538,
14.451606
],
"landmarks": [
614.1295,
161.77643,
647.84894,
...
],
"pupils": [
637.25793,
177.63129,
5.2395487,
689.71075,
192.1905,
5.2395487
],
"genderList": [
0
],
"ageList": [
24
],
"expressions": [
1
],
"glasses": [
1
],
"denseFeatures": [
"-0.0080740926787257195",
"0.011421392671763897",
"-0.027754634618759155",
...
]
}
}
从返回结果中得到的该图片人脸属性识别结果如下:
- 人脸个数:1
- 性别:女性
- 年龄:24
- 是否微笑:微笑
- 是否戴眼镜:有眼镜
人体计数
DetectBodyCount可以检测输入图片中人体的个数。
待检测图片如下:
示例代码如下:
import com.aliyun.CommonConfig;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.facebody.model.v20191230.DetectBodyCountRequest;
import com.aliyuncs.facebody.model.v20191230.DetectBodyCountResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;
/**
* 人体计数
*/
public class DetectBodyCountDemo {
private static DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai", "<access key id>", "<access key secret>");
private static IAcsClient client = new DefaultAcsClient(profile);
public static void main(String[] args) {
String detectBodyCountURL = "https://visionapi-test.oss-cn-shanghai.aliyuncs.com/multiplayer.jpg";
detectBodyCount(detectBodyCountURL);
}
/**
* 人体计数
* @param imageURL 图片URL地址
*/
private static void detectBodyCount(String imageURL)
{
DetectBodyCountRequest detectBodyCountRequest = new DetectBodyCountRequest();
detectBodyCountRequest.setImageURL(imageURL);
try {
DetectBodyCountResponse detectBodyCountResponse = client.getAcsResponse(detectBodyCountRequest);
System.out.println("人体计数:");
System.out.println(new Gson().toJson(detectBodyCountResponse));
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
}
}
代码返回结果类似如下:
{
"requestId": "15170328-DF69-4F24-900D-9915645A4237",
"data": {
"personNumber": 3
}
}
从返回结果中得到该图片被检测到有3个人。
人脸搜索
人脸搜索可以根据输入图片,在数据库中搜索相似的人脸图片数据。
人脸搜索操作流程示意图如下:
说明: 公测阶段每个阿里云主账号只能创建一个数据库,且开通服务后默认创建一个名称为default的数据库,每个数据库最多可以添加5万张图片。
涉及的API如下:
例如我们有以下人脸数据:
将上面图片样本加入人脸库,使用下面人脸数据搜索人脸库。
示例代码如下:
import com.aliyun.CommonConfig;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.facebody.model.v20191230.*;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;
public class SearchFaceDemo {
private static DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai", CommonConfig.ACCESSKEY_ID, CommonConfig.ACCESSKEY_SECRET);
private static IAcsClient client = new DefaultAcsClient(profile);
public static void main(String[] args) throws InterruptedException {
String dbName = "default";
String human1_1 = "https://visionapi-test.oss-cn-shanghai.aliyuncs.com/human_11.jpg";
String human1_2 = "https://visionapi-test.oss-cn-shanghai.aliyuncs.com/human_12.jpg";
String human2_1 = "https://visionapi-test.oss-cn-shanghai.aliyuncs.com/human_21.jpg";
String human2_2 = "https://visionapi-test.oss-cn-shanghai.aliyuncs.com/human_22.jpg";
String sample = "https://visionapi-test.oss-cn-shanghai.aliyuncs.com/sample.jpg";
String entityId1 = "human1";
String entityId2 = "human2";
// 1.创建人脸样本
addFaceEntity(dbName, entityId1);
addFaceEntity(dbName, entityId2);
// 2.向人脸样本中加入人脸,每个样本人脸上限为5
addFace(dbName,entityId1,human1_1);
addFace(dbName,entityId1,human1_2);
addFace(dbName,entityId2,human2_1);
addFace(dbName,entityId2,human2_2);
Thread.currentThread().sleep(3000);
// 3.到人脸库中查找
searchFace(dbName,sample,1);
}
/**
* 添加人脸样本
* @param dbName 数据库名称
* @param entityId 实体ID
*/
private static void addFaceEntity(String dbName, String entityId)
{
AddFaceEntityRequest addFaceEntityRequest = new AddFaceEntityRequest();
addFaceEntityRequest.setDbName(dbName);
addFaceEntityRequest.setEntityId(entityId);
try{
AddFaceEntityResponse addFaceEntityResponse = client.getAcsResponse(addFaceEntityRequest);
System.out.println("添加人脸样本:");
System.out.println(new Gson().toJson(addFaceEntityResponse));
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
}
/**
* 添加人脸数据
* @param dbName 数据库名称
* @param entityId 实体ID
* @param imageUrl 人脸图片地址,必须是同Region的OSS的图片地址。人脸必须是正面无遮挡单人人脸。
*/
private static void addFace(String dbName, String entityId, String imageUrl)
{
AddFaceRequest addFaceRequest = new AddFaceRequest();
addFaceRequest.setDbName(dbName);
addFaceRequest.setEntityId(entityId);
addFaceRequest.setImageUrl(imageUrl);
try{
AddFaceResponse addFaceResponse = client.getAcsResponse(addFaceRequest);
System.out.println("添加人脸数据:");
System.out.println(new Gson().toJson(addFaceResponse));
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
}
/**
* 搜索人脸
* @param dbName 数据库名称
* @param imageUrl 图片URL地址。必须是同Region的OSS地址。
*/
private static void searchFace(String dbName, String imageUrl, Integer limit)
{
SearchFaceRequest searchFaceRequest = new SearchFaceRequest();
searchFaceRequest.setDbName(dbName);
searchFaceRequest.setImageUrl(imageUrl);
searchFaceRequest.setLimit(limit);
try{
SearchFaceResponse searchFaceResponse = client.getAcsResponse(searchFaceRequest);
System.out.println("搜索人脸:");
System.out.println(new Gson().toJson(searchFaceResponse));
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
}
}
返回结果类似如下:
添加人脸样本:
{"requestId":"718AE1B9-F1B3-4720-98FA-69E2A41F4C31"}
添加人脸样本:
{"requestId":"9CE55AD1-1E21-49F0-BB2C-B3C07A015EAE"}
添加人脸数据:
{"requestId":"9551C7C7-8027-4E82-82FB-15FEC0EB8161","data":{"faceId":"1589791311965000"}}
添加人脸数据:
{"requestId":"C193A2E0-F22A-4418-AAD3-F28749BDDC17","data":{"faceId":"1589791312203000"}}
添加人脸数据:
{"requestId":"687D9D8B-5EDE-4774-B377-C1CB4E0FB855","data":{"faceId":"1589791312433000"}}
添加人脸数据:
{"requestId":"1E0948E3-7D75-4709-A624-073B4CB54874","data":{"faceId":"1589791312679000"}}
搜索人脸:
{
"requestId": "F0543F2A-216F-495A-8B4D-20CA06B605A7",
"data": {
"matchList": [
{
"faceItems": [
{
"faceId": "1589791312203000",
"score": 0.86908734,
"extraData": "",
"entityId": "human1"
}
],
"location": {
"x": 592,
"y": 132,
"width": 152,
"height": 204
}
}
]
}
}
从返回结果中得出输入图片:
- 被匹配到的样本数据faceId为1589791312203000。
- 匹配到的样本名称为human1。
- 与样本数据相似度为0.86908734。