所以我试图使用lulu的CCV JavaScript库,这里看到的代码示例在检测到的面部上绘制眼镜:enter link description here 但是,我希望能够检测到脸部,并在其周围绘制一个矩形,然后将其作为变量保存在Web浏览器中,而不是绘制眼镜。
在face.html文件中,我认为有一条线将眼镜拉到检测到的脸部
for (i = App.comp.length; i--; ) {
ctx.strokeRect(App.glasses, (App.comp[i].x - w / 2) * m, (App.comp[i].y - w / 2) * m, (App.comp[i].width + w) * m, (App.comp[i].height + w) * m);
}
}
};
我尝试用此代码段替换该行:
ctx.strokeRect(comp[i].x, comp[i].y, comp[i].width, comp[i].height);
它确实绘制了一个矩形,但在屏幕的一角绘制了一个小矩形。我迷失了,因为从这里去的地方。
这里可以看到html页面的整个代码:
<pre>
<!DOCTYPE html>
<html lang="en">
<!-- Adapted to work with the getUserMedia API using code from http://wesbos.com/html5-video-face-detection-canvas-javascript/ -->
<head>
<meta charset="utf-8">
<title>HTML5 Face Detection - JavaScript getUserMedia API and Groucho Marx glasses!</title>
<style>
body {
font-family: sans-serif;
font-size: 17px;
line-height: 24px;
color: #fff;
width: 100%;
height: 100%;
margin: 0;
text-align: center;
background-color: #111;
}
#info {
position: absolute;
width: 100%;
height: 30px;
top: 50%;
margin-top: -15px;
}
#output {
width: auto;
height: 100%;
background: black;
-webkit-transform: scale(-1, 1);
}
</style>
</head>
<body>
<p id="info">Please allow access to your camera!</p>
<canvas id="output"></canvas>
<script src="ccv.js"></script>
<script src="face.js"></script>
<script>
// requestAnimationFrame shim
(function() {
var i = 0,
lastTime = 0,
vendors = ['ms', 'moz', 'webkit', 'o'];
while (i < vendors.length && !window.requestAnimationFrame) {
window.requestAnimationFrame = window[vendors[i] + 'RequestAnimationFrame'];
i++;
}
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime(),
timeToCall = Math.max(0, 1000 / 60 - currTime + lastTime),
id = setTimeout(function() { callback(currTime + timeToCall); }, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
}());
var App = {
start: function(stream) {
App.video.addEventListener('canplay', function() {
App.video.removeEventListener('canplay');
setTimeout(function() {
App.video.play();
App.canvas.style.display = 'inline';
App.info.style.display = 'none';
App.canvas.width = App.video.videoWidth;
App.canvas.height = App.video.videoHeight;
App.backCanvas.width = App.video.videoWidth / 4;
App.backCanvas.height = App.video.videoHeight / 4;
App.backContext = App.backCanvas.getContext('2d');
var w = 300 / 4 * 0.8,
h = 270 / 4 * 0.8;
App.comp = [{
x: (App.video.videoWidth / 4 - w) / 2,
y: (App.video.videoHeight / 4 - h) / 2,
width: w,
height: h,
}];
App.drawToCanvas();
}, 500);
}, true);
var domURL = window.URL || window.webkitURL;
App.video.src = domURL ? domURL.createObjectURL(stream) : stream;
},
denied: function() {
App.info.innerHTML = 'Camera access denied!<br>Please reload and try again.';
},
error: function(e) {
if (e) {
console.error(e);
}
App.info.innerHTML = 'Please go to about:flags in Google Chrome and enable the "MediaStream" flag.';
},
drawToCanvas: function() {
requestAnimationFrame(App.drawToCanvas);
var video = App.video,
ctx = App.context,
backCtx = App.backContext,
m = 4,
w = 4,
i,
comp;
ctx.drawImage(video, 0, 0, App.canvas.width, App.canvas.height);
backCtx.drawImage(video, 0, 0, App.backCanvas.width, App.backCanvas.height);
comp = ccv.detect_objects(App.ccv = App.ccv || {
canvas: App.backCanvas,
cascade: cascade,
interval: 4,
min_neighbors: 1
});
if (comp.length) {
App.comp = comp;
}
for (i = App.comp.length; i--; ) {
ctx.strokeRect(App.glasses, (App.comp[i].x - w / 2) * m, (App.comp[i].y - w / 2) * m, (App.comp[i].width + w) * m, (App.comp[i].height + w) * m);
}
}
};
App.glasses = new Image();
App.glasses.src = 'glasses.png';
App.init = function() {
App.video = document.createElement('video');
App.backCanvas = document.createElement('canvas');
App.canvas = document.querySelector('#output');
App.canvas.style.display = 'none';
App.context = App.canvas.getContext('2d');
App.info = document.querySelector('#info');
navigator.getUserMedia_ = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
try {
navigator.getUserMedia_({
video: true,
audio: false
}, App.start, App.denied);
} catch (e) {
try {
navigator.getUserMedia_('video', App.start, App.denied);
} catch (e) {
App.error(e);
}
}
App.video.loop = App.video.muted = true;
App.video.load();
};
App.init();
</script>
</body>
</html>
</pre>
有什么想法吗?
答案 0 :(得分:0)
var x_offset = 0, y_offset = 0, x_scale = 1, y_scale = 1;
if (App.video.Width * App.video.Height > localVideo.videoWidth * localVideo.clientHeight) {
x_offset = (localVideo.clientWidth - localVideo.clientHeight * localVideo.videoWidth / localVideo.videoHeight) / 2;
} else {
y_offset = (localVideo.clientHeight - localVideo.clientWidth * localVideo.videoHeight / localVideo.videoWidth) / 2;
}
x_scale = (localVideo.clientWidth - x_offset * 2) / localVideo.videoWidth;
y_scale = (localVideo.clientHeight - y_offset * 2) / localVideo.videoHeight;
for (var i = 0; i < comp.length; i++) {
comp[i].x = comp[i].x * x_scale + x_offset;
comp[i].y = comp[i].y * y_scale + y_offset;
comp[i].width = comp[i].width * x_scale;
comp[i].height = comp[i].height * y_scale;
然后使用
行ctx.strokeRect(comp[i].x, comp[i].y, comp[i].width, comp[i].height);
通过App.video.width替换所有localvideo.clientwidth和通过App.video.height替换ocalvideo.clientheight