思路:
注意:
1、注册百度账号,申请API
2、项目中引入百度SDK
官方文档:https://ai.baidu.com/ai-doc/FACE/Lk37c1tpf
<!-- 人脸识别 sdk-->
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.15.1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
3、人脸识别工具类 FaceUtil.java
import com.baidu.aip.face.AipFace;
import com.baidu.aip.util.Base64Util;
/**
* Desc: 人脸识别工具
*/
public class FaceUtil {
private static final String APP_ID = "";
private static final String APP_KEY = "";
private static final String SECRET_KEY = "";
private static volatile AipFace client = new AipFace(APP_ID, APP_KEY, SECRET_KEY);
public static AipFace getClient(){
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);
return client;
}
/**
* 编码
*/
public static String encodeBase64(byte[] form){
return Base64Util.encode(form);
}
/**
* 解码
*/
public static byte[] decodeBase64(String data){
return Base64Util.decode(data);
}
}
人脸检测管理 FaceManage.java
import com.alibaba.fastjson.JSON;
import com.baidu.aip.face.FaceVerifyRequest;
import com.baidu.aip.face.MatchRequest;
import com.kaxinkeji.im.common.face.constant.ActionTypeEnum;
import com.kaxinkeji.im.common.face.constant.FaceConstant;
import com.kaxinkeji.im.common.face.constant.LivenessControlEnum;
import com.kaxinkeji.im.common.face.constant.QualityControlEnum;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Objects;
@Service
public class FaceManage {
private static final Logger logger = LoggerFactory.getLogger(FaceManage.class);
/**
* 人脸注册
*/
public static void faceRegister(FaceUserDTO userDTO, ImageU imageU) {
// 传入可选参数调用接口
HashMap<String, String> options = new HashMap<String, String>();
// 用户资料
options.put("user_info", JSON.toJSONString(userDTO));
// 图片质量
options.put("quality_control", QualityControlEnum.LOW.name());
// 活体检测控制
options.put("liveness_control", LivenessControlEnum.NONE.name());
// 操作方式
options.put("action_type", ActionTypeEnum.REPLACE.name());
String image = imageU.getData();
String imageType = imageU.getImageTypeEnum().name();
String groupId = userDTO.getGroupId();
String userId = userDTO.getUserId();
// 人脸注册
JSONObject res = FaceUtil.getClient().addUser(image, imageType, groupId, userId, options);
FaceResultUtil.isSuccess(res);
logger.info("人脸注册成功");
}
/**
* 人脸更新
*/
public static void faceUpdate(FaceUserDTO userDTO, ImageU imageU) {
HashMap<String, String> options = new HashMap<String, String>();
// 用户资料
options.put("user_info", JSON.toJSONString(userDTO));
// 图片质量
options.put("quality_control", QualityControlEnum.LOW.name());
// 活体检测控制
options.put("liveness_control", LivenessControlEnum.NONE.name());
// 操作方式
options.put("action_type", ActionTypeEnum.REPLACE.name());
String image = imageU.getData();
String imageType = imageU.getImageTypeEnum().name();
String groupId = userDTO.getGroupId();
String userId = userDTO.getUserId();
// 人脸更新
JSONObject res = FaceUtil.getClient().updateUser(image, imageType, groupId, userId, options);
FaceResultUtil.isSuccess(res);
logger.info("人脸更新成功 {}", res.toString(2));
}
/**
* 人脸删除
*/
public static void faceDelete(String userId, String groupId, String faceToken) {
// 传入可选参数调用接口
HashMap<String, String> options = new HashMap<String, String>();
// 人脸删除
JSONObject res = FaceUtil.getClient().faceDelete(userId, groupId, faceToken, options);
FaceResultUtil.isSuccess(res);
logger.info("人脸删除成功 {}", res.toString(2));
}
/**
* 用户信息查询
*/
public static FaceUserDTO<String> findUser(String userId, String groupId) {
HashMap<String, String> options = new HashMap<>();
// 用户信息查询
JSONObject res = FaceUtil.getClient().getUser(userId, groupId, options);
FaceResult result = FaceResultUtil.isSuccess(res);
return JSON.parseObject(result.getData().toJSONString(), FaceUserDTO.class);
}
/**
* 获取用户人脸列表
*
* @throws Exception
*/
public static FaceResult faceGetList(String userId, String groupId) {
HashMap<String, String> options = new HashMap<String, String>();
// 获取用户人脸列表
JSONObject res = FaceUtil.getClient().faceGetlist(userId, groupId, options);
return FaceResultUtil.isSuccess(res);
}
/**
* 获取用户列表
*/
public static FaceResult listUserByGroupId(String groupId) {
HashMap<String, String> options = new HashMap<String, String>();
options.put("start", "0");
options.put("length", "50");
// 获取用户列表
JSONObject res = FaceUtil.getClient().getGroupUsers(groupId, options);
return FaceResultUtil.isSuccess(res);
}
/**
* 删除用户
*/
public static void deleteUser(String userId, String groupId) {
HashMap<String, String> options = new HashMap<String, String>();
// 删除用户
JSONObject res = FaceUtil.getClient().deleteUser(groupId, userId, options);
FaceResultUtil.isSuccess(res);
logger.info("用户删除成功 {}", res.toString(2));
}
/**
* 创建用户组
*/
public static void addGroup(String groupId) {
HashMap<String, String> options = new HashMap<String, String>();
// 创建用户组
JSONObject res = FaceUtil.getClient().groupAdd(groupId, options);
FaceResultUtil.isSuccess(res);
logger.info("创建用户组 {}", res.toString(2));
}
/**
* 删除用户组
*/
public static void deleteGroup(String groupId) {
HashMap<String, String> options = new HashMap<String, String>();
// 删除用户组
JSONObject res = FaceUtil.getClient().groupDelete(groupId, options);
FaceResultUtil.isSuccess(res);
logger.info("删除用户组 {}", res.toString(2));
}
/**
* 组列表查询
*/
public static FaceResult listGroup() {
HashMap<String, String> options = new HashMap<String, String>();
options.put("start", "0");
options.put("length", "50");
// 组列表查询
JSONObject res = FaceUtil.getClient().getGroupList(options);
return FaceResultUtil.isSuccess(res);
}
/**
* 身份验证
*/
public static FaceResult personVerify(String idCardNumber, String realName, ImageU imageU) {
HashMap<String, String> options = new HashMap<String, String>();
options.put("quality_control", QualityControlEnum.LOW.name());
options.put("liveness_control", LivenessControlEnum.NONE.name());
// 身份验证
JSONObject res = FaceUtil.getClient().personVerify(imageU.getData(), imageU.getImageTypeEnum().name(), idCardNumber, realName, options);
return FaceResultUtil.isSuccess(res);
}
/**
* 人脸对比
*/
public static int faceMatchScore(ImageU imageU1, ImageU imageU2) {
MatchRequest req1 = new MatchRequest(imageU1.getData(), imageU1.getImageTypeEnum().name());
MatchRequest req2 = new MatchRequest(imageU2.getData(), imageU2.getImageTypeEnum().name());
ArrayList<MatchRequest> requests = new ArrayList<MatchRequest>();
requests.add(req1);
requests.add(req2);
JSONObject res = FaceUtil.getClient().match(requests);
FaceResult result = FaceResultUtil.isSuccess(res);
// 对结果进行特殊处理
Integer score = result.getData().getInteger(FaceConstant.SCORE);
return score == null ? 0 : score;
}
/**
* 人脸是否对比成功
*
* @param imageU1
* @param imageU2
* @param score 匹配分数
* @return
*/
public static boolean isfaceMatch(ImageU imageU1, ImageU imageU2, Integer score) {
int defaultScore = FaceConstant.MATCH_SCORE;
if (Objects.nonNull(score)) {
defaultScore = score;
}
return faceMatchScore(imageU1, imageU2) > defaultScore ? true : false;
}
/**
* 人脸检测
*/
public static FaceResult faceDetect(ImageU imageU) {
HashMap<String, String> options = new HashMap<String, String>();
options.put("face_field", "age");
options.put("max_face_num", "2");
options.put("face_type", "LIVE");
// 人脸检测
JSONObject res = FaceUtil.getClient().detect(imageU.getData(), imageU.getImageTypeEnum().name(), options);
return FaceResultUtil.isSuccess(res);
}
/**
* 人脸搜索
*/
public static FaceResult faceSearch(String groupIds, ImageU imageU) {
HashMap<String, String> options = new HashMap<String, String>();
options.put("max_face_num", "1");
options.put("max_user_num", "1");
options.put("quality_control", QualityControlEnum.LOW.name());
options.put("liveness_control", LivenessControlEnum.NONE.name());
// 人脸搜索
JSONObject res = FaceUtil.getClient().search(imageU.getData(), imageU.getImageTypeEnum().name(), groupIds, options);
return FaceResultUtil.isSuccess(res);
}
/**
* 活体检测
*/
public static FaceResult faceverify(ImageU imageU) {
FaceVerifyRequest req = new FaceVerifyRequest(imageU.getData(), imageU.getImageTypeEnum().name());
ArrayList<FaceVerifyRequest> list = new ArrayList<FaceVerifyRequest>();
list.add(req);
JSONObject res = FaceUtil.getClient().faceverify(list);
return FaceResultUtil.isSuccess(res);
}
}
window.onload = function (){
try{
document.createElement("canvas").getContext("2d");
document.getElementById("support").innerHTML = "浏览器支持HTML5 CANVAS";
}catch(e){
document.getElementById("support").innerHTML = "浏览器不支持HTML5 CANVAS";
}
};
//这段代 主要是获取摄像头的视频流并显示在Video 签中
window.addEventListener("DOMContentLoaded", function () {
var video = document.getElementById("video");
var videoObj = { "video": true };
var errBack = function (error){
console.log("Video capture error: " + error.message, error.code);
};
// 支持浏览器 谷歌,火狐,360,欧朋
// debugger;
var constraints = { audio: true, video: { width: 1280, height: 720 } };
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
var video = document.querySelector('video');
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
video.play();
};
})
.catch(function(err) { console.log(err.name + ": " + err.message); }); // always check for errors at the end.
// navigator.getUserMedia = navigator.getUserMedia ||
// navigator.webkitGetUserMedia ||
// navigator.mozGetUserMedia;
//
//
// if (navigator.getUserMedia) {
// navigator.getUserMedia({
// audio: true,
// video: {
// width: 1280,
// height: 720
// }
// },
// function(stream) {
// var video = document.querySelector('video');
// video.srcObject = stream;
// video.onloadedmetadata = function(e) {
// video.play();
// };
// },
// function(err) {
// alert("The following error occurred: " + err.name);
// }
// );
// } else {
// var div = document.createElement("div");
// div.innerHTML = 'getUserMedia not supported';
// document.body.appendChild(div);
// alert("getUserMedia not supported");
// }
//这个是拍照按钮的事件,
document.getElementById("snap").addEventListener("click",function(){
CatchCode();
});
}, false);
function dataURItoBlob (base64Data) {
var byteString;
if (base64Data.split(',')[0].indexOf('base64') >= 0)
byteString = atob(base64Data.split(',')[1]);
else
byteString = unescape(base64Data.split(',')[1]);
var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0];
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type: mimeString});
};
//定时器
//var interval = setInterval(CatchCode, "300");
function CatchCode() {
var canvans = document.getElementById("canvas");
var video = document.getElementById("video");
var context = canvas.getContext("2d");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
context.drawImage(video,0,0);
var base64Data = canvans.toDataURL("image/jpeg", 0.3);
//封装blob对象
var blob = dataURItoBlob(base64Data);
var formdata = new FormData();
formdata.append("file", blob);
$.ajax({
url: "/api/login_face",
type: "post",
data:formdata,
processData: false,
contentType: false,
success: function (data) {
console.log(data);
},
error:function(err){
alert("服务器错误");
}
});
}