■ホビーロボット部品の製造・販売 
  モータコントローラ、センサ、音声、画像、無線モジュールなど、
■ホビーロボット制作記事のページ (各種マイコン、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についてはこちらを参照願います。



構成

  S-EYEは主にリモートブレイン用途を想定しています。よって、PCとの無線接続がメインになるかと思いますので今回は下記のように浅草ギ研のBluetoothモジュールAG-BT20Eを経由してPCと接続します。

 

 BT20Eへの電源はS−EYEから供給することができますので上記のように4端子を直結するだけで終わりです。
 通信速度は初期設定の460800bpsで行いました。
 電源は4.5V〜10Vという仕様ですが、電圧が高くなると効率が悪くなり基板も熱くなるので今回は5VのACアダプタを使っています。
 S−EYEはFPGAを使っているので、出力が高く安定したものを使ってください。6Vニッケル水素や7.4VのLiPoなどを想定しています。7.4Vだと電圧が少々高めなので5Vぐらいの電源回路を組んだ方がよいかもしれません。

 PC側のBluetooth無線ですが、460800bpsだと通信できない機種があるので注意してください。今回は現時点で一番小さいUSBタイプのBluetooth無線機 プリンストン製 PTM-UBT3S を使いました。
 この機種はTOSHIBA系ですが、添付されているソフト TOSHIBA Bluetooth Stack はバグ(?)があり、私の使っている3台のPCにインストールしたところ全てのPCで”TosOBEX”が動きっぱなしになってしまう(PCのCPU稼働率が常に100%近くになり、他のプログラムが動かなくなる)という現象がおきています。これを回避するにはインストール後にコピーされるTosOBEX.exeをリネーム(名前を変える)し、動いているTosOBEXを強制終了させるとよくなります。

 

 AG-BT20Eのページに他の機種を含めたセットアップ方法やBT20Eとの接続方法などが書いてありますので詳しくはそちらを参照願います。

 AG−BT20Eに電源をいれ、PC側のBluetooth側でアプリを起動してデバイスの検出を行うとAG−BT20Eが発見されますのでペアリングを行っておきます。AG−BT20EはRF−COMでSPP接続(仮想シリアルポートになる)です。ペアリング後、PC側Bluetooth無線のプロパティを確認してCOMポート番号を確認して置いてください。今回のPTM−UBT3SはデフォルトでCOM40になるようです。BT20Eを複数台接続することもでき、その時は40番から順番に値が上がっていくようです。

 Bluetoothと書くと長いので以下BTにします。

 現在、私のPCではS-EYEとは別にロボット神経システムもBT接続していますので下記のようになってます。左がCOM40としてS-EYEとつながりました。2つのポートを同一アプリで動かすこともできますので画像結果によりサーボを動かす、ということもできます。
 




センサーとしてのS-EYE

 S-EYEはセンサーとして作っています。カメラではありませんのでWebカメラの動画のように速い表示はできませんし画面サイズも大きくありません。しかし、簡単に実装できるというメリットがあります。今回の例でも.NET Freamworksの標準コンポーネントしか使っていませんし、PC側機器もたった1500円で済みます。また、今回のようにBT経由での接続だと複数のS−EYEを1つのPCに接続できるというメリットもあります。
 データも非圧縮なのでデコードする必要もなく、簡単に計算することができます。よって個人レベルで作る画像認識システムなどに最適です。

 今回はモニタに画像を出しますが、これは画像システムを構築中のデバック用であると考えており、真剣にモニタリングする用途ではありませんのでご了承下さい。但し今回は画像を連続アップデートして動画のような表示にしています。

 S-EYEは、あくまでもセンサーであることを念頭においてください。



画像の高速取得方法について

 C#を含む.NET Feramwork(Visual Studio、VisualBasic、VisualC++など)の初級本では画像の取り扱いにはPictureBoxを使ってSetPicxelで描画する方法が書いてありますが、このSetPicxelメソッド(関数のようなもの)が異常に遅いというのが難点です。
 実際に今回紹介する方法とSetPixcelを使った場合を比べたら、SetPixcelの方は5倍以上の時間がかかりました 。

 ということで今回は初級本などで紹介されている方法ではなく、もっと違った方法を取っています。よってプログラムが少々複雑になりますが、今回のソースをそのまま使えばよいでしょう。この方法はMSDNやネットで調べて作りました。
 まあ、プロの目から見ると普通のことかもしれませんが...




プログラム

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

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

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

 フォームの構成は次のようにしました。連続で画面を更新するプログラムですが、ボタンを付けて一時停止できるようにしています。画面サイズは80x60のカラーにします。ということで80x60サイズのPictureBoxも配置しています。
 
 通信はSerialPort1をドロップするだけ。Timer1は一時停止の状態かどうかの判定を周期的にするのに使用しています。画面を一時停止しなくても良い場合はボタンもタイマも不要でしょう。


 画像フォーマットですが、S-EYEはカラーの場合は2バイトで1ピクセルを表します。今回はRGB565のモードで画像を取得します。PCの表示はRGB各8ビットづつの24ビットカラーで表すのが普通です。ということで、取得する画像データと表示する画像データは次のような関係になります。






 



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

 全体の構成は次のようになっています。行9〜11は標準状態から追加した行で、画像表示メソッド内で使うクラスを使うのに必要な宣言です。
 

 コンストラクタ(スタートアップルーチンみたいな部分)で各コンポーネントの初期設定を行っています。
 今回は画面を80x60のRGB565にしましたので送られてくる1画面は80x60x2=9600バイトになりますが、「SerialPortコンポーネントとBTを連携する場合に受信バッファが少ないとデータ取りこぼしが発生する」 というのを聞いたので受信バッファは必要以上に多く取っています。(それでも15万はやりすぎだったかも。少なくしてもぜんぜんうごきます)
 
 タイマはドロップしただけではEnagledがfalse(つまり動作していない)になっていますので注意。

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


 ボタンとの動きですが、ボタンを押すと単にフラグがかわるだけです。タイマーでは50mS毎にフラグを監視し、"START"だったらS-EYEに対して画像を要求するという感じになっており、STOPボタンを押してフラグがかわると停止、つまり画面をアップデートしなくなります。
 


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

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

 おおきな流れとしては

 1)S-EYEに対して画像要求コマンドを発行(行103:別メソッドにしてます)
 1)描画領域を固定(行107〜112)
 2)データを受信して配列に格納(行113〜120)
 3)RGB565をRGB888(24ビットカラー)に変換(行121〜132)
 4)ピクチャーボックスに表示(行133〜135)

 となっています。

 ポイントは行107〜112の部分です。
 まず、作業用のビットマップを用意してピクチャーボックスに割り当てます。(行107,108)
 次にBitmapクラスでビットマップをロックします。(行109〜111)
 その領域のポインタを作ります(行112)
 このポインタに対して、RGB565−>RGB888に変換したデータをコピーすることで、ビットマップに直接操作するのではなくメモリ上のデータをスパッっと渡すことができ、速く画像を出すことができます。
 
 深く考えずに行107〜112と、行133〜135をそのままコピーして使ってもいいと思います。

 RGB565からRGB888への変換は行125〜127の部分です。単純に2バイトに分散されているRGBの値を3バイトに直してるだけです。画像フォーマットについてはS−EYEのページに詳しく書いてあります。

 ビットマップのカラーの場所ですが、アドレスが小さい順にBGRとなるので注意してください。(行128〜130)

 受信データは1ピクセル2バイト、出力は1ピクセル3バイト、というところがポイントです。



結果

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

 

 速度はだいたい0.5秒毎ぐらいのアップデート速度になりました。ビデオカメラとしては使えませんがセンサーとしてはまあまあかと。この4倍のサイズの160x120も撮れますが、この後、複雑な画像処理をした上でさらにロボットを動かそうと考えると、あまり大きな画像は問題あります。40x30にすると10fps(秒間10枚)ぐらいになりましたので動画っぽく見えました。モノクロにするとさらに2倍速になります。

 下は上の結果を拡大したところです。各ピクセル毎の色の状態がわかるかと思います。
 


 ということでとりあえず画像が取得できるようになりました。次は簡単な画像処理を行ってみたいと思います。



2008年10月16日


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