前段时间开发一个小程序需要使用到阿里云(1:N)人脸识别的服务,查询资料发现网上并没有详细的教程,而官方的api文档也写得很简略,于是就有了如下教程,希望能帮助到大家。

目录

服务开通

人脸识别服务开通

oss存储服务开通

代码部分

人脸识别

①pom.xml

②face_detect_util

③代码讲解:

oss上传

①pom.xml

②OSS_Util

③小程序前端

最后的结果:


服务开通

人脸识别服务开通

注册阿里云账户后,进入人脸人体控制台(阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台),进行对人脸人体API调用量的购买。目前阿里云上所有人脸人体的接口都是2QPS((Query Per Second):每秒请求数)免费,足够开发时学习使用。

oss存储服务开通

进入oss控制台(阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台),右侧有一块Bucket管理,点击创建Bucket来得到一块存储空间。个人对Bucket的理解就像是database中的一个个table,是用户用来管理所存储对象的存储空间。一个oss中可以拥有许多Bucket,但是每个Bucket的名称都是唯一的。由于人脸人体的url只支持上海的oss链接,所以创建华东2的Bucket。创建好之后便可以使用阿里云的人脸识别技术了。

代码部分

这里使用java代码作为实例,前端为需要人脸识别功能的小程序,后端使用Springboot框架。

人脸识别

①pom.xml

        <dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.1.1</version></dependency>

②face_detect_util

需要先得到阿里云的access_key_id(如何创建AccessKey_访问控制-阿里云帮助中心);

package com.zhiqi.wayhome.Util;import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhiqi.wayhome.Bean.Face_msg;import java.util.Map;public class face_detect_util {//DefaultProfile.getProfile的参数分别是地域,access_key_id, access_key_secretpublic static DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai", "xxx", "xxx");//这里要改成自己的public static DefaultAcsClient client = new DefaultAcsClient(profile);public static ObjectMapper mapper=new ObjectMapper();/*** AddFaceEntity用于添加人脸样本 添加了人脸样本后才能添加人脸数据* 只有在用户上传第一张照片时调用这个接口 之后就只需要添加人脸数据即可* @param EntityId 用身份证号码来标识**/public static void AddFaceEntity(String EntityId){CommonRequest request = new CommonRequest();request.setMethod(MethodType.POST);request.setVersion("2019-12-30");request.setDomain("facebody.cn-shanghai.aliyuncs.com");request.putBodyParameter("Action", "AddFaceEntity");request.putBodyParameter("DbName", "Wayhome");request.putBodyParameter("EntityId", EntityId);CommonResponse response = null;try {response = client.getCommonResponse(request);} catch (ClientException e) {e.printStackTrace();}System.out.println(response.getData());}/*** AddFace接口用于向人脸样本中添加人脸数据* @param* @param EntityId 添加人脸的身份证号* @param imageUrl 检测图片的URL*/public static int AddFace(String EntityId,String imageUrl){CommonRequest request = new CommonRequest();request.setMethod(MethodType.POST);request.setVersion("2019-12-30");request.setDomain("facebody.cn-shanghai.aliyuncs.com");request.setAction("AddFace");request.putBodyParameter("DbName", "Wayhome");request.putBodyParameter("EntityId", EntityId);request.putBodyParameter("ImageUrl",imageUrl);
//        request.putBodyParameter("Content", "/9j/4AAQSkZJRgABA...");  //检测图片的内容,Base64编码CommonResponse response = null;try {response = client.getCommonResponse(request);} catch (ClientException e) {e.printStackTrace();}System.out.println(response.getData());//得到这张图片的FaceId 并存到数据库中Face_msg face_msg=null;String s=response.getData();String[] ss=s.split("FaceId");String a=ss[1].substring(3,ss[1].length()-3);return Integer.parseInt(a);}/*** DeleteFace接口用于从人脸库中删除某张人脸数据* @param FaceId 删除指定FaceId的图片* @throws ClientException*/public static void DeleteFace(int FaceId)  {CommonRequest request = new CommonRequest();request.setMethod(MethodType.POST);request.setVersion("2019-12-30");request.setDomain("facebody.cn-shanghai.aliyuncs.com");request.setAction("DeleteFace");request.putBodyParameter("DbName", "Wayhome");request.putBodyParameter("FaceId", FaceId);CommonResponse response = null;try {response = client.getCommonResponse(request);} catch (ClientException e) {e.printStackTrace();}System.out.println(response.getData());}/*** DeleteFaceEntity接口用于从人脸库中删除人脸实体* @param EntityId 在任务结束后清除该走失者的人脸实体* @throws ClientException*/public static void DeleteFaceEntity(String EntityId)  {CommonRequest request = new CommonRequest();request.setMethod(MethodType.POST);request.setVersion("2019-12-30");request.setDomain("facebody.cn-shanghai.aliyuncs.com");request.setAction("DeleteFaceEntity");request.putBodyParameter("DbName", "Wayhome");request.putBodyParameter("EntityId", EntityId);CommonResponse response = null;try {response = client.getCommonResponse(request);} catch (ClientException e) {e.printStackTrace();}System.out.println(response.getData());}/**** @param ImageUrl*/public static String SearchFace(String ImageUrl) {CommonRequest request = new CommonRequest();request.setMethod(MethodType.POST);request.setVersion("2019-12-30");request.setDomain("facebody.cn-shanghai.aliyuncs.com");request.setAction("SearchFace");request.putBodyParameter("DbName", "Wayhome");request.putBodyParameter("ImageUrl", ImageUrl);request.putBodyParameter("Limit", 1);CommonResponse response = null;try {response = client.getCommonResponse(request);} catch (ClientException e) {e.printStackTrace();}String s=response.getData();System.out.println(s);return s;}
}

