■ホビーロボット部品の製造・販売 
  モータコントローラ、センサ、音声、画像、無線モジュールなど、
■ホビーロボット制作記事のページ (各種マイコン、PCとの接続事例)
■特殊メイク、特殊材料の販売 ※特殊メイクのコーナーはこちらに移りました。
Top(お知らせ) 製品紹介 使い方とサンプルプログラム 通信販売 リンク ロボット掲示板 会社案内
 Easy Robotics for all enthusiastic people!!!  ---HOBBY ROBOT PARTS SHOP ASAKUSAGIKEN---   Since 2003...

S-EYE PCで動体検知
はじめに

 
CMOSイメージセンサS-EYEはシリアル通信により画像が取得できるモジュールです。特にPCと接続すれば多彩な画像処理を行うことができ、接続も装備も簡単に済みます。
 今回は、動体検知を説明します。言語は他のページと同じくC#、接続はBluetooth無線経由で行います。
 

 ※このページで紹介する内容はあくまでも一例です。個別の作成のご相談ご質問はお答えできませんのでご了承下さい。このページと同じ内容についてのご質問についてはロボット掲示板にてお願いいたします。

 ※以下の情報は2008年10月現在のものです。ご注意ください。


 S-EYEについてはこちらを参照願います。



構成

  構成その他は前のページと同じですのでそちらを参照願います。浅草ギ研製Bluetooth無線と市販の安価なBluetooth無線を使ってPCと接続しています。



動体検知のアルゴリズム

 動体検知は非常に簡単です。画像を連続で取得し、前画像と今画像を比べて、ある程度以上値が離れていたらその部分が動いていると判定するものです。詳細は下のプログラムの部分で説明します。



画像フォーマットついて

 前画像との違いを判定するだけなので、画像フォーマットは白黒でもOKです。ということで今回は白黒画像で実験します。大きさは前回同様80x60にしてみます。S-EYEの場合は「モード1」が「白黒80x60」の出力になります。




プログラム

 とりあえず完成版がこちらになります。

 SEYE_Move.lzh (右クリックで対象を保存)

 保存後、解凍するとVC#2008のプロジェクトのフォルダになります。

 フォームの構成は次のようにしました。連続で画面を更新するプログラムですが、ボタンを付けて一時停止できるようにしています。画面サイズは80x60のにします。ということで80x60サイズのPictureBoxも配置しています。また、しきい値を変えられるようにテキストボックスも配置しています。
 
 通信はSerialPort1をドロップするだけ。Timer1は一時停止の状態かどうかの判定を周期的にするのに使用しています。

 ではプログラムの解説に入ります。

 全体の構成は次のようになっています。行9〜11は標準状態から追加した行で、画像表示メソッド内で使うクラスを使うのに必要な宣言です。基本的には前のページと同じ構成ですので詳細はそちらを参照願います。
 


 前回との違いはしきい値の概念が入ったところです。コンストラクタで初期設定などをしますが、しきい値の初期設定もおこなっています。しきい値は英語でスレッショルドなので変数名はthにしました。50の値はいままでの経験から大体このぐらいの変化値で意図したとおりに検出できるというものです。画素の値変化は8ビットなので0〜255になります。
 

 次にコンストラクタ内でS-EYEに対して初期設定を行っています。
 まずは命令4を実行してカメラの212番レジスタを0にしています。これはAE(オートエクスポージャ:自動露出)とAWB(オートホワイトバランス)をどちらもOFFにするという設定です。カメラのレジスタ変更についてはS-EYEのページに書いてあります。特にAWBは対象物の色の多さによって色自体が変わってしまうので認識系では余計な機能です。たとえば赤が多い画面だと赤が押さえられて全体的に青っぽくなったりして正確な色認識ができなくなりますのでこの機能を切ります。もともとは携帯電話用のカメラなので起動時はこの機能がONになっているようです。ここは前回と同様です。 今回は白黒なので色は関係ないのですが、一応、毎回この操作をしています。
 
 その後、命令3を実行してモードを1(BW 80x60 のモード)に変更しています。これでS-EYEに画像要求をすると80x60の白黒画像のデータ列が送られてきます。1ピクセルは1バイトのグレースケールになります。画像フォーマットの詳細についてはS-EYEのページを参照願います。

 ボタンなどの動きは前回同様なので割愛します。

 さて、いいよいよ中心部の画像表示部分になります。

 基本的には各行にコメント入れてますのでソースをみればわかります。

 おおきな流れとしては

 1)S-EYEに対して画像要求コマンドを発行(行117:別メソッドにしてます)
 2)描画領域を固定(行121〜126)
 3)データを受信して配列に格納(行127〜134)
 4)前回画像と比較して、変化が大きかったら赤描画(行135〜156)
 5)ピクチャーボックスに表示(行157〜159)

 となっています。

 Setpixcelメソッドを使わないで、画像を高速に表示する部分(上記の1)〜3)および5)の部分)は前回同様なので割愛します。今回は白黒なので画素数とデータバイト数が同じなので扱いやすいかと思います。
 結果に赤を描画するので、入力は白黒画像ですが出力はRGB24ビットカラーで扱っています。
 
 大きく違う部分は行135〜156の部分です。取得した画像から前回値との差を計算し(行141)、しきい値以上離れていたら行145〜147でその画素を強制的に赤にしています。しきい値以内の場合は取得した画素をそのまま描画します(行151〜153)。
 RGBカラーのデータのRとGとBの値を同じにするとグレースケールになりますので行151〜153は同じ値を3バイト分格納しています。

 ということでどちらかというと前回(カラー表示)よりも簡単なプログラムになったかと思います。



結果

 結果、次のように無事画像が表示されました。


<動体検知>

 まず、背景がずっと写っている状態から私の顔が視角に入ってきたところです。このようにして動いているところが赤で検出されています。
 


 次に、もともと画面内にあるものの変化です。とりあえず手をグーの形にして動かさないで置くと赤い部分がなくなり、画面がほとんど静止している、つまり動体がないという判定になります。
 


 おもむろにチョキにすると、チョキのような部分が動体として検知されました。
 


 さらにパーにすると動いた部分がパーの形になりました。
 

 このようにして動くものとその位置を判定できます。


<しきい値について>

 初期値ではしきい値を50にしています。この値を変化させるとどうなるでしょうか?

 とりあえず1にしました。一見なにも動いていない画面なのに各ピクセルが雑音のように赤になってしまっています。このようにカメラは画素単位では厳密に毎回同じ値が出ているわけではないのです。よってある幅をもったしきい値で判定する必要があるのです。
 


 参考までにしきい値を5にしたところ。だいぶ雑音がおさまりました。
 


 10にするとほとんど消えました(まだ少し出ている)。
 

 
<残像について>

 今回のプログラムのように毎回比較する画像を更新(oldBWValue配列)していると、現在動いている部分だけでなく、その前に存在した部分も動体となってしまいます。
 下は画面の前で手をすばやく動かしたところです。画面右から左に手を振っています。右のは残像で、前に手があったが今回は無いので背景が元に戻った部分が差がおおきくなってしまい動体のような扱いになってしまいます。これを回避するには、oldBWValueの値を数フレーム間同じ値にして更新しない、という手があります。が今回はここまで。
 

 次もなにかの認識をしてみたいと思います。


2008年10月17日


 
(C)Copylight 2003. 有限会社浅草ギ研 | 通信販売の法規(訪問販売法第8条)に基づく通信販売業者の表示