背景
人脸识别技术在当下已经十分成熟,但主要在移动端和专有设备应用上较为普及,而在Web端并不多见,本着学习的目的从零实现web端的人脸登录功能。
视频流
使用navigator.getUserMedia方法在浏览器中获取视频流 音频流(通过摄像头麦克风),将来可以用于获取任意数据流,比如光盘和传感器。
识别工具
百度人脸识别库
1、分析图片中人脸的遮挡度、模糊度、光照强度、姿态角度、完整度、大小等特征,基于输出的符合质量标准的图片,返回准确的相似度评分 2、比对图片中两张人脸的相似度,并返回相似度分值 3、支持生活照、证件照、身份证芯片照、带网纹照4种图片类型的人脸对比 4、分析单张图片中人像的破绽(摩尔纹、成像畸形等),判断图片中目标对象否为真人,确保比对效果真实可靠
face_recognition
被称为世界上最简单的人脸识别库(使用确实超简单)。你可以通过Python引用或者命令行的形式使用它,来管理和识别人脸。 该软件包使用dlib中最先进的人脸识别深度学习算法,使得识别准确率在《Labled Faces in the world》测试基准下达到了99.38%。 它同时提供了一个叫face_recognition的命令行工具,以便你可以用命令行对一个文件夹中的图片进行识别操作。
总体流程
- 启动web服务,使用face_recognition将基础库图片进行建模,将建模结果(识别到的人脸在图片中的位置和人脸特征)加载到内存。
- 前端通过h5页面的getUserMedia方法调用摄像头获取视频流。
- 通过canvas抓取一帧视频转化为图片(base64),使用http或websocket发送到后台。
- 后台接受base64参数并转化为图片保存。
- 调用face_recognition.locations和face_recognition.face_encodings进行图片建模。
- 调用face_recognition.compare_faces将图片建模结果与基础库结果比对。
- 根据定义的比对阈值(被称为容忍度,一般为0.6)返回比对结果,如果阈值小于该值,判断是该用户,认定允许登录,返回系统界面。否则返回人脸识别失败的信息。
流程图
时序图
参考案例
前段代码
代码语言:javascript复制<div class="layui-container">
<div class="blog-main">
<!-- 左边区域 -->
<div id="support"></div>
<div class="div-a" id="contentHolder">
<video id="video" width="100%" height="60%" autoplay></video>
<canvas hidden="hidden" id="canvas" width="520" height="250"></canvas>
</div>
<div class="div-b">
<!-- <input type="button" id="snap" style="width:100px;height:35px;" value="拍 照" />
<input type="button" onclick="CatchCode();" style="width:100px;height:35px;" value="上传服务器" /> -->
<h3>检测实时数据</h3>
<span>年龄:</span><span id="age"></span><br />
<span>颜值:</span><span id="beauty"></span><br />
<span>性别:</span><span id="gender"></span><br />
<span>人种:</span><span id="race"></span><br />
<span>是否戴眼镜:</span><span id="glasses"></span><br />
<span>表情:</span><span id="expression"></span><br />
</div>
</div>
</div>
<script>
//判断浏览器是否支持HTML5 Canvas
window.onload = function () {
try {
//动态创建一个canvas元 ,并获取他2Dcontext。如果出现异常则表示不支持 document.createElement("canvas").getContext("2d");
document.getElementById("support").innerHTML = "浏览器支持HTML5 CANVAS";
}
catch (e) {
document.getElementByIdx("support").innerHTML = "浏览器不支持HTML5 CANVAS";
}
};
var timer = null;
//这段代 主要是获取摄像头的视频流并显示在Video 签中
window.addEventListener("DOMContentLoaded", function () {
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
video = document.getElementById("video"),
// videoObj = { "video": true },
//调用用户媒体设备,访问摄像头
mediaConstraints = {
audio: false,
video: {
width: { ideal: 1280 },
height: { ideal: 720 },
frameRate: {
ideal: 10,
max: 15
},
facingMode: "environment"
}
};
errBack = function (error) {
console.log("Video capture error: ", error.code);
};
//拍照按钮
// $("#snap").click(function () {
// context.drawImage(video, 0, 0, 330, 250);
// })
//拍照每秒一次
timer = setInterval(function () {
context.drawImage(video, 0, 0, 330, 250)
CatchCode();
}, 3000);
//navigator.getUserMedia这个写法在Opera中好像是navigator.getUserMedianow
//更新兼容火狐浏览器
if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) {
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
navigator.getUserMedia(mediaConstraints, function (stream) {
video.srcObject = stream;
video.play();
}, errBack);
}
}, false);
/**
* Base64 数据处理
*/
function dataURItoBlob(base64Data) {
var byteString;
if (base64Data.split(',')[0].indexOf('base64') >= 0)
byteString = atob(base64Data.split(',')[1]);
else
byteString = unescape(base64Data.split(',')[1]);
var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0];
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i ) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], { type: mimeString });
}
/**
* 上传服务器
*/
function CatchCode() {
var canvans = document.getElementById("canvas");
//获取浏览器页面的画布对象
//以下开始编 数据
var imageBase64 = canvans.toDataURL();
var blob = dataURItoBlob(imageBase64);
var fd = new FormData(document.forms[0]);
fd.append("the_file", blob, 'image.png');
//将图像转换为base64数据
$.ajax({
type: "POST",
url: "{:url('/index/Index/faceVerifyVideo')}",
processData: false, // 必须
contentType: false, // 必须
data: fd,
datatype: "json",
success: function (res) {
console.log(res);
if (res.code == 0) {
// layer.msg(JSON.stringify(res.data.face_list));
var jsonObj = res.data.face_list[0];
var age = jsonObj.age;
var beauty = jsonObj.beauty;
var gender = jsonObj.gender;
var race = jsonObj.race;
var glasses = jsonObj.glasses;
var expression = jsonObj.expression
$("#age").html(age);
$("#beauty").html(beauty);
if (gender.type == 'male') {
$("#gender").html("男");
} else {
$("#gender").html("女");
}
if (race.type == 'yellow') {
$("#race").html("黄种人");
} else if (race.type == 'white') {
$("#race").html("白种人");
} else if (race.type == 'black') {
$("#race").html("黑种人 ");
} else {
$("#race").html("阿拉伯人");
}
if (glasses.type == 'none') {
$("#glasses").html("未戴眼镜");
} else if (glasses.type == 'common') {
$("#glasses").html("戴了普通眼镜");
} else {
$("#glasses").html("戴了墨镜");
}
if (expression.type == 'none') {
$("#expression").html("不笑");
} else if (expression.type == 'smile') {
$("#expression").html("微笑");
} else {
$("#expression").html("大笑");
}
// layer.alert(res.msg, { icon: 6 });
clearInterval(timer);
} else {
layer.msg(res.msg, { icon: 5 });
}
},
error: function () {
layer.alert('接口异常', { icon: 5 });
}
});
}
</script>
服务端代码
微信公众号好回复 百度人脸识别代码
获取