③代码讲解:

使用人脸识别的顺序-->创建人脸数据库(可手动也可代码,目前免费用户一人只能创建一个人脸库)-->创建人脸实体(一个人脸实体代表一个人,可以有几张照片)-->为人脸实体添加数据(一个实体最多用五张图片来训练)-->上传图片与人脸库中的所有实体进行比对(1:N)。

①创建人脸库:我是手动创建人脸库的,登录到人脸人体控制台(阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台)中,点击以下按钮,进入数据库管理中新建人脸库,我的取名为Wayhome。

②创建人脸实体:代码中的AddFaceEntity(String EntityId)函数。调用的也是AddFaceEntity接口,接口文档(AddFaceEntity_视觉智能开放平台-人脸人体_API文档-阿里云OpenAPI开发者门户),查看文档发现,请求的参数列表如下:

其中DbName为之前创建的人脸数据库名,我创建的为Wayhome;EntityId为创建的人脸实体的ID,一般使用该人的唯一标识。如身份证号、员工号等。Lables可传可不传,可以是该人的姓名作为备注。

注意:要用POST方法调用接口,传入的参数中要有SDK的版本:request.setVersion("2019-12-30");版本号从文档中查看(文档的网址中也有版本号)。

之后的接口就很类似了,这里不一一演示。

由于人脸识别传入的faceimage需要是自家oss的链接,我一开始自己搭建了上传图片的服务器,但是发现传入图片链接后报错,查阅资料传入的参数必须是oss的链接,接下来介绍一下小程序上传多张照片到oss并返回URL链接。

oss上传

①pom.xml

        <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>2.7.0</version></dependency>

②OSS_Util

