人脸识别技术在当下已经十分成熟,但主要在移动端应用上较为普及,而在Web端并不多见。
本文介绍在Web端人脸识别的简单实现。
Web端人脸识别主要有三个技术思路:1.前端的人脸识别,例如使用Tensorflow.js,2.后台人脸识别,有很多开源或者免费的SDK可以使用,3.前后端结合,即结合以上两种方法,虽然系统复杂度提高,但对于系统的安全性,以及减轻服务器负担都有很大提升。
效果图:
登录界面:
拿开面前的遮挡物后很快登录成功。
以下介绍基于后台的Web端人脸识别。按照系统实现的简单流程,进行分步介绍:
1.前端获取人脸数据
通过调用摄像头,将某一时刻的照片绘制在Canvas上,将Canvas转化成jpg或png。
var video = document.getElementById('video');
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
function getUserMediaToPhoto(constraints,success,error) {
if(navigator.mediaDevices.getUserMedia){
//最新标准API
navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
}else if (navigator.webkitGetUserMedia) {
//webkit核心浏览器
navigator.webkitGetUserMedia(constraints,success,error);
}else if(navigator.mozGetUserMedia){
//firefox浏览器
navigator.mozGetUserMedia(constraints,success,error);
}else if(navigator.getUserMedia){
//旧版API
navigator.getUserMedia(constraints,success,error);
}
}
//成功回调函数
function success(stream){
//兼容webkit核心浏览器
var CompatibleURL = window.URL || window.webkitURL;
//将视频流转化为video的源
video.src = CompatibleURL.createObjectURL(stream);
video.play();//播放视频
//将视频绘制到canvas上
postFace()
}
function error(error) {
console.log('访问用户媒体失败:',error.name,error.message);
}
if(navigator.mediaDevices.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia){
getUserMediaToPhoto({video:{width:480,height:320}},success,error);
}else{
alert('你的浏览器不支持访问用户媒体设备');
}
2.将人脸图片数据传向后台
将图片转为base64格式,通过Ajax传向后台,指定后台专门的处理函数。
function postFace() {
setTimeout(function () {
context.drawImage(video,0,0,480,320);
img=canvas.toDataURL('image/jpg')
{#获取完整的base64编码#}
img=img.split(',')[1]
//将照片以base64用ajax传到后台
$.post({
url:'/getface',
data:{
message:img
},
success:function (callback) {
if(callback=='no'){
postFace()
}else {
window.location.href=callback
}
},
error:function (callback) {
postFace()
}
})
},300)
}
3.后台接受图片
后台接受到base64编码后,将编码解密并解析,保存成图片。
def getface(request):
if request.POST:
time = datetime.datetime.now().strftime('%Y%m%d&%H%M%S')
strs=request.POST['message']
imgdata = base64.b64decode(strs)
try:
file = open(u'static/facedata/confirm/'+time+'.jpg', 'wb')
file.write(imgdata)
file.close()
except:
print('as')
res=AFRTest.checkFace(u'static/facedata/base/niewzh.jpg',u'static/facedata/confirm/'+time+'.jpg')
if res>=0.6:
return HttpResponse('panel')
else:
return HttpResponse('no')
else:
return HttpResponse('no')
4.调用SDK进行图片比对
假设用户在注册时已经上传了作为参照的人脸数据,我们使用用户上传的参照人脸数据与刚刚获得的人来拿数据进行比对,SDK获取到两张照片作为参数,比较后返回相似度。
def face(request):
res = AFRTest.checkFace(u'static/facedata/base/niewzh.jpg', u'static/facedata/base/niewzh.jpg')
return HttpResponse(res)
5.根据比对结果,返回给前端相应的数据
定义一个合适的阈值,如果相似度大于该值,判断是该用户,认定允许登录,返回系统界面。否则返回人脸识别失败的信息。
后记:
本文只介绍了简单实现,系统安全性没有过多考虑,比如在这个简单系统中,前端的数据获取流程,非注册用户使用注册用户的照片也能骗过系统,在照片数据传输的过程中,也会有数据泄露的风险。后面将会针对这些情况进行一系列的优化。
经测试,最终实现的系统可以在1s左右实现刷脸登录,识别效果也令人满意。
百度网盘:https://pan.baidu.com/s/1OOjsz1YiRQ0ItSDh7Shm0Q
密码:psvl