始めまして、アクアリング鶴舞ラボでアルバイトをしている市橋と申します。
#この記事について
この記事では赤外線を撮影できるカメラを用いた、三角測量によるタッチ位置検出法の説明をします。
場所としては壁面を想定しています。
#使用器具
使用したものは以下の通りです。
・Raspberry Pi 2 Model B 2個
・Raspberry Pi NoIR Camera 2個(赤外線カメラ)
・赤外線ライト 2個
・赤外線透過フィルタ
設置すると次のようになります。
右上と左上にRaspberryPiとカメラが、左右から4分の1ほどの位置に下向きの赤外線ライトが設置されています。二つのカメラに同時に映る場所に手をかざすと、その場所がタッチされたことを検出できるようになっています。
#方式の説明
##赤外線カメラの用意
一般的に売られているカメラは赤外線カットフィルタが入っていて、赤外線を撮影できません。webカメラは、物によっては赤外線カットフィルタを取り外し、赤外線を通すフィルタに張り替えることで赤外線カメラに改造できるようですが、ものによってはできなかったり、できるとされていたものでもモデルチェンジによりできなくなったりします。そこで、今回は初めからフィルタが入っていないことが確定している物を使用しました。ただ、本格的な赤外線カメラとなると価格が数万円となるので、今回はRasberry Piのカメラモジュールの赤外線カットフィルタが入っていないタイプのものを使用しました。
##赤外線カメラによる物体検出
赤外線カメラは赤外線しかとることができません。そのため、赤外線を発する光源や、赤外線を反射する物があると、その部分が白く映ります。このことを利用して物体検出をしていきます。今回は次のようなアルゴリズムで検出を行いました。
- 赤外線画像を取得
- 赤外線画像を二値化。閾値は適宜設定する
- 画像の上下を切り捨てて、高さの45%~55%の範囲を切り出す
- 3で切り出した画像を一次元配列に圧縮する。とあるx座標について、一定数以上の白のピクセルがあれば白、そうでなければ黒とした一次元配列を作成する。そのため、一次元配列の次数は画像の横解像度と同じとなる
- 4で作成した1次元配列にて、白が一定数以上連続した時、その連続区間の中心に物体があるとする
- 物体を検出した位置がカメラの中心を0[rad]としたとき、何ラジアンに相当するのかを計算する。物体を検出した横座標がx、画像の横解像度がXmax、カメラの水平画角がhfov[deg]のとき、その角度はarcsin((x / Xmax - 0.5) * sin(hfov / 2))より求められる
RaspberryPiでの画像処理にはOpenCVを、カメラモジュールからの画像取得にはRaspiCamCVを用いました。
##三角測量
三角測量 - Wikipediaにある原理を応用しました。今回の場合、基準点は2台のカメラ、調べたい点はタッチされた場所となります。カメラの設置位置はタッチ検出したい範囲の左上と右上の隅となるので、wikipediaの図とは上下が逆になります。つまり、角度はは検出範囲の上辺を基準としたものとなります。
角度情報の取り扱いについて注意点が3つあります
- カメラの姿勢によって、角度の符号を反転させる必要がある
- カメラの中心を0[rad]とした角度が送られてくるので、検出範囲の上辺を0[rad]、左右の辺をπ/2[rad]とした角度に変更する必要がある
- 今回使用したカメラは水平画角が54°なので、上辺から36°の範囲は検出できないため、その分の補正が必要
##通信方法
スイッチングハブでLANを構成し、oscにて通信を行いました。
PCではopenframeworksのofxOscを、RaspberryPiではoscPack(http://www.rossbencina.com/code/oscpack)を用いました。
#動画
実際に動かしてみるとこのようになります。
Vimeoに投稿しました