package com.zhiqi.wayhome.Util;import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Random;public class OSS_Util {protected static final Logger log = LoggerFactory.getLogger(OSS_Util.class);private static String endpoint="oss-cn-shanghai.aliyuncs.com";private static String accessKeyId="LTAI5tE4awy6GwWiHA4sHkd5";private static String accessKeySecret="5E3X23XuLBO71YPW01ZXSdfgresG28";private static String bucketName="wayhome";//文件存储目录private static String filedir = "userImg/";/**** 上传图片* @param file* @return*/public static String uploadImg2Oss(MultipartFile file) {if (file.getSize() > 1024 * 1024 *20) {return "图片太大";//RestResultGenerator.createErrorResult(ResponseEnum.PHOTO_TOO_MAX);}String originalFilename = file.getOriginalFilename();String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();Random random = new Random();String name = random.nextInt(10000) + System.currentTimeMillis() + substring;try {InputStream inputStream = file.getInputStream();uploadFile2OSS(inputStream, name);return name;//RestResultGenerator.createSuccessResult(name);} catch (Exception e) {return "上传失败";//RestResultGenerator.createErrorResult(ResponseEnum.PHOTO_UPLOAD);}}/*** 上传图片获取fileUrl* @param instream* @param fileName* @return*/private static String uploadFile2OSS(InputStream instream, String fileName) {String ret = "";try {//创建上传Object的MetadataObjectMetadata objectMetadata = new ObjectMetadata();objectMetadata.setContentLength(instream.available());objectMetadata.setCacheControl("no-cache");objectMetadata.setHeader("Pragma", "no-cache");objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));objectMetadata.setContentDisposition("inline;filename=" + fileName);//上传文件OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);PutObjectResult putResult = ossClient.putObject(bucketName, filedir + fileName, instream, objectMetadata);ret = putResult.getETag();} catch (IOException e) {log.error(e.getMessage(), e);} finally {try {if (instream != null) {instream.close();}} catch (IOException e) {e.printStackTrace();}}return ret;}public static String getcontentType(String FilenameExtension) {if (FilenameExtension.equalsIgnoreCase(".bmp")) {return "image/bmp";}if (FilenameExtension.equalsIgnoreCase(".gif")) {return "image/gif";}if (FilenameExtension.equalsIgnoreCase(".jpeg") ||FilenameExtension.equalsIgnoreCase(".jpg") ||FilenameExtension.equalsIgnoreCase(".png")) {return "image/jpg";}if (FilenameExtension.equalsIgnoreCase(".html")) {return "text/html";}if (FilenameExtension.equalsIgnoreCase(".txt")) {return "text/plain";}if (FilenameExtension.equalsIgnoreCase(".vsd")) {return "application/vnd.visio";}if (FilenameExtension.equalsIgnoreCase(".pptx") ||FilenameExtension.equalsIgnoreCase(".ppt")) {return "application/vnd.ms-powerpoint";}if (FilenameExtension.equalsIgnoreCase(".docx") ||FilenameExtension.equalsIgnoreCase(".doc")) {return "application/msword";}if (FilenameExtension.equalsIgnoreCase(".xml")) {return "text/xml";}return "image/jpg";}/*** 获取图片路径* @param fileUrl* @return*/public static String getImgUrl(String fileUrl) {if (!StringUtils.isEmpty(fileUrl)) {String[] split = fileUrl.split("/");String url = getUrl(filedir + split[split.length - 1]);return url;}return null;}/*** 获得url链接** @param key* @return*/public static String getUrl(String key) {// 设置URL过期时间为10年 3600l* 1000*24*365*10// 如果不设置则URL的有效时间很短Date expiration = new Date(new Date().getTime() + 3600L * 1000 * 24 * 365 * 10);// 生成URLOSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);if (url != null) {return url.toString();}return null;}/*** 多图片上传* @param fileList* @return*/public static String checkList(List<MultipartFile> fileList) {String fileUrl = "";String str = "";String photoUrl = "";for(int i = 0;i< fileList.size();i++){fileUrl = uploadImg2Oss(fileList.get(i));str = getImgUrl(fileUrl);if(i == 0){photoUrl = str;}else {photoUrl += "," + str;}}return photoUrl.trim();}/*** 单个图片上传* @param file* @return*/public static String checkImage(MultipartFile file){String fileUrl = uploadImg2Oss(file);String str = getImgUrl(fileUrl);return str.trim();}/*** 删除oss内的文件**/public static void removeFile(String img_url) {int i1=img_url.indexOf('/');int i2=img_url.indexOf('/',i1+1);int i3=img_url.indexOf('/',i2+1);int i4=img_url.indexOf("?",i3+1);String substring=img_url.substring(i3+1,i4);OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);try {// 删除文件。如需删除文件夹,请将ObjectName设置为对应的文件夹名称。如果文件夹非空,则需要将文件夹下的所有object删除后才能删除该文件夹。ossClient.deleteObject(bucketName, substring);} catch (Exception e) {e.printStackTrace();}// 关闭OSSClient。ossClient.shutdown();}}

使用代码时只需要修改以下部分:

  protected static final Logger log = LoggerFactory.getLogger(OSS_Util.class);private static String endpoint="oss-cn-shanghai.aliyuncs.com";private static String accessKeyId="xxx";//人脸识别那讲的accessKeyIdprivate static String accessKeySecret="xxxxx";private static String bucketName="wayhome";//之前创建的bucket名称//文件存储目录private static String filedir = "userImg/";//自定

单图片和多图片上传分别调用checkImage()和checkList()方法,返回图片的url。

删除文件部分代码的解释:

图片返回的url样例(http://wayhome.oss-cn-shanghai.aliyuncs.com/userImg/1618904390858.jpg?Expires=1934264388&OSSAccessKeyId=LTAI5tE4awy6GwWiHA4sHLd5&Signature=9J%2FQ1A%2F29y2XTPpBVudnW726bek%3D)

所以文件在Bucket中存储的的路径为,即第三个‘/’到‘?’之间的部分,所以获取删除文件的目录为以下代码。

public static void removeFile(String img_url) {int i1=img_url.indexOf('/');int i2=img_url.indexOf('/',i1+1);int i3=img_url.indexOf('/',i2+1);int i4=img_url.indexOf("?",i3+1);String substring=img_url.substring(i3+1,i4);OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);try {// 删除文件。如需删除文件夹,请将ObjectName设置为对应的文件夹名称。如果文件夹非空,则需要将文件夹下的所有object删除后才能删除该文件夹。ossClient.deleteObject(bucketName, substring);} catch (Exception e) {e.printStackTrace();}// 关闭OSSClient。ossClient.shutdown();}

③小程序前端

data: {temp_img:null
}uploadd:function(i){var that=this;wx.uploadFile({ url: '...',//输入你的上传接口 filePath: that.data.temp_img[i], //小程序的上传只能是一张一张图片上传 ,参数不能是一个数组。name: 'fileList',formData:{//这里面放补充参数},//使用递归进行上传,会有错success: function (res) { console.log(res);console.log(i);i++;if(i == length){ //当图片传完时,停止调用console.log('成功');wx.showToast({title: '上传成功!',duration: 1500,success: function(){that.hideModal();}});}else {that.uploadd(i);    }//刷新页面that.onLoad();}, fail: function (err) { console.log(err) }});},upload_img(){//上传图片开始var that = this;wx.chooseImage({count: 5, // 最多可以选择的图片张数,默认9(人脸库每个人最多五张照片)sizeType: ['original'], // original 原图,compressed 压缩图,默认二者都有sourceType: ['album', 'camera'], // album 从相册选图,camera 使用相机,默认二者都有success: function (res) {// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片var tempFilePaths = res.tempFilePaths;wx.showToast({title: '正在上传',icon: 'loading',mask: true,duration: 1000});console.log(tempFilePaths);that.setData({temp_img:tempFilePaths})var i=0;that.uploadd(i);},});},

最后的结果:

阿里云 aliyun 人脸识别(1:N) java spring 小程序 小程序上传多图 阿里云oss相关推荐

  1. java spring文件下载_SpringMVC实现文件上传和下载的工具类

    本文主要目的是记录自己基于SpringMVC实现的文件上传和下载的工具类的编写,代码经过测试可以直接运行在以后的项目中. 开发的主要思路是对上传和下载文件进行抽象,把上传和下载的核心功能抽取出来分装成 ...

  2. 微信小程序视频图片上传到腾讯云COS对象储存

    配置好腾讯云账号 下载对应SDK引入使用,这里提供实践代码. let COS = require('./utils/cos-wx-sdk-v5'); //签名生成配置数,可自行生成,或者后台处理好给你 ...

  3. java 文件空指针,java – Spring 3中的文件上传MVC – 空指针异常

    我正在使用 spring MVC 3.我一直在尝试访问上传文件的属性,但我不断收到以下错误消息.我可以访问已发布的表单的其他字段但我无法访问上传的文件. nullhandleForm - Failed ...

  4. Java spring boot 阿里云调用人脸识别接口,本地sdk上传到阿里云调用api

    Java spring boot 阿里云调用人脸识别接口 没有写测试类,工具类如下,有access_key_id和access_key_secret传参调用就可使用 代码如下: pom.xml依赖 & ...

  5. java上传文件至阿里云oss工具类

    第一步:引入oss maven坐标 <dependency><groupId>com.aliyun.oss</groupId><artifactId>a ...

  6. java利用iText写pdf并上传阿里云OSS并下载

    iText是用于生成pdf的一个类库,通过它可以生成pdf或者将XML , HTML转换城pdf模版:阿里云的oss对象存储存储的类型比较多了,可以存储音频 图片 pdf excel 等资源,oss本 ...

  7. 使用百度云的人脸识别API实现两张照片是否为同一人的判断

    今天是小编第一次使用百度云的人脸识别API,小编是个小白,一路坎坷,经过一天的学习与研究,终于实现了这个功能. 1.下面是在这个过程中使用的所有的工具: IntelliJ IDEA(Java的开发工具 ...

  8. 云脉人脸识别门禁 拒绝“伪装”蒙混过关

    从刷脸解锁手机到刷脸支付,如今人脸识别相关应用已然遍布人们的日常生活.然而,每当提及人脸识别,仍然会听到稀稀疏疏的质疑声,人们一方面享受着人脸识别带来的便利,一方面又不愿意信任这项技术. 人脸识别门禁 ...

  9. 安卓Android基于百度云平台人脸识别学生考勤签到系统设计

    开发软件:Idea + Mysql + AndroidStudio + 雷电模拟器 基于安卓开发一个人脸识别签到系统,服务器采用springboot框架开发,管理员登录后可以添加和维护人脸信息,添加的 ...

最新文章

  1. Serial Communications in Win32
  2. Gartner 2019 年 BI 炒作周期五大趋势:增强分析、数字文化、关系分析、决策智能、实施和扩展...
  3. ListView、AdapterView、RecyclerView全面解析
  4. 比乐高便宜十倍!4合1电动遥控积木玩法百变
  5. java8 函数式编程_如何使用Java 8函数式编程生成字母序列
  6. 云顶之弈机器人法爆_云顶之弈10.16b机器人阵容推荐 云顶之弈10.16b机器人娱乐阵容玩法攻略...
  7. 指针数据类型 java_C/C++ 指针的小结——指针与其它数据类型(数组、字符串、函数、结构体)的关系...
  8. android 动态文本选取,android-用动态文本更新UI
  9. 更改盘符实现文件服务器的特使需求
  10. vue element-UI的树形结构,父级关联,返回数据反选的问题
  11. 云智慧压测实战分享之JMeter场景设置与监控
  12. 【NLP笔记】理论与实践详解词向量
  13. linux选择内核命令,Lenky个人站点
  14. python写一个自动在网页搜索资源并下载的程序
  15. 【微信小程序】flex布局
  16. 中科大自主招生2018年笔试数学
  17. 为自己加油,祝福我吧,朋友
  18. 杨辉三角与倒置杨辉三角
  19. 每日一道 LeetCode (16):求 x 的平方根
  20. 基于Aforge的物体运动识别-入门篇

热门文章

  1. 过一遍HTML标签(三)
  2. 不知道这是FreeTextBox还是五笔加加的bug
  3. 【每日一词】buzzword
  4. 张家界暑假自驾游凤凰古城与芙蓉镇
  5. C#关于ComboBox的使用
  6. 史上最浅的ios面试题,重复了
  7. saas 商业模式风险_商业模式:SaaS(软件即服务)
  8. 怀念啊我的青春(歌词)
  9. 数据线如何申请办理检验报告,需要的资料有什么?
  10. 传奇世界服务器端口被占用,Windows socket error: 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 (10048), on API 'bi...