Google Hangout Effects Using HTML5 And JavaScript Facedetection

Google hangouts very popular because of Google effects like face masks and background effects.

I tried to implement Google Effects using HTML5 Canvas,HTML5 getUserMedia API via JavaScript face detection library by  Liuliu.

To simplify I divided this tutorial into two parts First getUserMedia basics and Second Face detection & Google Effects.

Please go through the getUserMedia basics then you will understand the logic clearly.

Continuous to the previous post, we learnt how to take a snapshot using getUsermedia and Canvas. Here is the Demo

button.addEventListener('click',snapshot, false);

function snapshot() {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
ctx.drawImage(video, 0, 0);
}

 

Just remove capture button and replace onclick event with setInterval Method as shown below

setInterval(snapshot, 30);

 

The Logic is simple I am injecting local media stream video into HTML5 Canvas.For every 30msec one latest image snapshot will be drawn on the canvas. As the Time Interval is very less both video and canvas look like exactly same. Here is the Demo.

Now we will understand face detection JavaScript by LiuLiu. The library contains two js file ccv.js and face.js.

I Added some CSS code to style our Google Effects page.Here is the Final HTML Code.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Google Effects By By Arunkumar Gudelli</title>
    <script src="https://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script>
    <script src="ccv.js" type="text/javascript"></script>
    <script src="face.js" type="text/javascript"></script>
    <script>

        var MaskImage = new Image();

        function selectmask(source) {
            console.log(source);
            MaskImage.src = source + ".png";
        }

        function onFailure(err) {
            alert("The following error occured: " + err.name);
        }

        jQuery(document).ready(function () {

            var video = document.querySelector('#webcam');
            var button = document.querySelector('#screenshot-button');
            var canvas = document.querySelector('#screenshot-canvas');
            var ctx = canvas.getContext('2d');

            navigator.getUserMedia = (navigator.getUserMedia ||
                            navigator.webkitGetUserMedia ||
                            navigator.mozGetUserMedia ||
                            navigator.msGetUserMedia);
            if (navigator.getUserMedia) {
                navigator.getUserMedia
                            (
                              { video: true },
                              function (localMediaStream) {
                                  video.src = window.URL.createObjectURL(localMediaStream);
                              }, onFailure);
            }
            else {
                onFailure();
            }
            //button.addEventListener('click', snapshot, false);
            setInterval(snapshot, 30);
            function snapshot() {
                canvas.width = video.videoWidth;
                canvas.height = video.videoHeight;
                ctx.drawImage(video, 0, 0);
                var position = ccv.detect_objects({ "canvas": canvas,
                    "cascade": cascade,
                    "interval": 2,
                    "min_neighbors": 1
                });
                for (var i = 0; i < position.length; i++) {
                    ctx.drawImage(MaskImage, position[i].x - 90, position[i].y - 150, position[i].width + 200, position[i].height + 200);
                }
            }
        });

    </script>
</head>
<body>
    <div align="center" class="normaldiv">
        <div style="width: 90%" class="normaldiv">
            <div style="float: left;">
                <h3>
                    <img src="GoogleEffects.png" alt="GoogleEffects" />
                    Google Effects By Arunkumar Gudelli</h3>
            </div>
            <div>
                <p>
                    <input id="GlassesWithMask" onclick="selectmask(this.id)" type="button" style="background: url(glassesIcon.png);
                        background-repeat: no-repeat; width: 110px; height: 110px; cursor: pointer" />
                    <input id="BatMan" onclick="selectmask(this.id)" type="button" style="background: url(batmanIcon.png);
                        background-repeat: no-repeat; width: 110px; height: 110px; cursor: pointer" />
<input id="PirateCaptain" onclick="selectmask(this.id)" type="button" style="background: url(PirateCaptainIcon.png);
                        background-repeat: no-repeat; width: 110px; height: 110px; cursor: pointer" />

                </p>
            </div>
        </div>
        <video id="webcam" autoplay>
        </video>
        <canvas id="screenshot-canvas">
        </canvas>
    </div>
</body>
</html>

 

Here is the Final Google Effects Demo.

You have to enable getUserMedia in your browser. That I explained in previous post If you have any queries feel free to comment.

Remember getUserMedia does’not work on file:// URL you have host html in IIS or Apache.Use Chrome or Mozilla or Opera

NOTE:

It’s not perfect. Keep Your Face straight and Close to Webcam(with Clean Background) and Remove your Eye Glasses if you have.

And Your suggestions are always welcome Please Add your valuable feedback to improve this App.

GoogleEffectsDemo

GoogleEffectsDemo

I hope you’ve enjoyed this article and that it gives you more ideas face detection and getUserMedia API.If so share this post with your friends and also join our mailing list I will be sharing my learning’s and experiments with HTML5.

NOTE: getUserMedia has been removed from the Web standards.