调用百度人脸AI接口实现人脸识别(深层次算法属于BaiduAI,研究整个流程仍是花了一些时间,毕竟是新东西)前端
首先咱们先从获取摄像头中的人脸开始python
一开始我在想一会儿就想到的方法,openvc来调用摄像头获取人脸照片
可是这是针对网页应用,若是能经过前端获取带有人脸的照片不更好吗?把负载加到用户浏览器处
因此就有了下面的js代码nginx
$(document).ready(function () { var video = document.getElementById('video'), canvas = document.getElementById('canvas'), regButton = document.getElementById('regButton'), student_id = document.getElementById('student'), vendorUrl = window.URL || window.webkitURL; //媒体对象 // 老的浏览器可能根本没有实现 mediaDevices,因此咱们能够先设置一个空的对象 if (navigator.mediaDevices === undefined) { navigator.mediaDevices = {}; } // 一些浏览器部分支持 mediaDevices。咱们不能直接给对象设置 getUserMedia // 由于这样可能会覆盖已有的属性。这里咱们只会在没有getUserMedia属性的时候添加它。 if (navigator.mediaDevices.getUserMedia === undefined) { navigator.mediaDevices.getUserMedia = function (constraints) { // 首先,若是有getUserMedia的话,就得到它 var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia; // 一些浏览器根本没实现它 - 那么就返回一个error到promise的reject来保持一个统一的接口 if (!getUserMedia) { return Promise.reject(new Error('getUserMedia is not implemented in this browser')); } // 不然,为老的navigator.getUserMedia方法包裹一个Promise return new Promise(function (resolve, reject) { getUserMedia.call(navigator, constraints, resolve, reject); }); } } navigator.mediaDevices.getUserMedia({ audio: false, video: { 'facingMode': "user" } }) .then(function (stream) { var video = document.querySelector('video'); // 旧的浏览器可能没有srcObject if ("srcObject" in video) { video.srcObject = stream; } else { // 防止在新的浏览器里使用它,由于它已经再也不支持了 video.src = window.URL.createObjectURL(stream); } video.onloadedmetadata = function (e) { video.play(); }; }) .catch(function (err) { console.log(err.name + ": " + err.message); }); regButton.addEventListener('click', function () { //绘制canvas图形 canvas.getContext('2d').drawImage(video, 0, 0, 400, 300); //把canvas图像转为img图片 var data = { img: canvas.toDataURL("image/png"), student_id: student_id.value } $.ajax( { type: 'POST', url: '../checkReg', data: JSON.stringify(data), dataType: "json", complete: function(res){ console.log(res); if (res.responseJSON) { alert(res.responseJSON.msg); } else { alert("服务端发生错误") } } } ) }); })
这里咱们使用navigator来调用摄像头设备并经过canvas将video对象绘制成图片
再经过post传给后端就好了,这里采用了base64的方式
同时百度接口也只接受base64格式的图片,至此获取图片步掫咱们已经完成了web
后端接收到图像以后,通过一些必要的过滤措施
就能够向百度接口post数据了,可是咱们首先要注意的就是把前端的图像处理一下data,base64数据须要删除","以后的数据
base64.b64decode(image.split(',')[-1])
其余的咱们都直接放置到config文件中,方便维护和调用,具体代码以下ajax
client = current_app.config['CLIENT'] image = base64.b64decode(image.split(',')[-1]) det_options = current_app.config['DETOPTIONS'] check_image = client.detect(image, det_options) if check_image['result'][0]['face_probability'] != 1: return jsonify({"status": False, 'msg': "请对准人脸"}) groupId = current_app.config['GROUP_ID'] add_options = current_app.config['ADDOPTIONS'] userInfo = '' result = client.addUser(result_id, userInfo, groupId, image, add_options) if 'error_code' in result: return jsonify({"status": False, 'msg': "请检查是否对准了摄像头"}) check_stu_num.log_id = result['log_id'] if check_stu_num.log_id: return jsonify({"status": True, 'msg': "人脸更新成功"}) else: return jsonify({"status": True, 'msg': "注册成功"})
其实咱们需求很简单,就是在图片中对比人脸库里的人脸识别出来他是谁,使用百度AI有点大材小用的感受
咱们能够本身使用opencv的相关第三方库来实现的,也能够是使用一些简单的机器学习算法来实现
(懒字当头,固然使用这两个的前提是你要去先熟悉一下他们~)算法
这里采用了nginx记录x-header-ip数据来实现真实IP检测
在nginx配置里set一个X-Real-Ip,后端就可使用request.header['X-Real-Ip']来获取IP地址了
一些基础的IP伪造仍是能够过滤掉的数据库
这里是经过判断用户的sign_status字段值和目前签到距离上次签到的时间来判断是否上次签出了和此次是不是签出动做
关键代码以下:json
```python if user.sign_statue and now_time-user.signlogs[-1].signtime < timedelta(days=1): user.sign_statue = False return jsonify({"status": True, 'msg': user.name+"\n您签出成功了~"}) elif not user.sign_statue: user.sign_statue = True return jsonify({"status": True, 'msg': user.name+"\n您签到成功了~\n记得签出!!!!!!!!!"}) else: user.sign_statue = True return jsonify({"status": False, 'msg': user.name+"\n您上次值班没有签出~\n就先放过你,下次别忘了哦~\n签到成功~"}) ```
就是一个对数据库查询和对xls文件写入的操做
而后为了办公方便,读取传入的指定days来肯定要下载的天数
而后为了省事,也就是办公只须要签到历史,就采用了文件直接下载的形式
抛却了后台,只是构造密码形式的路由就好了
类似的,用户的录入也是同理只是对xls的读取操做罢了~canvas
for user in users: for user_signlog in user.signlogs: now_time = datetime.now() if not now_time-user_signlog.signtime < timedelta(hours=20*int(days)): continue ... data.save(current_app.config['SIGN_LOGS_CONTENS']+r'/result.xls') return send_from_directory(current_app.config['SIGN_LOGS_CONTENS'], 'result.xls')
刚才已经说了一个摄像头的调用
固然也会在前端实时显示摄像头以便用户拍照操做
而后也是采用了相似微信登录页面的样式(或许是为了懒省事)
中间的盒子模型,定义一下各类元素的位置和大小(后期维护能够根据须要调整)后端
这个动做我正在添加loading界面
以防用户不断的点击button按钮,来催促网页有回显
PS:数据库的创建是一对多的形式形式