赞
踩
项目里考勤打卡需要换成人脸识别,主要思路:超级管理员在员工管理处上传员工相对清晰的五官电子一寸照片。然后员工登录自己的账号,在考勤页面点击打卡,浏览器开启电脑摄像头,采集员工脸部信息照片,并且将这个照片与员工之前的电子照进行比对比。
演示视频:【学生考勤系统单人脸采集和多人脸识别和二维码扫描识别身份签到考勤系统展示-杰凡IT】 https://www.bilibili.com/video/BV1fq4y1L77p?p=2&share_source=copy_web&vd_source=ed0f04fbb713154db5cc611225d92156
先来看看实现的效果吧
首先需要百度申请接口,具体这里不在赘述,百度里申请个人开发,人工智能,人脸识别里新建一个应用,可以拿到三个参数, 项目只用到了两个 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; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。