我们模型的输入是60*36的一张正则化后的眼部图片,所以需要将视频流中的信息处理成输入所需的规则的眼部图片,整个处理过程是"寻找脸部->取得眼睛图像->正则化眼部图像"。
主要工作流程参考了如下这篇博客:
https://cpury.github.io/learning-where-you-are-looking-at/
1.寻找脸部
基本思路就是首先开启摄像头,将摄像头的视频流导入video标签里面,然后利用将video标签作为输入,利用clmtrackr.js来帮助寻找脸部
所需html
<!doctype html>
<html>
<body>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.12.0"></script>
<script src="clmtrackr.js"></script>
<script src="main.js"></script>
<video id="webcam" width="400" height="300" autoplay></video>
<style>
</style>
</body>
</html>
对应main.Js
$(document).ready(function() {
const video = $('#webcam')[0]; // 展示脸部的视频流
const ctrack = new clm.tracker(); //新建一个追踪对象
ctrack.init(); //初始化追踪对象
//追踪循环,一直寻找脸部
function trackingLoop(){
requestAnimationFrame(trackingLoop); //在每一帧都调用循环中的逻辑
let currentPosition=ctrack.getCurrentPosition(); //获取当前脸部关键点坐标
}
// 传入视频流,来进行处理
function onStreaming(stream){
ctrack.start(video); //追踪video中的图像
video.srcObject=stream; //设置video对象的输入来源
trackingLoop(); //调用循环
}
navigator.mediaDevices.getUserMedia({
video: true }).then(onStreaming); //请求用户开启摄像头
});
到这里,currentPosition就是用户脸部关键点坐标了,其参考图如下:
2.得到眼睛图像
这里分为左眼和右眼进行处理,由于用户的脸可能是倾斜的,所以应该找出眼睛各边界的最值,同时由于可能存在的误差,应该适当扩展边界。
在合适的范围内,眼睛的X轴方向基本由眼角确定边界,但是Y轴则可能是由两眼角或眼睛上部确定的,所以需要取三点最值来确定边界。
分左眼右眼处理,得到如下处理函数,将其增加到main.js:
//获取眼睛轮廓,传入脸部关键点坐标,和是否是左眼,返回起始点坐标和宽高
function getEyesRectangle(positions,isLeft) {
if(!isLeft){
//如果是右边
const minX = positions[23][0] - 5;
const maxX = positions[25][0] + 5;
const minY = Math.min(positions[23][1],positions[26][1],positions[25][1])-5;
const maxY = Math.max(positions[23][1],positions[24][1],positions[25][1])+5;
const width = maxX - minX;
const height = maxY - minY;
return [minX, minY, width, height];
}else{
//如果是左边
const minX = positions[30][0] - 5;