0

So im attempting to use lulu's CCV JavaScript library and this code example seen here that draws glasses over a detected face: enter link description here But instead of drawing glasses I would like to be able to detect the face, and draw a rectangle around it, then save it in the web browser as a variable.

In the face.html file there is a line which I believe draws the glasses to the detected face

 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);
            }
    }
}; 

I have tried replaced that line with this code snippet:

ctx.strokeRect(comp[i].x, comp[i].y, comp[i].width, comp[i].height);

It does draw a rectangle, but a small one in the corner of the screen. I'm lost lost as where to go from here.

The entire code for the html page is seen here:

<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 &quot;MediaStream&quot; 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> 

Any ideas?

4

1 回答 1

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

于 2013-04-24T09:05:26.243 回答