基于百度AI+jquery-webcam+servlet实现人脸识别登录,兼容各主流浏览器

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" οnclick="action('reg');" /> <input type="button" value="登录" id="saveBtn" οnclick="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,未来可能支持3dctx = 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个rgbfor (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像素的图片时发给后端phpif (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/SKpublic 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

 

转载于:https://www.cnblogs.com/guo-eric/p/8371861.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/571239.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

杨辉三角java代码_【LeetCode】118. 杨辉三角(Pascal#x27;s Triangle)解题思路

题目如下&#xff08;题目链接戳我&#xff09;&#xff1a;给定一个非负整数 numRows&#xff0c;生成杨辉三角的前 numRows 行。 备注&#xff1a;在杨辉三角中&#xff0c;每个数是它左上方和右上方的数的和。示例&#xff1a; 输入: 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],…

Django项目创建图解

注&#xff1a;创建完views.py&#xff08;也可以不做编写直接测试&#xff09;就可以运行 python manage.py runserver 来检测服务器是否创建成功了&#xff08;打开浏览器输入提示的网址即可&#xff09; 项目创建解析&#xff1a;http://www.cnblogs.com/monkpy/p/8377190.…

索引会自动更新吗_mysql的B+树中数据存放结构和索引常见问题你会吗?

问题如何理解mysql中 数据存放在B树的叶子节点而不是其他非叶子节点&#xff1f;(InnoDB中)B树的叶子节点一定存放全部的真实数据吗&#xff1f;辅助索引和聚集索引的B树有什么区别&#xff1f;联合索引的B树中数据又有啥区别呢&#xff1f;MyISAM中的索引是什么样的&#xff1…

pandas-事例练习

补充&#xff1a;  DataFrame.dropna(axis0, howany, threshNone, subsetNone, inplaceFalse)功能&#xff1a;根据各标签的值中是否存在缺失数据对轴标签进行过滤&#xff0c;可通过阈值调节对缺失值的容忍度参数&#xff1a;axis : {0 or ‘index’, 1 or ‘columns’},或 …

扒一扒TCP协议与UDP协议

TCP服务的特点 &#xff08;1&#xff09;面向连接&#xff1a;使用TCP协议通讯的双方必须先建立连接&#xff0c;然后才能开始数据的读写。双方都必须为该连接分配必要的内核资源&#xff0c;以管理连接的状态和连接上数据的传输。TCP链接是全双工的&#xff0c;即双方的数据读…

linux 查看共享磁盘_如何可视化地查看 Linux 系统磁盘使用情况?

本文介绍一个可视化地查看 Linux 系统磁盘使用情况的工具——Duc。Duc 是一个工具集&#xff0c;可以在类 Unix 操作系统上建立索引、检查和可视化系统的磁盘。与其它相似工具相比&#xff0c;它可以正常工作在超大规模的文件系统上。测试表明&#xff0c;Duc 可以毫无问题地工…

mysql git下载安装_xshell、python、git、mysql安装(玩阿里云的第二天)

2、因为放弃了图形化桌面&#xff0c;所以要找清自己的位置。不清楚自己刚进去时在哪个目录&#xff0c;先ll、ls、cd ..试试3、python安装安装python失败&#xff0c;同时发现自带了2个python版本(python2.7和python3.6)&#xff1b;卸载python&#xff1a;sudo apt-get remov…

Tomcat端口冲突

在编码时&#xff0c;有时候会一步小心多开了一个tomcat&#xff0c;而且端口也没改&#xff0c;这个时候就会造成端口冲突问题&#xff1a; 解决冲突问题也很简单&#xff1a;打开 dos窗口&#xff1a;netstat -ano|findstr <端口号> 输入netstat -ano|findstr 加上被冲…

vscode html 格式化_详解VSCode 格式化不符合预期的问题

一句话总结不同格式化程序执行时长不一样&#xff0c;导致文件格式好后和预期不符。请务必保持校验&#xff08;Lint&#xff09;规则和格式化&#xff08;Format&#xff09;规则一致&#xff0c;不然格式化后还是不符合预期是非常讨厌的。本篇主要讲解怎么调教VSCode的保存时…

C#总结(四)调用C++动态库

由于公司很多底层的SDK&#xff0c;都是C开发&#xff0c;上层的应用软件却是C# Winform程序。在实际工作的过程中&#xff0c;就经常碰到了C# 程序调用C 动态库的问题。最近一直在和C 打交道&#xff0c;C# 怎么调用C 类库函数。也遇到了一些问题&#xff0c;所以就来总结总结…

mysql外码内码定义_中文编码杂谈(转) - CodeAxe的个人页面 - OSCHINA - 中文开源技术交流社区...

编码问题的例子在windows自带的notepad(记事本)程序中输入“联通”两个字&#xff0c;保存后再次打开&#xff0c;会发现“联通”不见了&#xff0c;代之以“&#xfffd;&#xfffd;ͨ”的乱码。这是windows平台上典型的中文编码问题。即文件保存的时候是按照ANSI编码(其实就…

python re.split_python re模块re.split将字符串分割后返回列表

re.splitsplit 方法按照能够匹配的子串将字符串分割后返回列表&#xff0c;它的使用形式如下&#xff1a;re.split(pattern, string[, maxsplit0, flags0])参数&#xff1a;参数描述pattern匹配的正则表达式string要匹配的字符串。maxsplit分隔次数&#xff0c;maxsplit1 分隔一…

python自动化控制设备有限公司_华为 Python网络自动化

哈喽&#xff0c;大家好&#xff01;我是艺博东 &#xff0c;是一个思科出身、专注于华为的网工&#xff1b;好了&#xff0c;话不多说&#xff0c;我们直接进入正题。光棍二十年&#xff0c;不知道情人节是什么鬼东西。还是好好学技术吧&#xff01;努力、奋斗吧&#xff01;为…

vue组件 Prop传递数据

组件实例的作用域是孤立的。这意味着不能(也不应该)在子组件的模板内直接引用父组件的数据。要让子组件使用父组件的数据&#xff0c;我们需要通过子组件的props选项。 prop 是单向绑定的&#xff1a;当父组件的属性变化时&#xff0c;将传导给子组件&#xff0c;但是不会反过来…

python视图函数是什么意思_Flask初学者:视图函数

视图函数返回html模板&#xff1a;使用“from flask import render_template”&#xff0c;在函数中传入相对于文件夹“templates”html模板路径名称字符串即可&#xff0c;flask会自动到项目根目录的“templates”文件夹(创建flask项目时&#xff0c;pycharm会自动创建两个空文…

kendo Grid json解析的问题

新建立了一个 页面&#xff0c;在grid中使用了dropdownlist&#xff0c;总是显示companyId is not defined &#xff0c;以前这个问题解决过了&#xff0c;忘记记录了额&#xff0c;现在不知道怎么办了 下面的这个解决方法是错误的razor语法中的renderScript移动到scrip前面去解…

人工蜂群算法python_教程 | 用人工蜂群算法求解k-分区聚类问题

原标题&#xff1a;教程 | 用人工蜂群算法求解k-分区聚类问题选自towarddatascience作者&#xff1a;Pedro Buarque参与&#xff1a;Pedro、刘晓坤群体智能算法是一类受生物群体智能行为的启发而发展出来的算法&#xff0c;社会性动物例如蚂蚁、蜜蜂、鱼等&#xff0c;个体的简…

java遍历树_Java实现遍历N级树形目录结构

最近挺忙&#xff0c;一直在做项目&#xff0c;然后有个树形目录结构需要返回给前端&#xff0c;这里给大家说一下实现的思路。具体达到的效果类似&#xff1a;一级目录A&#xff1a;二级目录A&#xff1a;三级目录&#xff1a;四级目录&#xff1a;文件.txt二级目录B&#xff…

python_fullstack基础(十八)-并发编程

并发编程 一、进程 1、理论背景 ①操作系统背景 手工操作—穿孔卡片 原理&#xff1a;用户独占计算机&#xff0c;CPU等待手工操作&#xff0c;资源利用和CPU利用效率极低批处理—磁带处理、批处理系统 原理&#xff1a;主机与输入机之间增加磁带存储设备&#xff0c;使得计算机…

20165218 学习基础和C语言基础调查

个人技能及阅读心得 个人技能之绘画绘画是我从很小便开始接触的&#xff0c;从最初的简笔画到国画、素描、水粉&#xff0c;大约也学了七八年。但是到了高中之后&#xff0c;就逐渐放下了。 记得当初学素描时&#xff0c;老师的一句话让我记忆犹新&#xff0c;她说&#xff0c;…