WebRTC(2)ccv.jsと組み合わせて顔認識を実装〜笑い男〜

前回はブラウザにカメラ映像を映し出すだけでした。
今回は少しステップアップして、avascriptで実装された顔認識ライブラリのccv.jsと
組み合わせでリアルタイムの笑い男変換を実装したいと思います。

face.jsで顔認識〜という記事も見かけますが、実際の画像処理のコアはccv.jsに記述されています。
ccvとはC-based Computer Vision Libraryの略でその名の通り、OpenCVの処理を抜粋・簡略化して
javascript実装したものがccv.jsです。

言うなれば、
ccv.js  = OpenCV本体
face.js = face用のカスケードファイル
といったところでしょうか。

ccv.jsは以下のgithubレポジトリからダウンロードしてください。
ccv.js

以前の記事でjava×OpenCVで画像の笑い男変換を実装しましたが、今回はそれのリアルタイム映像版です。
物体検知入門(2)サンプル:笑い男

さきにざくっと処理の流れをまとめておきますと、

 1.wenRTCでカメラから映像を読み込む
 2.1の映像の中からsetIntervalを利用して定期的にface.jsとccv.jsで顔を検出
 3.映像のstreamに対して2で検出した座標に画像を描画したものをcanvasタグに書き出し

ライブラリ以外のソースコードは以下の通りです。
index.html

<!DOCTYPE html>
<html>
    <head>
        <title>sample-Laughingman-</title>
        <script type="text/javascript" src="http://www.google.com/jsapi"></script><script type="text/javascript">
            google.load('jquery', '1');
            google.load('jqueryui', '1');
        </script>
        <script type="text/javascript" src="./js/lib/ccv.js"></script>
        <script type="text/javascript" src="./js/lib/face.js"></script>
        <script type="text/javascript" src="./js/laughingman.js"></script>
        <script>
            jQuery(document).ready(function() {
                Laughingman.initialize();
                Laughingman.execute();
            });
        </script>
    </head>

    <body>
        <h3>sample-Laughingman-</h3>
        <video id="input" height="400" width="800" controls autoplay style="display: none;"></video>
        <canvas id="output"></canvas>
    </body>
</html>

laughingman.js

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 * author potter0517
 */

//笑い男描画オブジェクト
var Laughingman = {};

/**
 * init関数
 * フィールドに必要な要素を保持する
 * @returns {undefined}
 */
Laughingman.initialize = function() {
    //笑い男の顔画像を重ねるためのビデオタグ(これ自体はブラウザに映さない)
    Laughingman.video = jQuery("#input").get(0);

    //ビデオに笑い男の画像を描画して最終的に映し出すためのcanvasタグ
    Laughingman.canvas = jQuery("#output").get(0);
    //Laughingman.canvas = document.querySelector("#canvas");
    Laughingman.ctx = Laughingman.canvas.getContext("2d");
    //笑い男の画像
    Laughingman.image = new Image();
    Laughingman.image.src = "./img/laughingman.gif";
};

/**
 * 実行
 * @returns {undefined}
 */
Laughingman.execute = function() {
    navigator.webkitGetUserMedia({video: true, audio: true},
    Laughingman.successCallback, Laughingman.failCallback);
}

/**
 * 描画関数
 * これをsetIntervalで定期実行させる
 * @returns {undefined}
 */
Laughingman.draw = function() {
    var width = Laughingman.video.videoWidth;
    var height = Laughingman.video.videoHeight;

    // var canvas = document.createElement('canvas');
    Laughingman.canvas.width = width;
    Laughingman.canvas.height = height;
    Laughingman.ctx.drawImage(Laughingman.video, 0, 0, width, height);

    var faces = ccv.detect_objects({"canvas": Laughingman.canvas,
        "cascade": cascade,
        "interval": 5,
        "min_neighbors": 1});
    for (var i = 0; i < faces.length; i++) {
        Laughingman.ctx.drawImage(Laughingman.image, faces[i].x - 30, faces[i].y - 30, faces[i].width + 60, faces[i].height + 60);
    }
};

/**
 * webkitGetUserMediaの成功時コールバック関数
 * @param {type} stream
 * @returns {undefined}
 */
