memorandums

日々の生活で問題解決したこと、知ってよかったことなどを自分が思い出すために記録しています。

カメラによる物体検知

つくるとVol.5に向けて準備作業開始しました。

なかなか時間が取れず。。。とはいえ一ヶ月前なのでさすがにやらないと。。。という感じです。

出展予定の内容は以下の通りです。

蕎麦屋の出前ではありませんが。。。投稿してから作るという感じで。。。実はまだ完成していません。ごめんなさい?

もちろん技術的にできることは最低限確認した上での投稿でしたので。。。

ScratchでRomoを操縦して、プロジェクターで投影したドット?を消していく(接触すると消える)、全部消すまでの時間を競うようなゲームにするつもりです。

ScratchでRomoを操縦するところは既にある仕組みを利用させていただきますので、これはdoneです。

さて、お次は投影したドットとRomoの接触?を検知するにはどーするか。。。です。

昨年、プロジェクションマッピングの応用事例として製作した装置(モバイルプロジェクタとWebカメラを一体化したもの)がありましたのでそれを流用します。ちなみに以下のような感じです。そういえばこれ動画あげてなかったなぁ。。。まあいいか。ちなみにこれ焦点距離を稼ぐために高くなってしまっているので本番まで改良予定です。

f:id:ke_takahashi:20180615193321p:plain

これで机面にドットを表示して、その表示したドットをRomoが遮ったら?、その様子を撮影しているWebカメラの映像で検知できないか?というお題です。

レンジセンサーやKinectを使う解法もありますが、装置がゴテゴテした感じにはしたくありません。ゆくゆくはRomoも自作して小中学校とかの実習なんかで採用してもらえるように低価格化したいので。それでWebカメラです。

以下のような感じです。

f:id:ke_takahashi:20180615193948j:plain

この状態でRomoが前進すると。。。以下です。このときに何とかして変化を検知したいわけです。

f:id:ke_takahashi:20180615193956j:plain

ちなみにカメラから見た画像は以下の通りです。

f:id:ke_takahashi:20180615195953p:plain


まず、考えたのがOpenCVライブラリを利用したBlob検出です。

Romoが前進することでBlobの中心座標が少なからず移動するだろう。。。という期待です。絵にすると以下。

f:id:ke_takahashi:20180615194932p:plain

実際にプログラムを作ってやってみたのですがうまく検出できませんでした。

原因はプロジェクタとカメラが同じ方向から対象を見ているため、Romoが遮光することで多少、ドットが大きくなるのですが中心座標が大きく変化することはない、ということだと思われます。対策として、プロジェクタとカメラの位置を離すことで検知できそうですが。。。構成が複雑になるので避けたいところです。

次に試したのが、画素の情報です。

ちなみに画素はBlob検出などして座標を計算するのですが、今回の場合はドットを表示する画面上の座標をプログラムで決めていますので、この座標系をカメラの座標系にマッピングすることで位置が一意に決まります。Blob検出する必要がない分、計算負荷を減らせます。単純ですが思いついてよかった。。。

毎フレームごとにカメラのドットの中央部の画素を取得し、Processingのbrightnessとhueとsaturationを適用して、Romoの遮光前と後の値を調べてみました。

結果は以下です。

遮光前* 遮光後*
brightness 255 255
hue 127 157
saturation 12 170

brightnessは前後でほとんど変わらずでした。

hueは30程度増えるのですが、遮光前の状態でなぜか127と0をいったりきたりして安定しません。これでは使えそうもありませんでした。

最後のsaturationはバッチリです。安定しています。数値の変化も大きいので使えそうです。ただ、アタリマエですがRomoの白い部分に当たると12くらいになりますのでそこでは検知できません。それでも青い部分やキャタピラのグレーの部分でも変化が大きくでましたので検知に使えそうです。

ということで、saturationで行きたいと思います。

とりあえず今日はここまで。