1、注册百度AI账号,获取到AI开发资格
详情参见个人博客:你的第一个人脸识别demo(http://www.cnblogs.com/guo-eric/p/8109411.html)
2、环境准备
首先按照第一步说明将百度的AI类文件和用到的三方类文件下载到本地,需要的文件有:
然后从jquery-webcam官网下载操作摄像头的插件:
下载地址:https://www.xarg.org/project/jquery-webcam-plugin/
下载后解压文件:
最后将jquery的js文件引入,我这里用的是1.8.3:如上面截图所示
3、前端页面开发:采用jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta charset="utf-8"> <title>jQuery-webcam-master</title> <script src="js/jquery-1.8.3.min.js"></script> <script type="text/javascript" src="js/jquery.webcam.min.js"></script> <style type="text/css"> #webcam { border: 1px solid #666666; width: 320px; height: 240px; } #photos { border: 1px solid #666666; width: 320px; height: 240px; } .btn { width: 320px; height: auto; margin: 5px 0px; } .btn input[type=button] { width: 150px; height: 50px; line-height: 50px; margin: 3px; } </style> </head> <body> <input type="text" id="uid" value=""> <div id="webcam"></div> <div class="btn"> <input type="button" value="注册" id="regBtn" onclick="action('reg');" /> <input type="button" value="登录" id="saveBtn" onclick="action('login');" /> </div> <div id="photos"> <img src="" id="img"> </div> </body> <script type="text/javascript"> $(document).ready(function() { var pos = 0, ctx = null, saveCB, image = []; //创建画布指定宽度和高度 var canvas = document.createElement("canvas"); canvas.setAttribute('width', 320); canvas.setAttribute('height', 240); //如果画布成功创建 if (canvas.toDataURL) { //设置画布为2d,未来可能支持3d ctx = canvas.getContext("2d"); //截图320*240,即整个画布作为有效区(cutx?) image = ctx.getImageData(0, 0, 320, 240); saveCB = function(data) { //把data切割为数组 var col = data.split(";"); var img = image; //绘制图像(这里不是很理解算法) //参数data 只是每行的数据 ,例如320*240 大小的照片,一张完整的照片下来需要240个data,每个data有320个rgb for (var i = 0; i < 320; i++) { //转换为十进制 var tmp = parseInt(col[i]); img.data[pos + 0] = (tmp >> 16) & 0xff; img.data[pos + 1] = (tmp >> 8) & 0xff; img.data[pos + 2] = tmp & 0xff; img.data[pos + 3] = 0xff; pos += 4; } //当绘制320*240像素的图片时发给后端php if (pos >= 4 * 320 * 240) { //把图像放到画布上,输出为png格式 ctx.putImageData(img, 0, 0); //alert('图片保存成功'); $.ajax({ url : 'upload.do?method='+method+'&uid='+$('#uid').val(), type : "POST", dataType : 'json', async : false, data : {image : canvas.toDataURL("image/png")}, success : function(data) { alert(data.flag+'---'+data.message); var msg = data.message; if (msg != "success") { resultflag=false; } }, error : function(error) { tip('访问数据异常', '异常提示'); return true; } }); /* $.post("upload.do", { type : "data", image : canvas.toDataURL("image/png"), function(data,status){ alert("Data: " + data + "\nStatus: " + status); } }); */ pos = 0; } }; } else { saveCB = function(data) { //把数据一点点的放入image[] image.push(data); pos += 4 * 320; if (pos >= 4 * 320 * 240) { $.post("upload.do", { type : "pixel", image : image.join('|') }); pos = 0; } }; } // /** // * 获取canvas画布的内容 getImageData // * 内容放回到canvas画布 putImageData // * 获取ImgData的每一个像素 ImgData.data // * getImageData(起始点的横坐标, 起始点的纵坐标, 获取的宽度, 获取的高度) // * putImageData(绘制点的横坐标, 绘制点点纵坐标, imgData的起始点横坐标, imgData的起始点纵坐标, 宽度, 高度) // */ $("#webcam").webcam({ width : 320, height : 240, mode : "callback", swffile : "js/jscam_canvas_only.swf", onTick : function(remain) { if (0 == remain) { jQuery("#status").text("Cheese!"); } else { jQuery("#status").text(remain + " seconds remaining..."); } }, onSave : saveCB, onCapture : function() { webcam.save(); }, debug : function(type, string) { console.log(type + ": " + string); } }); }); //拍照 //var iCount = setInterval(action,10000);//循环执行 //var i = 1; var method = 'login'; function action(action) { var uid = $('#uid').val(); if('' == uid){ alert('uid不能为空'); return ; } if(action != null){ method = action; } /* if(i == 1){ clearInterval(iCount); } */ webcam.capture(); } </script> </script> </html>
4、servlet接收传经来的base64编码的图片文件,并进行登录和注册的处理
package com.hengyunsoft.face.login; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.json.JSONObject; import sun.misc.BASE64Decoder; import com.baidu.aip.face.AipFace; import com.hengyunsoft.face.aip.FaceManage; /** * Servlet implementation class UploadFile */ @WebServlet("/upload.do") public class Login extends HttpServlet { private static final long serialVersionUID = 1L; //设置APPID/AK/SK public static final String APP_ID = "10580034"; public static final String API_KEY = "CUEBLydMIEhyHXGgjuBLMCDx"; public static final String SECRET_KEY = "xPATdkt3lpn0TiWZyGtfUs1rYrN5HgI6"; /** * @see HttpServlet#HttpServlet() */ public Login() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { uploadPhoto(request, response); } catch (Exception e) { e.printStackTrace(); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } /** * 功能描述:拍照并上传图片 * * @since 2016/5/24 */ public void uploadPhoto(HttpServletRequest req, HttpServletResponse resp) throws Exception { resp.setContentType("application/text; charset=utf-8"); String basePath = "upload/" + getDate("yyyyMMdd") + "/"; String filePath = req.getSession().getServletContext().getRealPath("/") + basePath; String fileName = getDate("yyyyMMddHHmmss") + ".png"; //默认传入的参数带类型等参数:data:image/png;base64, PrintWriter out = resp.getWriter(); JSONObject j = new JSONObject(); String imgStr = req.getParameter("image"); String uid = req.getParameter("uid"); String method = req.getParameter("method"); if (null != imgStr) { imgStr = imgStr.substring(imgStr.indexOf(",") + 1); } //文件上传到服务器 Boolean flag = GenerateImage(imgStr, filePath, fileName); String message = "没有检测到图片"; if (flag) { //拿到base64编码的图片,就可以调用百度的API进行验证 AipFace client = new AipFace(APP_ID, API_KEY, SECRET_KEY); if(method.equals("login")){ message = login(filePath, fileName, j, uid, client); }else if (method.equals("reg")) { message = register(filePath, fileName, j, uid, client); } } j.put("message", message); out.write(j.toString()); } /** * 登录 * * @param filePath * @param fileName * @param j * @param uid * @param client * @return */ private String login(String filePath, String fileName, JSONObject j, String uid, AipFace client) { String message; double matchPercent = FaceManage.verifyUser(client, filePath + fileName,uid); if (matchPercent > 90) { System.out.println("验证成功,人脸匹配度是:"+matchPercent); j.put("flag", true); message = "验证成功,人脸匹配度是:"+matchPercent; }else{ System.out.println("验证失败,人脸匹配度是:"+matchPercent); j.put("flag", false); message = "验证失败,人脸匹配度是:"+matchPercent; } return message; } /** * 注册 * * @param filePath * @param fileName * @param j * @param uid * @param client * @return */ private String register(String filePath, String fileName, JSONObject j, String uid, AipFace client) { String message; int matchPercent = FaceManage.addUser(client, filePath + fileName,uid); if (matchPercent == 1) { System.out.println("注册成功"); j.put("flag", true); message = "注册成功"; }else{ System.out.println("注册失败"); j.put("flag", false); message = "注册失败"; } return message; } /** * 功能描述:base64字符串转换成图片 * * @since 2016/5/24 */ public boolean GenerateImage(String imgStr, String filePath, String fileName) { try { if (imgStr == null) { return false; } BASE64Decoder decoder = new BASE64Decoder(); //Base64解码 byte[] b = decoder.decodeBuffer(imgStr); //如果目录不存在,则创建 File file = new File(filePath); if (!file.exists()) { file.mkdirs(); } //生成图片 OutputStream out = new FileOutputStream(filePath + fileName); out.write(b); out.flush(); out.close(); return true; } catch (Exception e) { System.out.println("生成图片异常:{}"+e.getMessage()); return false; } } public String getDate(String pattern){ return new SimpleDateFormat(pattern).format(new Date()); } }
其中web.xml的配置如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>AipFaceSys</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>UploadFile</servlet-name> <servlet-class>com.hengyunsoft.UploadFile</servlet-class> </servlet> <servlet-mapping> <servlet-name>UploadFile</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
其中servlet中用到的FaceManage等类,都在 博客:你的第一个人脸识别demo((http://www.cnblogs.com/guo-eric/p/8109411.html)中有明确说明,有问题,请联系我,和大家一起学习进步!
FAQ:
倘若浏览器报错了:提示webcam.capture is not a function ,这是因为jquery-webcam必须用在项目中,才能够正常使用。
如果IE浏览器中摄像头显示不出来,需要按照以下操作设置:
1)合理设置浏览器,启用flash的正确方法:
Internet Explorer,设置,安全,禁用ActiveX筛选(去掉勾)
2)管理加载项,启用Shockwave Flash Object