开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
未来项目可能需要使用人脸识别相关技术,所以今天做一下技术储备.
人脸识别说的比较高大上,其实背后就是一个机器学习训练出来的模型,如果有条件,可以尝试自己训练一个模型,如果没有条件,就可以像本文一样,调用一些平台开放出来的技术能力.
我们本次体验的是阿里云的人脸识别技术,截至本篇文档发布,阿里云的人脸人体能力还是免费,后续可能需要收费.
贴一个地址: vision.console.aliyun.com/cn-shanghai…
准备
- 阿里云开通人脸人体能力,链接在上面(免费)
- 阿里云新建RAM账户,授予AliyunVIAPIFullAccess权限(视觉管理api全部权限) ram.console.aliyun.com/users
-
- RAM账号较为安全,官网建议使用子账户.
- 阿里云OSS服务,作为文件上传存储介质(收费,体验免费)
流程简述
人脸识别的基本流程如下:
- 创建人脸数据库(个人账号最多创建1000个人脸数据库,最多100w张人脸)
- 上传人脸样本,也就是将来要搜索的人脸数据
- 调用人脸查询接口,传递要查询的图片,返回查询结果
那么oss在这里起到的作用是什么呢? 这是因为阿里云的人脸识别接口传递的都是人脸图片的url,而不是直接文件流,这样就需要先把文件上传到一个图床服务,oss的作用就在这里了.
实战
创建java项目之类的就不再赘述了.
1. 引入jar包
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.14</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-facebody -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-facebody</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.1</version>
</dependency>
前两个是人脸识别的sdk,第三个是oss的sdk包.
2. show me code
package com.zy.facebody;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.comm.Protocol;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.facebody.model.v20191230.*;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
/**
* @Author: Zy
* @Date: 2022/12/2 10:24
*/
public class TestFaceBody {
static DefaultProfile profile;
static {
profile = DefaultProfile.getProfile("cn-shanghai", "申请的accessKeyId", "申请的accessSecret");
}
public static void main(String[] args) throws FileNotFoundException {
String dbName = "compare_face_test";
String entityId = "test_1";
// File entityFile = new File("C:\Users\zy963\Desktop\entity.jpg");
File searchFile = new File("C:\Users\zy963\Desktop\search4.jpg");
// 添加样本
// addFaceEntity(dbName, entityId);
// addFace(dbName, entityId, new FileInputStream(entityFile), entityFile.getName());
// 查询人脸数据库
searchFace(dbName, searchFile.getName(), new FileInputStream(searchFile));
}
/**
* 创建人脸数据库
*
* @param dbName 数据库名
* @return void
* @author Zy
* @date 2022/12/2
*/
public static void createFaceDb(String dbName) {
IAcsClient client = new DefaultAcsClient(profile);
CreateFaceDbRequest request = new CreateFaceDbRequest();
request.setSysRegionId("cn-shanghai");
request.setName(dbName);
try {
CreateFaceDbResponse response = client.getAcsResponse(request);
System.out.println(new Gson().toJson(response));
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
}
/**
* 添加人脸样本
* 人脸样本就是要存储的人脸数据
*
* @param entityId 样本id
* @return void
* @author Zy
* @date 2022/12/2
*/
public static void addFaceEntity(String dbName, String entityId) {
IAcsClient client = new DefaultAcsClient(profile);
AddFaceEntityRequest request = new AddFaceEntityRequest();
request.setSysRegionId("cn-shanghai");
request.setDbName(dbName);
request.setEntityId(entityId);
request.setLabels("测试");
try {
AddFaceEntityResponse response = client.getAcsResponse(request);
System.out.println(new Gson().toJson(response));
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
}
/**
* 上传样本数据,支持oss
*
* @param dbName 人脸数据库名
* @param entityId 样本id
* @param inputStream 输入流
* @return void
* @author Zy
* @date 2022/12/2
*/
public static void addFace(String dbName, String entityId, FileInputStream inputStream, String fileName) {
OSS ossClient = getOssClient();
String bucketName = "oss的bucketName";
// 创建PutObject请求。
ossClient.putObject(bucketName, fileName, inputStream);
ossClient.shutdown();
String url = "https://" + bucketName + ".oss-cn-shanghai.aliyuncs.com/" + fileName;
System.out.println(url);
IAcsClient client = new DefaultAcsClient(profile);
AddFaceRequest request = new AddFaceRequest();
request.setSysRegionId("cn-shanghai");
request.setDbName(dbName);
request.setImageUrl(url);
request.setEntityId(entityId);
request.setExtraData("小明");
try {
AddFaceResponse response = client.getAcsResponse(request);
System.out.println(new Gson().toJson(response));
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
}
/**
* 搜索人脸
*
* @param dbName 人脸数据库名称
* @param fileName 图片文件名称
* @param inputStream 图片文件流
* @return void
* @author Zy
* @date 2022/12/2
*/
public static void searchFace(String dbName, String fileName, InputStream inputStream) {
OSS ossClient = getOssClient();
String bucketName = "oss的bucketName";
// 创建PutObject请求。
ossClient.putObject(bucketName, fileName, inputStream);
ossClient.shutdown();
String url = "https://" + bucketName + ".oss-cn-shanghai.aliyuncs.com/" + fileName;
System.out.println(url);
IAcsClient client = new DefaultAcsClient(profile);
SearchFaceRequest request = new SearchFaceRequest();
request.setSysRegionId("cn-shanghai");
request.setDbName(dbName);
request.setImageUrl(url);
request.setLimit(5);
try {
SearchFaceResponse response = client.getAcsResponse(request);
System.out.println(new Gson().toJson(response));
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
}
/**
* oss client创建
*
* @param
* @return com.aliyun.oss.OSS
* @author Zy
* @date 2022/12/2
*/
public static OSS getOssClient() {
// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
String endpoint = "oss的endpoint";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "申请的accessKeyId";
String accessKeySecret = "申请的accessKeyId";
// 创建OSSClient实例。
return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
}
}
代码不再赘述,都是官网的api,有兴趣可以参考官网: help.aliyun.com/document_de…
实现的效果也不太好贴图,毕竟是本人丑照.
不过识别还是很准确的.
能力概述
阿里云平台的人脸识别能力包含很多种,比如活体检测,人脸定位,人脸识别1:1,人脸识别1:N等,我们做人脸识别主要用的是人脸识别1:N,简单理解一下:
- 阿里云通过大量的训练做出一个识别准确度比较高的模型.
- 上传样本,阿里云将照片图片解析成特征项
-
- 人脸识别是不存储图片的,最多保留24H,可以理解为将图片转化为特征后,图片就没用了.
- 搜索人脸时,也是通过同样的方式来处理图片的.
总结
这次只是简单的调用平台api,并没有做很多识别准确度的测试,不过我觉得应该没啥问题.
有时间了可以对人脸识别的工具做一次封装,封成一个starter,便于使用.
阿里云平台或者其他平台的这种服务能力都并没有与springBoot这种流行技术结合起来,需要自己手动封装.