Webカメラと赤外線LEDを使ってUnityで使える座標を取得する.その2

ソフト面

続いてソフトに入っていきます.IDEやOpenCVの設定は他のサイトを見ながらなんとかしてください.

それでは,いきなり最終版のコードを載せます(初心者丸出しの恥ずかしいコードですが...)

 

コード

解説

雑に解説

上のプログラムを雑に説明すると,まず,スクリーンに埋め込まれた3つのLEDをWebカメラで撮影します.その後,3点のうちどこが鈍角(120°)かということを判定し,その他の2点同士の結ぶ線の角度と尺度からスクリーン上の座標を計算します.

感が良い方ならわかると思いますが,実は2点あれば同じことができます.これは当初,スクリーンの上下がわからないかもしれないと思い3点にしておけば判定できると思った時のなごりです.

あと,勝手にソケット通信で座標を他のプログラムに送信する部分を追加しています.

もう少し丁寧に解説

(0)・・・ヘッダのインクルードや関数定義など

(1)・・・Webカメラの設定(OpenCV)

(2)・・・ソケット通信の設定

(3)・・・メインの処理(以下で解説)

まず,USBWebカメラでスクリーンを撮影すると図1のような画像が得られます.赤い点が赤外線LEDです.

図1

この図1の画像から,頂角と2つの底角を決定します.

そして,底辺の角度と長さ(px)を計算します.(図2)

赤い円は,(下2つのLEDの中点)底辺の重心です.

図2

撮影された画像の中心と2つのLEDの中点を結ぶベクトルを算出します.

図3

次に,線形代数の基礎で出てくる,ベクトルを原点中心にθだけ回転した後の座標を求める公式を使って,図4のように下2つのLEDが水平になるようにします.

図4

次に,スクリーンのピクセルに合うように尺度を変換します(図5).1000px/90px=11.1倍を図4で変換したベクトル(赤円から青丸)に掛けます.図5のピクセルはかなり適当です.

図5

最後に,座標の基準を左上に持ってくるようにオフセット(図6)すれば終了です.

図6

 

2件のコメント

  • こんにちは。こちらの記事を興味深く読ませていただきました。私は以前wiiリモコンとwiiremoteで似たようなことを簡易的にやったことがあるのですが、こちらの方法ではwebカメラを揃えれば多人数プレイに対応できるのでしょうか

    • コメントありがとうございます.私も色々調べたのですが,WiiRemoteを使うという方法があるということを初めて知りました...
      私は1台のカメラで動作させるつもりで構成しましたが,仕組み的には複数のカメラを使ってプレイすることも可能です.
      そのためには,キャプチャデバイス「cv::VideoCapture cap(1);」などを修正する必要があるかと思います.
      また,無駄な処理も多いため数が多くなってくると処理が間に合わないかもしれません.

      追記-
      この例に限らないと思いますが,ガンコントローラに物理的な照準器(サイト)が付いているとして,
      その照準器で狙った座標とWebカメラから画像処理をして得た座標はそれなりにずれます.
      私は,シューティングゲームにしたので画面上の照準を見ながら狙いを合わせても気になりませんでしたが,
      精度はイマイチといった印象でした(子ども向けのシューティングゲームであればタイムラグも少なく実用レベル).
      そのうち実演動画をアップできればと思っています.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です