java使用face++简单实现人脸识别注册登录
java使用face++简单实现人脸识别注册登录
前言
人脸识别,好高大上!!!
理解之后很简单。
支付宝使用的就是face++,
至于face++账号信息,apikey…..,本文不做讲述,网上很多.
一.设计思想
1. 先想一想,如果让你实现人脸识别,你会怎么做?
寻找图片上的关键点,制作一套算法,分析脸部信息,将得到的数据存入数据库,
登录的时候,通过同样的算法,分析数据,和数据库中存入的信息进行比对……
工作量好大!!!
face++有着它独有的非常优秀的算法,我们可以将我们的图片上传到face++服务器来获取对应的图片数据,剩下的事情就很简单了
2. 四个face++ api简介:
这里只介绍用到的api,
2.1 使用api肯定需要先注册一下信息,获取api_key和api_secret,可以注册试用的进行获取
2.2 create
作用: 创建一个FaceSet,创建一个脸部信息集合,引用官网的描述:
url:https://api-cn.faceplusplus.com/facepp/v3/faceset/create
参数:api_key,api_secret,……
返回值: faceset_token, outer_id……,这里写的两个返回值需要记住,是这个脸部信息集合的唯一标识,具体返回值信息如下图:
2.3 addFace
作用:向脸部信息集合faceSet添加一条或多条脸部信息,便于后期搜索
url: https://api-cn.faceplusplus.com/facepp/v3/faceset/addface
参数: 不用说,肯定需要,api_key,api_secret,faceSet_token或outer_id(脸部信息唯一标识),还有图片信息,官网截图:
返回值:可以获取插入的结果信息
.
2.4 Search
作用: 传入一张图片信息到face++服务器,会返回最相似的face_token
url: https://api-cn.faceplusplus.com/facepp/v3/search
参数:api_key,api_secret,image_url或image_file或image_base64或face_token,详细参数列表如下
是否必选 |
参数名 |
类型 |
参数说明 |
必选 |
api_key |
String |
调用此 API 的 API Key |
必选 |
api_secret |
String |
调用此 API 的 API Secret |
必选(四选一) |
face_token |
String |
进行搜索的目标人脸的 face_token,优先使用该参数 |
image_url |
String |
目标人脸所在的图片的 URL |
|
image_file |
File |
目标人脸所在的图片,二进制文件,需要用 post multipart/form-data 的方式上传。 |
|
image_base64 |
String |
base64 编码的二进制图片数据 如果同时传入了 image_url、image_file 和 image_base64 参数,本 API 使用顺序为 image_file 优先,image_url 最低。 |
|
必选(二选一) |
faceset_token |
String |
用来搜索的 FaceSet 的标识 |
outer_id |
String |
用户自定义的 FaceSet 标识 |
|
可选 |
return_result_count |
Int |
控制返回比对置信度最高的结果的数量。合法值为一个范围 [1,5] 的整数。默认值为 1 |
可选(仅正式 API Key 可以使用) |
face_rectangle |
String |
当传入图片进行人脸检测时,是否指定人脸框位置进行检测。 如果此参数传入值为空,或不传入此参数,则不使用此功能。本 API 会自动检测图片内所有区域的所有人脸。 如果使用正式 API Key 对此参数传入符合格式要求的值,则使用此功能。需要传入一个字符串代表人脸框位置,系统会根据此坐标对框内的图像进行人脸检测,以及人脸关键点和人脸属性等后续操作。系统返回的人脸矩形框位置会与传入的 face_rectangle 完全一致。对于此人脸框之外的区域,系统不会进行人脸检测,也不会返回任何其他的人脸信息。 参数规格:四个正整数,用逗号分隔,依次代表人脸框左上角纵坐标(top),左上角横坐标(left),人脸框宽度(width),人脸框高度(height)。例如:70,80,100,100 注:只有在传入 image_url、image_file 和 image_base64 三个参数中任意一个时,本参数才生效。 |
返回值:返回值包含和你传入图片信息最像的图片的face_token,(可以再和数据库中对应的信息进行比较)
2.4 Detect
作用:
传入一张图片信息,获取这张图片的face_token,注意,一张相同图片获取多次的face_token不同
url: https://api-cn.faceplusplus.com/facepp/v3/detect
参数:api_key,api_secret, image_url或image_file或image_base64,
是否必选 |
参数名 |
类型 |
参数说明 |
||||||
必选 |
api_key |
String |
调用此API的API Key |
||||||
必选 |
api_secret |
String |
调用此API的API Secret |
||||||
必选(三选一) |
image_url |
String |
图片的 URL。 注:在下载图片时可能由于网络等原因导致下载图片时间过长,建议使用 image_file 或 image_base64 参数直接上传图片。 |
||||||
image_file |
File |
一个图片,二进制文件,需要用post multipart/form-data的方式上传。 |
|||||||
image_base64 |
String |
base64 编码的二进制图片数据 如果同时传入了 image_url、image_file 和 image_base64 参数,本API使用顺序为 image_file 优先,image_url 最低。 |
|||||||
可选 |
return_landmark |
Int |
是否检测并返回人脸关键点。合法值为:
注:本参数默认值为 0 |
||||||
可选 |
return_attributes |
String |
是否检测并返回根据人脸特征判断出的年龄、性别、情绪等属性。合法值为:
注:本参数默认值为 none |
||||||
可选(仅正式 API Key 可以使用) |
calculate_all |
Int |
是否检测并返回所有人脸的人脸关键点和人脸属性。如果不使用此功能,则本 API 只会对人脸面积最大的五个人脸分析人脸关键点和人脸属性。合法值为:
注:本参数默认值为 0 |
||||||
可选(仅正式 API Key 可以使用) |
face_rectangle |
String |
是否指定人脸框位置进行人脸检测。 如果此参数传入值为空,或不传入此参数,则不使用此功能。本 API 会自动检测图片内所有区域的所有人脸。 如果使用正式 API Key 对此参数传入符合格式要求的值,则使用此功能。需要传入一个字符串代表人脸框位置,系统会根据此坐标对框内的图像进行人脸检测,以及人脸关键点和人脸属性等后续操作。系统返回的人脸矩形框位置会与传入的 face_rectangle 完全一致。对于此人脸框之外的区域,系统不会进行人脸检测,也不会返回任何其他的人脸信息。 参数规格:四个正整数,用逗号分隔,依次代表人脸框左上角纵坐标(top),左上角横坐标(left),人脸框宽度(width),人脸框高度(height)。例如:70,80,100,100 |
||||||
可选 |
beauty_score_min |
Int |
颜值评分分数区间的最小值。默认为0 注:默认颜值评分分数区间为0-100.可通过beauty_score_min和beauty_score_max来调节分数区间,满足您的场景需求。 |
||||||
可选 |
beauty_score_max |
Int |
颜值评分分数区间的最大值。默认为100 |
返回值:图片对应的face_token
字段 |
类型 |
说明 |
request_id |
String |
用于区分每一次请求的唯一的字符串。 |
faces |
Array |
被检测出的人脸数组,具体包含内容见下文。 注:如果没有检测出人脸则为空数组 |
image_id |
String |
被检测的图片在系统中的标识。 |
time_used |
Int |
整个请求所花费的时间,单位为毫秒。 |
error_message |
String |
当请求失败时才会返回此字符串,具体返回内容见后续错误信息章节。否则此字段不存在。 |
在faces中包含face_token
3.
设计分析
- 创建调用create api创建faceSet,取得faceSet_token,对应你的一张用户信息表
- 注册时:调用detect api传入用户注册的图片信息,获取face_token,
将face_token存入faceSet,(调用addFace api存入)
将face_token存入数据库
- 登录: 从前端获取用户图片,将图片编码为base64作为参数image_base64调用search api
返回值为在faceSet中,和传入图片相似度高的face_token
通过返回的face_token,在数据库中进行查询,实现登陆
二.用到的技术
有了上面的分析,即使使用javaweb也能实现了
本案例使用
maven
java的ssm框架
配上Druid连接池
前端使用了jquery,(不懂前端,通过参考和自己设计写的很low)
三.实现
3.1前端界面:
实体类:
User{
String
username;
String
password;
String
other; //在本案例中没有作用
String
faceToken;
}
技术不高,自己写的一个简单的界面
注册界面:register.html
<!DOCTYPE html> html, body { body { h1 { .media { #register { } <!--创建一个注册的按钮--> var video = document.getElementById("myVideo"); /*document.getElementById("myVideo").src= }, function (e) { //获取登陆按钮 } </script> |
登录界面:login.html
<!DOCTYPE html> |
3.2后端界面
face相关类,通过face++官网查到一个demo,本案例修改demo并封装了自己的信息,打成实现功能
获取到的demo:
import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Random; import javax.net.ssl.SSLException; public class FaceTest { public static void main(String[] args) throws Exception{ File file = new File("你的本地图片路径"); byte[] buff = getBytesFromFile(file); String url = "https://api-cn.faceplusplus.com/facepp/v3/detect"; HashMap<String, String> map = new HashMap<>(); HashMap<String, byte[]> byteMap = new HashMap<>(); map.put("api_key", "你的KEY"); map.put("api_secret", "你的SECRET"); map.put("return_landmark", "1"); map.put("return_attributes", "gender,age,smiling,headpose,facequality,blur,eyestatus,emotion,ethnicity,beauty,mouthstatus,eyegaze,skinstatus"); byteMap.put("image_file", buff); try{ byte[] bacd = post(url, map, byteMap); String str = new String(bacd); System.out.println(str); }catch (Exception e) { e.printStackTrace(); } } private final static int CONNECT_TIME_OUT = 30000; private final static int READ_OUT_TIME = 50000; private static String boundaryString = getBoundary(); protected static byte[] post(String url, HashMap<String, String> map, HashMap<String, byte[]> fileMap) throws Exception { HttpURLConnection conne; URL url1 = new URL(url); conne = (HttpURLConnection) url1.openConnection(); conne.setDoOutput(true); conne.setUseCaches(false); conne.setRequestMethod("POST"); conne.setConnectTimeout(CONNECT_TIME_OUT); conne.setReadTimeout(READ_OUT_TIME); conne.setRequestProperty("accept", "*/*"); conne.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundaryString); conne.setRequestProperty("connection", "Keep-Alive"); conne.setRequestProperty("user-agent", "Mozilla/4.0 (compatible;MSIE 6.0;Windows NT 5.1;SV1)"); DataOutputStream obos = new DataOutputStream(conne.getOutputStream()); Iterator iter = map.entrySet().iterator(); while(iter.hasNext()){ Map.Entry<String, String> entry = (Map.Entry) iter.next(); String key = entry.getKey(); String value = entry.getValue(); obos.writeBytes("--" + boundaryString + "\r\n"); obos.writeBytes("Content-Disposition: form-data; name=\"" + key + "\"\r\n"); obos.writeBytes("\r\n"); obos.writeBytes(value + "\r\n"); } if(fileMap != null && fileMap.size() > 0){ Iterator fileIter = fileMap.entrySet().iterator(); while(fileIter.hasNext()){ Map.Entry<String, byte[]> fileEntry = (Map.Entry<String, byte[]>) fileIter.next(); obos.writeBytes("--" + boundaryString + "\r\n"); obos.writeBytes("Content-Disposition: form-data; name=\"" + fileEntry.getKey() + "\"; filename=\"" + encode(" ") + "\"\r\n"); obos.writeBytes("\r\n"); obos.write(fileEntry.getValue()); obos.writeBytes("\r\n"); } } obos.writeBytes("--" + boundaryString + "--" + "\r\n"); obos.writeBytes("\r\n"); obos.flush(); obos.close(); InputStream ins = null; int code = conne.getResponseCode(); try{ if(code == 200){ ins = conne.getInputStream(); }else{ ins = conne.getErrorStream(); } }catch (SSLException e){ e.printStackTrace(); return new byte[0]; } ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buff = new byte[4096]; int len; while((len = ins.read(buff)) != -1){ baos.write(buff, 0, len); } byte[] bytes = baos.toByteArray(); ins.close(); return bytes; } private static String getBoundary() { StringBuilder sb = new StringBuilder(); Random random = new Random(); for(int i = 0; i < 32; ++i) { sb.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-".charAt(random.nextInt("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_".length()))); } return sb.toString(); } private static String encode(String value) throws Exception{ return URLEncoder.encode(value, "UTF-8"); } public static byte[] getBytesFromFile(File f) { if (f == null) { return null; } try { FileInputStream stream = new FileInputStream(f); ByteArrayOutputStream out = new ByteArrayOutputStream(1000); byte[] b = new byte[1000]; int n; while ((n = stream.read(b)) != -1) out.write(b, 0, n); stream.close(); out.close(); return out.toByteArray(); } catch (IOException e) { } return null; } } |
哪里需要改?
四.总结
人无我有,人有我优
思路很清晰,具体实现很难!!!
实现后感觉很简单
java使用face++简单实现人脸识别注册登录的更多相关文章
- 基于javaweb人脸识别注册登录系统
---恢复内容开始--- 现在是2019年,人脸识别技术已经相当成熟了,百度自2017年发布人脸识别技术,已经被广泛应用,不管从现在的iphoneX掀起的面部解锁到手机应用端的各种人脸认证,这一技术已 ...
- 10分钟手把手教你运用Python实现简单的人脸识别
欲直接下载代码文件,关注我们的公众号哦!查看历史消息即可! 前言:让我的电脑认识我 我的电脑只有认识我,才配称之为我的电脑! 今天,我们用Python实现高大上的人脸识别技术! Python里,简单的 ...
- C#_Demo_摄像头实时_4线程人脸识别注册开发全过程
v效率有点低,大家看看哪里开可以节省时间?源代码:https://github.com/catzhou2002/ArcFaceDemo说实话,为了提高识别效率,我也是竭尽所能,干了不少自认为的优化,如 ...
- Python在七牛云平台的应用(三)简单的人脸识别
前言 这是最后一篇介绍python在七牛云平台的应用了,因为-前两篇文章第一篇分享了怎么安装七牛的官方库以及怎么对自己的空间进行下载上传,删除等行动.而第二篇则分享了怎么利用七牛的API接口,由于七牛 ...
- java引用Arcface,实现人脸识别(demo)
## 开发环境准备: ###开发使用到的软件和工具: * Jdk8.mysql5.7.libarcsoft_face.dll(so).libarcsoft_face_engine.dll(so).li ...
- python3+opencv+tkinter开发简单的人脸识别小程序
学校里有门图像处理的课程最终需要提交一个图像处理系统, 正好之前对于opencv有些了解,就简单的写一个人脸识别小程序吧 效果图如下 笔者IDE使用Pycharm,GUI编程直接使用内置的tkinte ...
- Java对接百度智能云人脸识别
------------------------->这篇文章就是自己做个笔记<------------------------- 首先登录or注册自己的百度智能云管理中心:https:// ...
- 简单机器学习人脸识别工具face-recognition python小试,一行代码实现人脸识别
摘要: 1行代码实现人脸识别,1. 首先你需要提供一个文件夹,里面是所有你希望系统认识的人的图片.其中每个人一张图片,图片以人的名字命名.2. 接下来,你需要准备另一个文件夹,里面是你要识别的图片.3 ...
- 吴裕雄--天生自然python学习笔记:python 用 Open CV通过人脸识别进行登录
人脸识别登录功能的基本原理是通过对比两张图片的差异度来判断两张图片是 否是同 一人的面部 . 对比图片 差异度 的算法有很多种,本例中使用“颜色直方图” 算法来实现对人脸图像的识别. 下面为比较 im ...
随机推荐
- wx小程序知识点(六)
六.生命周期 (1)onLoad —— 加载时触发,只调用一次,可用来发送请求绑定数据.获取url中参数 (2)onShow —— 页面显示时触发,每次显示都会执行,用来获取需要频繁更新的数 ...
- Socket 对象(内建)方法
函数 描述 服务器端套接字 s.bind() 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址. s.listen() 开始TCP监听.back ...
- Nowcoder Monotonic Matrix ( Lindström–Gessel–Viennot lemma 定理 )
题目链接 题意 : 在一个 n * m 的矩阵中放置 {0, 1, 2} 这三个数字.要求 每个元素 A(i, j) <= A(i+1, j) && A(i, j) <= ...
- sh_08_格式化字符串
sh_08_格式化字符串 info_tuple = ("小明", 21, 1.85) # 格式化字符串后面的 `()` 本质上就是元组 print("%s 年龄是 %d ...
- 2-sat基础详解
(大量引用<2-SAT解法浅析 -by 华中师大一附中 赵爽><由对称性解2-SAT问题> Great_Influence关于P4782 [模板]2-SAT 问题的题解.在此对 ...
- Acwing:137. 雪花雪花雪花(Hash表)
有N片雪花,每片雪花由六个角组成,每个角都有长度. 第i片雪花六个角的长度从某个角开始顺时针依次记为ai,1,ai,2,…,ai,6ai,1,ai,2,…,ai,6. 因为雪花的形状是封闭的环形,所以 ...
- Jmeter获取未来时间
1.添加前置处理器:BeanShell PreProcessor import java.text.SimpleDateFormat; import java.util.Calendar; impor ...
- vue 组件 Vue.component 用法
todo https://blog.csdn.net/weixin_41796631/article/details/82929139
- webpack学习之路--demo1
1.不使用框架建立webpack项目时 (1).npm init -y 生成package.json文件 (2).npm install --save-dev webpack 在当前项目下安装webp ...
- vue一些注意事项
1.生命周期钩子的 this 上下文指向调用它的 Vue 实例. 不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a) 或 vm.$wa ...