本周完成的工作主要包括以下三方面的内容:
集成的具体细节方面:输入为图片的dataURL,即图片的base64格式,最小4848,最大40964096
输出为表示情绪的7维向量,使用json格式表示。7维分别是:
相关代码如下
var facepp = new FACEPP(APIKEY,APISERET,1);
function getEmotion(base64Image){
console.log(base64Image);
//图片的base64数据
//const base64Image=arrayBufferToBase64(img);
// 以二进制的方式上传图片
// 将base64转为二进制
//let imageData = facepp.dataURItoBlob(base64Image);
//根据个人需求填写的参数,这里全部写上了,包括年龄性别等,详情看官方文档
let attributes = 'gender,age,smiling,headpose,facequality,blur,eyestatus,emotion,ethnicity,beauty,mouthstatus,eyegaze,skinstatus';
//上传图片,获取结果
let dataDic = {'image_base64':base64Image,'return_landmark':2,'return_attributes':attributes};
//调用接口,检测人脸
facepp.detectFace(dataDic,success);
}
function success(e){
//console.log(JSON.stringify(e,null,"\t"))
const faces = e.faces;
const face=faces[0];
var emotion=face.attributes.emotion
console.log(emotion);
}
// Converts canvas to an image
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL();
return image;
}
window.onload=function(){
var img=new Image();
img.src="test.png";
//img.setAttribute('crossOrigin', 'anonymous');
var canvas=document.getElementById('picCan');
var canCC=canvas.getContext('2d');
img.onload = function(){
canCC.drawImage(img,0,0,500,400);
};
var base64Image=canvas.toDataURL("image/png");
// 在控制台中可以查看获取的情绪json,F12启动
getEmotion(base64Image);
}
</script>
在WEB页面的摄像头获取基本逻辑和Python中的差不多,只不过在html中需要
用于获取摄像头视频流并展示的html页面如下:
<html>
<head>
<meta charset="utf-8">
<title>Video Capture Exampletitle>
head>
<body>
<video id="videoInput" height=240 width=320>video>
<canvas id="canvasFrame" height=240 width=320 >canvas>
<canvas id="FirstFrame" height=240 width=320 >canvas>
<canvas id="canvasOutput" height=240 width=320 >canvas>
<script src="js代码逻辑" type="text/javascript">script>
body>
html>
视频获取的js代码如下
let video = document.getElementById("videoInput");
navigator.mediaDevices.getUserMedia({ video: true, audio: false })
.then(function (stream) {
video.height = HEIGHT;
video.width = WIDTH;
video.srcObject = stream;
video.play();
}).catch(function (err) {
console.log("An error occured! " + err);
});
视频处理部分
var frame = new cv.Mat(HEIGHT, WIDTH, cv.CV_8UC4);
cap.read(frame);
// cv.bilateralFilter(frame, frame, 5, 50, 100,cv.BORDER_DEFAULT) // 双边滤波 gg
cv.flip(frame,frame,1) // 反转
var gray = new cv.Mat();
cv.cvtColor(frame, gray, cv.COLOR_RGBA2GRAY);
var ksize = new cv.Size(21,21);
cv.GaussianBlur(gray,gray, ksize ,0)
// console.log(firstFrame)
帧间差分法获取移动物体
if(firstFrame == null){
console.log('enter')
firstFrame = gray;
setTimeout(processVideo,0)
}
cv.imshow("FirstFrame", frame);
// let frameDelta = new cv.Mat(HEIGHT, WIDTH, cv.CV_8UC1);
var frameDelta = new cv.Mat();
cv.absdiff(first Frame, gray, frameDelta) // 帧间差
var thresh = new cv.Mat();
cv.threshold(frameDelta,thresh, 25, 255, cv.THRESH_BINARY)
let M = new cv.Mat();
let anchor = new cv.Point(-1, -1);
cv.dilate(thresh,thresh,M,anchor, 2)
当画面发生变化,也就是有运动物体时,效果图如下
主要实现步骤如下
1.注视鼠标指针然后按下空格来采集数据
采集后右上角的数字会增加,同时如果点击"draw heatmap"按钮会绘制出当前采集的屏幕坐标:
小一点的点用于训练,大一点的点用于验证。
2.保存采集的数据
采集一段时间数据之后,可以点击"save dataset"按钮来保存数据,数据会以json文件形式下载到默认的下载目录中,文件名为dataset.json:
完成采集后,就是训练过程了,具体的训练代码可以参加这篇博客
经过反复调整batch,learning rate,在模型上训练400轮的结果如下在小数据集(251个样本)上,从上图中可以看出,同样在400轮的基础上,复杂模型在训练集上表现很好,在验证集上表现很差,可见有严重的过拟合;在简单模型上,训练集上的表现和复杂模型差不多,但在验证集上表现就比复杂模型好很多了。
而且在训练轮数增加之后,复杂模型loss能更进一步降到0.001左右,而简单模型就基本在0.008左右。
对于这种现象,下一步我们决定适当减少复杂模型的特征,并扩充数据集,再对比简单模型看效果是否有改善。