Laughingman.successCallback = function(stream) {
    var videoStream = window.webkitURL ? window.webkitURL.createObjectURL(stream) : stream;
    Laughingman.video.src = videoStream;
    setInterval(Laughingman.draw, 500);
};

/**
 * webkitGetUserMediaの失敗時コールバック関数
 * @param {type} error
 * @returns {undefined}
 */
Laughingman.failCallback = function(error) {
    alert("error... code : " + error.code);
};

videoタグはそのまま映像として映さずに元ソースとしてのみ利用し、
最終的な合成映像はcanvasタグで描画しています。
そのため映像がかくかくしてしまっています。ついでに言うとface.jsの顔検出精度も
そんなに高くありませんでした。。。

もっと良い実装がある気もするのですが,,,現在はこんな感じです。
参考になれば。

投稿者: potter0517 カテゴリー: Java

Three.js(1)描画に最低限必要なオブジェクト一覧

今回はThree.jsを扱ってみます。

まずは下書き程度にThree.jsで3Dオブジェクトを描画するために必要なjsのオブジェクトを
まとめたいと思います。

簡単に書くと以下の通り。実際のソースは次の記事で記載します。

・renderer ・・・ レンダラ。webGL用とcanvas用が存在。コイツがsceneをcameraで映してブラウザ上に表示される。
           new THREE.WebGLRenderer();
           new THREE.CanvasRenderer();
           renderer.render(scene, camera);

・camera ・・・ その名の通りカメラ。画角や距離を設定。
           new THREE.PerspectiveCamera(40, width / height, 1, 1000);

・scene ・・・ シーン。複数のmeshを一まとめに管理する。
           new THREE.Scene();

・mesh ・・・ 実際に描画される3Dメッシュ。geometryとmaterialから成る。
           new THREE.Mesh(geometry, material);

・geometry ・・・ 描画物体。立方体や球体やいろいろ。
           new THREE.SphereGeometry(10, 10, 10);

・material ・・・ 材質。色やテクスチャを設定。

以上。

投稿者: potter0517 カテゴリー: Java

WebRTC(1)WebRTCでカメラ映像をブラウザに映す

久しぶりの投稿です。

WebRTCに触れてみたのでいつも通り概要とソースを。

WebRTCの概要は以下の通り。

  • Web Real-Time Communicationの略
  • ずばりプラグイン無しでビデオチャット・音声通話・P2P共有を可能にする
  • リアルタイム通信のAPIや企画の総称
  • W3Cが提唱、googleがオープンソース化

下記がビデオチャットの第一歩、カメラで移した映像をブラウザ上で表示するサンプルです。
ハマった点としては、navigator.webkitGetUserMediaに関して

  • file://でのローカル配置では動作せずサーバにデプロイする必要がある
  • 第一引数が文字列からオブジェクトに仕様変更されている

ぐらいでしょうか。
サンプルはchromeでのみ動作します。
(FireFoxやOperaでも動くコードを書いてる人はいるんだけど…)

videochat.html

<!DOCTYPE html>
<html>
    <head>
        <title>camera test</title>
        <script type="text/javascript" src="http://www.google.com/jsapi"></script><script type="text/javascript">
            google.load('jquery', '1');
            google.load('jqueryui', '1');
        </script>
        <script>
            jQuery(document).ready(function() {
                var successCallback = function(stream) {
                    var video = jQuery("#chat");
                    var videoStream = window.webkitURL ? window.webkitURL.createObjectURL(stream) : stream;
                    video.attr("src", videoStream);
                };
                var failCallback = function(error) {
                    alert("error... code : " + error.code);
                };
                navigator.webkitGetUserMedia({video: true, audio: true},
                successCallback, failCallback);
            });
        </script>
    </head>

    <body>
        <h3>camera test</h3>
        <video id="chat" height="400" width="800" controls autoplay style="width:100%; height:100%;"></video>
    </body>
</html>

デプロイには例のごとくメテオを利用しています。
トップページのリンクから本サンプルが確認できます。

次回はチャットの通り双方向のやり取りを、後はface.jsの物体検知を利用してリアルタイム
顔変換をやっていきたいと思います。

投稿者: potter0517 カテゴリー: JavaScript