開発の背景
ここで少し、「crocro.jscam」の開発の背景について触れておきます。
去年の春ごろ、JavaでARマーカーを利用したモーションキャプチャーソフトを作って、紙人形ムービーを作っていました。その際、ARToolKitを使っていたのですが、ライセンスの関係からARToolKit互換のARマーカー認識ライブラリが欲しくなり、フルスクラッチで書いて差し替えました。
このソースコードを整理して、ライブラリとして公開することを当初は考えていたのですが、Javaの基本環境だけでは動かないという問題があり、労力の割には使用者はあまりいなさそうだと思い、計画を途中でやめました。
その後、去年の秋ごろ、HTML5を触りはじめて、ゲームエンジンを作ったりしていました。その際「これからはJavaScriptがよさそうだ」と思い、HTML5のWebカメラ利用の仕様を調べていたのですが、ほとんどのブラウザで実装されていないことが分かり、その計画もまた消えてしまいました。
その後、Flashなら簡単にWebカメラの画像が取得でき、FlashとJavaScriptで連携できる仕様もあることに気づき、去年の12月28日にFlex SDKをダウンロードして、Flashの勉強を始めました。
当初は、Flash側ではWebカメラの画像の取得だけを行う予定だったのですが、2つ問題が発生しました。1つ目は転送速度です。FlashからJavaScriptにデータを転送する際、配列数が大きいと転送時間がかなりかかることが分かりました。2つ目はメモリーです。ChromeやFirefoxでは問題ないのですが、IEでFlashからJavaScriptにデータを転送すると、転送回数分だけ消費メモリーが増大していくことが分かりました。
そこで仕様を仕切りなおして、リアルタイム処理のほとんどをFlash側で行うようにして、JavaScript側では、必要な情報を指定してコールバックでデータを取得する仕組みに切り替えました。また、フィルター設定を行うことで、Flash側のプログラムをJavaScriptから制御できるようにしました。
こういった背景で、「crocro.jscam」は作成されました。こういった背景が分かっていると、使う勘所が分かりやすいと思います。
それではこれから、「crocro.jscam」の使い方を紹介します。また、最後にマーカー認識の簡単な仕組みも解説しておきます。以下、簡単な目次です。
タイトル | 内容 |
シンプルなサンプル | Webカメラのキャプチャと、ラベルデータの取得 |
ゲームコントローラのサンプル | Webカメラを使った、方向と強さの入力 |
全部盛りのサンプル | ラジオボタンで機能を切り替え |
マーカー認識の仕組み | どうやってマーカーを認識しているのか簡単な紹介 |
シンプルなサンプル
Webカメラのキャプチャと、ラベルデータの取得を行うシンプルなサンプルです。
「crocro.jscam」の使い方は、大きな流れを書くと、以下のようになります。
- 【1】 ライブラリを使い、HTML中にFlashのSWFオブジェクトを書き出す。
- 【2】 ライブラリを使い、Webカメラの初期化を行う。
- 【3】★ ライブラリを使い、Webカメラの動作を配列で設定する。
- 【4】 ライブラリを使い、キャプチャ用のオブジェクトを作成する。
- 【5】★ キャプチャ用のオブジェクトに、Webカメラから取得するデータの種類を配列で指定する。
- 【6】 キャプチャ用のオブジェクトに、取得時のコールバック処理を登録する。
- 【7】 キャプチャ用のオブジェクトで、キャプチャを実行する。
ポイントとなるのは、【3】と【5】です。この2つの設定で、FlashのWebカメラ機能をコントロールします。
それでは実際にソースコードを見てもらいます。それぞれの処理が行われる行が分かるように、数字のラベルをつけています。
<!DOCTYPE html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>「crocro.jscam」 - サンプル シンプル - クロノス・クラウン</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" ></script> <script type="text/javascript" src="jscam.js"></script> <script language="javascript"> var cap; $(document).ready(function() { // JSカメラ初期化 crocro.jscam.initSwfCam(); // ………【2】Webカメラの初期化 crocro.jscam.setFilter(["bin", "label", "hidePaint"]); // ………【3】Webカメラの動作を設定 cap = crocro.jscam.makeCaptureObject("cnvsCap"); // ………【4】キャプチャ用のオブジェクトを作成 // コールバックの設定 cap.setBackDataType(["pixelSwf", "labelData"]); // ………【5】取得するデータの種類を指定 cap.setExtrFnc(function(resObj){ // ………【6】取得時のコールバック処理を登録 // 【7】キャプチャを実行 var resArr = []; if ("labelData" in resObj) { var ld = resObj.labelData; resArr.push("labelData.length : " + ld.length); for (var i = 0; i < ld.length; i ++) { var s = ""; $.each(ld[i], function(k, v) {s += k + ":" + v + ", "}); resArr.push("labelData[" + i + "] : " + s); } } $("#resData").html(resArr.join("<br>")); }) }); // キャプチャ function captureImg() { cap.capture(); // キャプチャ } </script> </head> <body bgcolor="#ffffff"> <div class="boxOut"> <script language="javascript"> crocro.jscam.write(); // ………【1】FlashのSWFオブジェクトを書き出す </script> <br> <input type="button" onClick="captureImg()" value="キャプチャ"> <br> <canvas id="cnvsCap" width="320" height="240"></canvas> <div id="resData"></div> </div> </body> </html>
JavaScriptの処理に慣れている人は、それほど難しいソースコードではないと思います。これだけでWebカメラの画像を取得できます。
簡単に解説すると、[キャプチャ]というボタンを押すと、id cnvsCap
の canvas
タグの場所にWebカメラの画像が取得されます。また、id resData
の div
タグの場所に、ラベル情報が出力されます。
setFilter
メソッドに ["bin", "label", "hidePaint"]
を指定しているので、Flash内では「2値化」と「ラベリング」が行われ、その結果を「非表示」にするという流れで処理が進みます。
また setBackDataType
メソッドに ["pixelSwf", "labelData"]
を指定しているので、「SWFオブジェクト全体の画面」と「ラベル・データ」を受け取ります。
受け取ったデータは、【6】【7】のコールバック関数の引数 resObj
の中に格納されます。