java基于springboot的人脸识别企业排班考勤系统之人脸识别模块的设计和实现

java基于springboot的人脸识别企业排班考勤系统之人脸识别模块的设计和实现-飞一样的编程
飞一样的编程
擅长邻域:Java,MySQL,Linux,nginx,springboot,mongodb,微信小程序,vue

2020-10-13 15:12:41   530浏览 分类: Java

项目里考勤打卡需要换成人脸识别,主要思路:超级管理员在员工管理处上传员工相对清晰的五官电子一寸照片。然后员工登录自己的账号,在考勤页面点击打卡,浏览器开启电脑摄像头,采集员工脸部信息照片,并且将这个照片与员工之前的电子照进行比对比。

先来看看实现的效果吧




首先需要百度申请接口,具体这里不在赘述,百度里申请个人开发,人工智能,人脸识别里新建一个应用,可以拿到三个参数, 项目只用到了两个 API Key 和clientSecret

在调用接口之前,需要获取AccessToke,AccessToke有效期是一个月,然后根据AccessToke去调用人脸匹配接口。

第一步:获取AccessToke,这个百度有api文档,里面也写得很轻清楚了,需要API Key 和clientSecret去获取得到,代码如下:
public class AuthService {


public static String getAuth() {
// 官网获取的 API Key 更新为你注册的
String clientId = " ";
// 官网获取的 Secret Key 更新为你注册的
String clientSecret = " ";
return getAuth(clientId, clientSecret);
}


public static String getAuth(String ak, String sk) {
// 获取token地址
String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
String getAccessTokenUrl = authHost
// 1. grant_type为固定参数
+ "grant_type=client_credentials"
// 2. 官网获取的 API Key
+ "&client_id=" + ak
// 3. 官网获取的 Secret Key
+ "&client_secret=" + sk;
try {
URL realUrl = new URL(getAccessTokenUrl);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.err.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String result = "";
String line;
while ((line = in.readLine()) != null) {
result += line;
}
/**
* 返回结果示例
*/
System.err.println("result:" + result);
JSONObject jsonObject = new JSONObject(result);

String access_token = jsonObject.getString("access_token");
return access_token;
} catch (Exception e) {


System.err.printf("获取token失败!重新获取");
e.printStackTrace(System.err);
}
return null;
}

public static void main(String[] args) {
System.out.println(getAuth());
}
第二部,调用照片匹配的接口并封装,代码如下:
参数说明img1和img2都是base64的格式,把两张需要对比的照片穿进去,返回值大于80说明比配成功,否则不是同一个人哦
/**
* 人脸对比
*/
public class FaceMatch {

public static String faceMatch(String img1,String img2) {
// 请求url
String url = "https://aip.baidubce.com/rest/2.0/face/v3/match";
try {
List pli=new ArrayList();
Map<String, Object> map = new HashMap<>();
map.put("image", img1);
map.put("image_type", "BASE64");
map.put("face_type", "LIVE");
map.put("quality_control", "LOW");
map.put("liveness_control", "HIGH");
pli.add(map);

map = new HashMap<>();
map.put("image", img2);
map.put("image_type", "BASE64");
map.put("face_type", "LIVE");
map.put("quality_control", "LOW");
map.put("liveness_control", "HIGH");
pli.add(map);



String param = new org.json.JSONArray(pli).toString();



String accessToken=AuthService.getAuth();//获取accessToken,有效期一个月,这里需要宁外做处理,我是直接调用了
String result = HttpUtil.post(url, accessToken, "application/json", param);
// System.out.println(result);

JSONObject jsonObject = new JSONObject(result);
JSONObject obj=(JSONObject) jsonObject.get("result");

return obj.get("score").toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}

}
第三部,写前端页面调用浏览器摄像头,并把摄像头采集到人脸照片以base64的方式传给后台,这个是我自己的jsp页面代码,直接复制应该是不可以用的,但是里面html5调用摄像头的可以参考使用哦。

注意:如果您的摄像头打开很黑,有可能是您的电脑摄像头坏掉了(脸都拍不清楚,肯定识别不了),这个不是代码的问题哦,我用的360和谷歌浏览器测试均可打开摄像头的。

代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html dir="ltr" lang="en">

<head>
<%@ include file="common.jsp"%>
</head>

<body>
<!-- ============================================================== -->
<!-- Preloader - style you can find in spinners.css -->
<!-- ============================================================== -->
<div class="preloader">
<div class="lds-ripple">
<div class="lds-pos"></div>
<div class="lds-pos"></div>
</div>
</div>
<!-- ============================================================== -->
<!-- Main wrapper - style you can find in pages.scss -->
<!-- ============================================================== -->
<div id="main-wrapper" data-navbarbg="skin6" data-theme="light" data-layout="vertical" data-sidebartype="full" data-boxed-layout="full">
<!-- ============================================================== -->
<!-- Topbar header - style you can find in pages.scss -->
<!-- ============================================================== -->
<%@ include file="leftmenu.jsp"%>
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- Page wrapper -->
<!-- ============================================================== -->
<div class="page-wrapper">
<!-- ============================================================== -->
<!-- Bread crumb and right sidebar toggle -->
<!-- ============================================================== -->

<!-- ============================================================== -->
<!-- End Bread crumb and right sidebar toggle -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- Container fluid -->
<!-- ============================================================== -->
<div class="container-fluid">
<!-- ============================================================== -->
<!-- Start Page Content -->
<!-- ============================================================== -->
<!-- Row -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<h4 class="card-title" style="text-align: center;">上下班请记得打卡哦</h4>

</div>

<div class="container" style="text-align: center;">

<span id="clockin" class="mdi mdi-cloud-print" style="font-size: 10em"></span>
<video id="video" width="480" height="320" style="display:none;"> </video>
<p id="video_tip" style="display:none;">脸部识别中,请正脸看向摄像头,<span id="ts"></span></p>
<canvas id="canvas" width="480" height="320" style="display:none;"></canvas>
<p id="result"></p>
</div>
</div>

</div>

</div>
<!-- Row -->
<!-- ============================================================== -->
<!-- End PAge Content -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- Right sidebar -->
<!-- ============================================================== -->
<!-- .right-sidebar -->
<!-- ============================================================== -->
<!-- End Right sidebar -->
<!-- ============================================================== -->
</div>
<!-- ============================================================== -->
<!-- End Container fluid -->
<!-- ============================================================== -->
<!-- ============================================================== -->
</div>
<!-- ============================================================== -->
<!-- End Page wrapper -->
<!-- ============================================================== -->
</div>

</body>



<script type="text/javascript">
var t=5;
$('#clockin').click(function(){
$('#clockin').hide();
$('#video,#video_tip').show();
var inv=setInterval(function(){
$('#ts').text(t+'s');
if(t<0){
t=5;
context.drawImage(video, 0, 0, 480, 320);
$('#canvas').show();
$('#clockin,#video,#video_tip').hide();
clearInterval(inv);
matchface();
}
t--;
}, 1000);
})
function matchface(){
$.ajax({
type:"post",
url:"${ctx}/clockin/faceadd",
dataType:"json",
data: {
faceimg:getBase64()
} , success:function(data){
if(data.status==1){
$('#result').text(data.msg).css('color','green');
} else{
alert(data.msg);
window.location.reload();
}
},fail:function(data){
alert('请检查网络');
window.location.reload();
}
})
}
//访问用户媒体设备的兼容方法
function getUserMedi1;

};

</script>
</html>
第四部:调用后台照片匹配接口,给前端返回结果,代码如下:
@ResponseBody
@RequestMapping("/faceadd")
public Object faceadd(@RequestParam(value="pageNo",defaultValue="1")int pageNo,ScClockin o,Model model,HttpSession session,String faceimg,
HttpServletRequest request) throws Exception {

String isbenren=FaceMatch.faceMatch(faceimg(刚刚前端摄像头拍摄的照片的buse64格式数据),“该员工之前的一寸电子照片的base64格式数据”);
if(isbenren==null){
m.put("status", "0");
m.put("msg","脸部信息匹配失败,重新签到");
return m;
}
double br=Double.parseDouble(isbenren);
if(br<80){
m.put("status", "0");
m.put("msg","签到失败,不是本人");
return m;
}

return m;

}
希望以下代码给你提供一点思路,解决你目前小小的疑惑。

好文章就要一起分享哦!分享海报

此处可发布评论

评论(0

暂无评论,快来写一下吧
客服QQ 1913284695