JavaWeb利用百度API实现人脸登陆功能
笔者的完整项目
URL:完整项目参考
笔者参考的人脸识别Servlet版本案例项目在下面网盘中
1,在百度云注册人脸库
URL:百度云的网址
注册,登陆之后的页面
找到人脸识别功能
点击创建应用
填写必要信息
点击人脸库,再点击自己创建的应用
添加组(组名要记住,后期需要)
进入创建的组,添加图片和填写id(id最好和数据库中的用户id保持一致)id也要记住,后期需要
2,引入必要的包
1,我是用的maven项目
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.8.0</version>
</dependency>
2,部分maven仓库里面没有的包(jar包放在案例里面,需要自取)
3,简单案例
百度网盘链接
提取码:23ab
3,编写java代码
大家可以参考:https://blog.csdn.net/qq_44199087/article/details/90245426,这位博主,案例就出自这位博主
我们需要把下面代码的JSONObject js = FaceSpot.searchFace(img, “face”, “2”);
“face”, “2”,两个参数替换成自己的,分别表示组名和用户id
以我的应用为例,就把这两个参数替换成"yuriDuan",“1000”
package cn.face.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONObject;
import cn.face.util.FaceSpot;
/**
* Servlet implementation class FaceLoginServlet
*/
public class FaceLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public FaceLoginServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.getHeader("textml; charset=UTF-8");
//实例化PrintWriter对象
PrintWriter out = response.getWriter();
String img = request.getParameter("img");
JSONObject js = FaceSpot.searchFace(img, "face", "2");
System.out.println(js.toString(2));
out.print(js);
}
}
工具类:(需要修改AppID ,APIKey,SecretKey 这三个参数是注册应用时就有的 )
我们直接在百度云控制台就已经上传了图片,所以可以把下面代码的main函数给注释掉
package cn.face.util;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONObject;
import com.baidu.aip.face.AipFace;
import com.baidu.aip.face.FaceVerifyRequest;
import com.baidu.aip.face.MatchRequest;
import com.baidu.aip.util.Base64Util;
public class FaceSpot {
//private static final BASE64Decoder decoder = new BASE64Decoder();
private static final String AppID = "###################";
private static final String APIKey = "###################";
private static final String SecretKey = "###################";
static AipFace client = null;
static {
client = new AipFace(AppID, APIKey, SecretKey);
// 可选:设置网络连接参数
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);
}
/**public static void main(String[] args) throws IOException {
//BASE64Decoder decoder = new BASE64Decoder();
/*String file1 = "F:/5.jpg";
byte[] img2 = FileToByte(new File(file1));
System.out.println(addUser(img2,"BASE64","2","face"));*/
String file1 = "F:/4.jpg";
byte[] img2 = FileToByte(new File(file1));
System.out.println(searchFace(img2,"face","1"));
}*/
/**
* 人脸检测
*/
public static String detectFace(File file, String max_face_num) {
try {
return detectFace(FileToByte(file), max_face_num);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 人脸检测
*/
public static String detectFace(byte[] arg0, String max_face_num) {
try {
HashMap<String, String> options = new HashMap<String, String>();
options.put("face_field",
"age,beauty,expression,faceshape,gender,glasses,race,qualities");
options.put("max_face_num", "2");
options.put("face_type", "LIVE");
// 图片数据
String imgStr = Base64Util.encode(arg0);
String imageType = "BASE64";
JSONObject res = client.detect(imgStr, imageType, options);
System.out.println(res.toString(2));
return res.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 人脸比对
*/
public static String matchFace(File file1, File file2) {
try {
return matchFace(FileToByte(file1), FileToByte(file2));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 人脸比对
*/
public static String matchFace(byte[] arg0, byte[] arg1) {
String imgStr1 = Base64Util.encode(arg0);
String imgStr2 = Base64Util.encode(arg1);
MatchRequest req1 = new MatchRequest(imgStr1, "BASE64");
MatchRequest req2 = new MatchRequest(imgStr2, "BASE64");
ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>();
requests.add(req1);
requests.add(req2);
JSONObject res = client.match(requests);
return res.toString();
}
/**
* 人脸搜索
*/
public static String searchFace(File file, String groupIdList, String userId) {
try {
return searchFace(FileToByte(file), groupIdList, userId);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 人脸搜索
*/
public static String searchFace(byte[] arg0, String groupIdList,
String userId) {
String imgStr = Base64Util.encode(arg0);
String imageType = "BASE64";
HashMap<String, String> options = new HashMap<String, String>();
options.put("quality_control", "NORMAL");
options.put("liveness_control", "LOW");
if (userId != null) {
options.put("user_id", userId);
}
options.put("max_user_num", "1");
JSONObject res = client.search(imgStr, imageType, groupIdList, options);
return res.toString(2);
}
//Base64参数
public static JSONObject searchFace(String imgStr, String groupIdList,
String userId) {
String imageType = "BASE64";
HashMap<String, String> options = new HashMap<String, String>();
options.put("quality_control", "NORMAL");
options.put("liveness_control", "LOW");
if (userId != null) {
options.put("user_id", userId);
}
options.put("max_user_num", "1");
JSONObject res = client.search(imgStr, imageType, groupIdList, options);
System.out.println(res.toString(2));
return res;
}
/**
* 增加用户
*/
public static String addUser(File file, String userInfo, String userId,
String groupId) {
try {
return addUser(FileToByte(file), userInfo, userId, groupId);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 增加用户
*/
public static String addUser(byte[] arg0, String userInfo, String userId,String groupId) {
String imgStr = Base64Util.encode(arg0);
String imageType = "BASE64";
HashMap<String, String> options = new HashMap<String, String>();
options.put("user_info", userInfo);
options.put("quality_control", "NORMAL");
options.put("liveness_control", "LOW");
JSONObject res = client.addUser(imgStr, imageType, groupId, userId,options);
return res.toString(2);
}
public static String updateUser(File file, String userInfo, String userId,
String groupId) {
try {
return updateUser(FileToByte(file), userInfo, userId, groupId);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 更新用户
*/
public static String updateUser(byte[] arg0, String userInfo,
String userId, String groupId) {
String imgStr = Base64Util.encode(arg0);
String imageType = "BASE64";
HashMap<String, String> options = new HashMap<String, String>();
if (userInfo != null) {
options.put("user_info", userInfo);
}
options.put("quality_control", "NORMAL");
options.put("liveness_control", "LOW");
JSONObject res = client.updateUser(imgStr, imageType, groupId, userId,
options);
return res.toString(2);
}
/**
* 删除用户人脸信息
*/
public static String deleteUserFace(String userId, String groupId,
String faceToken) {
HashMap<String, String> options = new HashMap<String, String>();
// 人脸删除
JSONObject res = client.faceDelete(userId, groupId, faceToken, options);
return res.toString();
}
/**
* 查询用户信息
*/
public static String searchUserInfo(String userId, String groupId) {
HashMap<String, String> options = new HashMap<String, String>();
// 用户信息查询
JSONObject res = client.getUser(userId, groupId, options);
return res.toString(2);
}
/**
* 获取用户人脸列表
*/
public static String getUserFaceList(String userId, String groupId) {
HashMap<String, String> options = new HashMap<String, String>();
// 获取用户人脸列表
JSONObject res = client.faceGetlist(userId, groupId, options);
return res.toString(2);
}
/**
* 获取一组用户
*/
public static String getGroupUsers(String groupId, String returnNum) {
HashMap<String, String> options = new HashMap<String, String>();
options.put("start", "0");
if (returnNum != null) {
options.put("length", returnNum);
}
// 获取用户列表
JSONObject res = client.getGroupUsers(groupId, options);
return res.toString(2);
}
/**
* 组用户复制
*/
public static String userCopy(String userId, String srcGroupId,
String dstGroupId) {
HashMap<String, String> options = new HashMap<String, String>();
options.put("src_group_id", srcGroupId);
options.put("dst_group_id", dstGroupId);
// 复制用户
JSONObject res = client.userCopy(userId, options);
return res.toString(2);
}
/**
* 删除用户
*/
public static String deleteUser(String userId, String groupId) {
HashMap<String, String> options = new HashMap<String, String>();
// 人脸删除
JSONObject res = client.deleteUser(groupId, userId, options);
return res.toString();
}
/**
* 增加组信息
*/
public static String addGroup(String groupId) {
HashMap<String, String> options = new HashMap<String, String>();
// 创建用户组
JSONObject res = client.groupAdd(groupId, options);
return res.toString();
}
/**
* 删除
*/
public static String deleteGroup(String groupId) {
HashMap<String, String> options = new HashMap<String, String>();
// 创建用户组
JSONObject res = client.groupDelete(groupId, options);
return res.toString();
}
/**
* 获取组列表
*/
public static String getGroupList(String length) {
HashMap<String, String> options = new HashMap<String, String>();
options.put("start", "0");
options.put("length", length);
// 组列表查询
JSONObject res = client.getGroupList(options);
return res.toString();
}
/**
* 活体检测
*/
public static String faceverify(byte[] arg0) {
String imgStr = Base64Util.encode(arg0);
String imageType = "BASE64";
FaceVerifyRequest req = new FaceVerifyRequest(imgStr, imageType);
ArrayList<FaceVerifyRequest> list = new ArrayList<FaceVerifyRequest>();
list.add(req);
JSONObject res = client.faceverify(list);
return res.toString();
}
public static byte[] FileToByte(File file) throws IOException {
// 将数据转为流
@SuppressWarnings("resource")
InputStream content = new FileInputStream(file);
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while ((rc = content.read(buff, 0, 100)) > 0) {
swapStream.write(buff, 0, rc);
}
// 获得二进制数组
return swapStream.toByteArray();
}
}
到此案例应该就能走得通。
4,介绍对人脸库的增删改查功能
1,修改AppID ,APIKey,SecretKey这三个参数为自己创建应用的值
2,修改JSONObject res = client.addUser(encode,“BASE64”, “yuriDUAN”, “1000”, options);
这两个参数替换成自己人脸库的组名和用户id
public class FaceTest {
private AipFace client;
@Before
public void init(){
//创建java代码和百度云交互的client对象
client = new AipFace("xxxxxxx","xxxxxxxxx","xxxxxxxxxxxxxx");
}
//人脸注册:向百度的人脸库中添加用户人脸照片
@Test
public void testFaceRegister()throws Exception{
//2.参数设置
HashMap<String,String> options = new HashMap<String, String>();
options.put("quality_control","NORMAL");//图片质量 NONE LOW NORMAL,HIGH
options.put("liveness_control","LOW");//活体检测
options.put("action_type","replace");//活体检测
//3.构造图片
String path = "C:\\User\\资源\\照片\\002.png";
//上传图片的两种格式:1,url地址 2,Base64字符串
byte[] bytes = Files.readAllBytes(Paths.get(path));
String encode = Base64Util.encode(bytes);
//4.调用API完成人脸注册
/* 参数一:(图片的url或者图片的Base64字符串),
* 参数二:图片形式(URL,BASE64)
* 参数三:组ID(固定字符串)
* 参数四:用户ID
* 参数五:hashMap中的基本参数配置
* */
JSONObject res = client.addUser(encode,"BASE64", "yuriDUAN", "1000", options);
System.out.println(res.toString());
}
/**
* 人脸更新:更新人脸库中的照片
*/
@Test
public void testFaceUpdate() throws Exception {
//2.参数设置
HashMap<String,String> options = new HashMap<>();
options.put("quality_control","NORMAL");//图片质量 NONE LOW NORMAL,HIGH
options.put("liveness_control","LOW");//活体检测
options.put("action_type","replace");
//3.构造图片
String path = "C:\\Users\\资源\\照片\\002.png";
//上传的图片 两种格式 : url地址,Base64字符串形式
byte[] bytes = Files.readAllBytes(Paths.get(path));
String encode = Base64Util.encode(bytes);
//4.调用api方法完成人脸注册
/** 参数一:(图片的url或者图片的Base64字符串),
* 参数二:图片形式(URL,BASE64)
* 参数三:组ID(固定字符串)
* 参数四:用户ID
* 参数五:hashMap中的基本参数配置
*/
JSONObject res = client.updateUser(encode, "BASE64", "yuriDUAN", "1000", options);
System.out.println(res.toString());
}
/**
* 人脸检测:判断图片中是否具有面部信息
*/
@Test
public void testFaceCheck() throws Exception {
//构造图片
String path = "C:\\Users\\资源\\照片\\001.png";
//上传的图片 两种格式 : url地址,Base64字符串形式
byte[] bytes = Files.readAllBytes(Paths.get(path));
String image = Base64Util.encode(bytes);
//调用api方法进行人脸检测
//参数一:(图片的url或者图片的Base64字符串),
//参数二:图片形式(URL,BASE64)
//参数三:hashMap中的基本参数配置(null:使用默认配置)
JSONObject res = client.detect(image, "BASE64", null);
System.out.println(res.toString(2));
}
/**
* 人脸搜索:根据用户上传的图片和指定人脸库中的所有人脸进行比较,
* 获取相似度最高的一个或者某几个的评分
* 说明:返回值(数据,只需要第一条,相似度最高的数据)
* score:相似度评分(80分以上可以认为是同一个人)
*/
@Test
public void testFaceSearch() throws Exception {
//构造图片
String path = "C:\\Users\\资源\\照片\\003.png";
byte[] bytes = Files.readAllBytes(Paths.get(path));
String image = Base64Util.encode(bytes);
//人脸搜索
JSONObject res = client.search(image, "BASE64", "yuriDUAN", null);
System.out.println(res.toString(2));
}
@Test
public void test123() throws Exception {
//构造图片
//人脸搜索
JSONObject res = client.getUser("1000","yuriDUAN",null);
System.out.println(res.toString(2));
}
}
5,该功能加入到我的项目
(1),界面展示
(2),前端代码
<script type="text/javascript">
$(function(){
$("#addEmpBtn").click(function(){
//弹出(新增)模态窗口
$("#editEmpModal").modal({
backdrop:"static"
});
});
});
</script>
<!-- 人脸登陆模态窗口 -->
<div id="editEmpModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="gridSystemModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="gridSystemModalLabel">人脸登陆</h4>
</div>
<div >
<p align="center">
<button class="btn btn-primary" id="open">开启摄像头</button>
<button class="btn btn-default" id="close">关闭摄像头</button>
<button class="btn btn-primary" id="CatchCode">拍照</button>
</p>
<div align="center" style="float: left;">
<video id="video" width="400px" height="400px" autoplay></video>
<canvas id="canvas" width="350" height="350"></canvas>
</div>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- 人脸登陆模态窗口 -->
//登陆按钮
<div style="background: #fafafa;text-align:right">
<button style="background-image:url('/assets/img/avatars/faceLogin.png');width:64px;height:64px;border-style: none;"
id="addEmpBtn">
</button>
</div>
//向后端发送请求
<script type="text/javascript">
var video;//视频流对象
var context;//绘制对象
var canvas;//画布对象
$(function() {
var flag = false;
//开启摄像头
$("#open").click(function() {
//判断摄像头是否打开
if (!flag) {
//调用摄像头初始化
open();
flag = true;
}
});
//关闭摄像头
$("#close").click(function() {
//判断摄像头是否打开
if (flag) {
video.srcObject.getTracks()[0].stop();
flag = false;
}
});
//拍照
$("#CatchCode").click(function() {
if (flag) {
context.drawImage(video, 0, 0, 330, 250);
CatchCode();
} else
alert("请先开启摄像头!");
});
});
//将当前图像传输到后台
function CatchCode() {
//获取图像
var img = getBase64();
//Ajax将Base64字符串传输到后台处理
$.ajax({
type : "POST",
url : "FaceLoginServlet",
data : {
img : img
},
dataType : "JSON",
success : function(data) {
//返回的结果
//取出对比结果的返回分数,如果分数90以上就判断识别成功了
if(parseInt(data.result.user_list[0].score) > 90) {
//关闭摄像头
video.srcObject.getTracks()[0].stop();
//提醒用户识别成功
//alert("验证成功!");
//验证成功跳转页面
//window.location.href="self.jsp";
//异步实现自登陆
$.ajax({
url:"/faceLogin/"+parseInt(data.result.user_list[0].user_id),
type:"get",
success:function (result) {
if(result=="SUC"){
//关闭模态窗
$("#addEmpModal").modal("hide");
location.href="/self";
}else {
alert("数据库中没有您的账号!");
}
}
})
}else {
alert("人脸库中没有您的信息!");
}
},
error : function(q, w, e) {
alert(q + w + e);
}
});
};
//开启摄像头
function open() {
//获取摄像头对象
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
//获取视频流
video = document.getElementById("video");
var videoObj = {
"video" : true
}, errBack = function(error) {
console.log("Video capture error: ", error.code);
};
context.drawImage(video, 0, 0, 330, 250);
//初始化摄像头参数
if (navigator.getUserMedia || navigator.webkitGetUserMedia
|| navigator.mozGetUserMedia) {
navigator.getUserMedia = navigator.getUserMedia
|| navigator.webkitGetUserMedia
|| navigator.mozGetUserMedia;
navigator.getUserMedia(videoObj, function(stream) {
video.srcObject = stream;
video.play();
}, errBack);
}
}
//将摄像头拍取的图片转换为Base64格式字符串
function getBase64() {
//获取当前图像并转换为Base64的字符串
var imgSrc = canvas.toDataURL("image/png");
//截取字符串
return imgSrc.substring(22);
};
</script>
(2),后端代码
package com.dk.oa.controller;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dk.oa.global.FaceSpot;
import org.json.JSONObject;
/**
* Servlet implementation class FaceLoginServlet
*/
public class FaceLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public FaceLoginServlet() {
super();
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.getHeader("textml; charset=UTF-8");
//实例化PrintWriter对象
PrintWriter out = response.getWriter();
String img = request.getParameter("img");
JSONObject js = FaceSpot.searchFace(img, "yuriDuan", "1000");
out.print(js);
}
}
工具栏代码就是上面那位博主的 FaceSpot .java(别忘了引入进来)
控制器层代码
//自登陆
@RequestMapping(value = "/faceLogin/{id}",method = RequestMethod.GET)
@ResponseBody
public String faceLogin(@PathVariable("id")String id,HttpSession session ){
Employee employee = employeeBiz.get(id);
if (employee!=null){
session.setAttribute("employee",employee);
return "SUC";
}else {
return "FAL";
}
}