Network Cameraを作ってみよう(3) Webサーバとカメラを結合

ここまでくればあと一息である。最終目的である、撮影した画像をWebサーバ経由で配信、というシステムに仕立て上げてみよう。

配線は図4の様に、単に図1と図3を組み合わせただけである。もちろんパルストランス無しでよければ図2と図3を組み合わせればよいので配線は更に楽だろう。

図4 撮影した画像をWebサーバ経由で配信というシステムの配線図

さてプログラムの方だが、Ilya I氏作のpub_iva2k_ethrpcを流用させていただいた。mbedのcookbookにも様々なWebサーバが載っているが、敢えてこちらを使ったのは

  • 当初から内蔵メモリをサポート
  • 画像転送などもサポート
  • 比較的構造が簡単で手を入れやすい
  • DHCPで立ち上がる

というあたりである。またSDカードをサポートしており、ソースを見る限り☆board Orangeと組み合わせればそのまま利用できそうなのも便利だ(pub_iva2k_ethrpc自身は、mbed-BoB2というベースボードでの動作を想定しているようだが)。変わったところでは、Dynamic HTMLをサポートしているのもちょっと将来の拡張に便利そうだ、と思える。

さて手順であるが、

  1. SummaryページでImport this programを使い、プログラムをまるごと自分のワークスペースに取り込む(ついでにこの際、名前も変えておく)
  2. Camera_LS_Y201のライブラリを取り込む(先の「カメラのハンドリング」で説明した通りだ)
  3. main.cppを書き換える
  4. コンパイル・リンクを行い、mbedにコピーする
  5. mbedをリセットする

という手順で完了である。再起動後、http://192.168.1.126/picture.jpg (←IPアドレスは各々の環境によって異なる)にアクセスすれば、こんな具合にカメラ映像が表示される筈だ(Photo37)。

Photo37:この形式の場合、FirefoxやOperaでは問題がなかったのに、IE8ではうまく表示がされなかった。しかもindex.htmを置くと、IE8でもちゃんと表示される。不思議だ

もうちょっとソフィストケイトしたものを…というのであれば、List 2の様なファイルをindex.htmという名前でmbedにコピーすればhttp://192.168.1.126/ (←IPアドレスは各々の環境によって異なる)にアクセスするだけで画像が表示されるし、しかも自動的に一定期間(List 2の場合は5分間)で画面が更新されるようになる。

さて、ではmain.cppをどう書き換えるかという話である。書き換えた後のソースをList 3に示すので見比べていただきたい。ポイントとしては

  • カメラの画像取り込み用にcaptureImage()とcamera_callback()を追加
  • main()の最後、while(1)でメインループに入る直前で、カメラの初期化処理を追加
  • main()のループの中で、一定期間(今回の場合は約60秒)ごとに1回ずつ画像をカメラから取り込み、それを"/local/picture.jpg"という名前で上書き保存する

といったあたりとなる。この「60秒」をどうやって設定するかだが、プログラムを見ていただくとお分かりだが、元のhttpサーバのプログラムでは、http.poll()という、HTTPリクエストが来ているかどうかの判断を5msごとに行っている。もっと正確に書けば、http.poll()を呼び出して、何もないと判断したら5msの間wait()で待機し、再びhttp.poll()を呼び出すという仕組みである。そこで12000回http.poll()を呼び出したら(つまり5ms×12000回=60秒wait()で待機したら)、カメラからの画像取得を1回行うという、割とベタな実装になっている。

ちなみにコンソールにはこんな具合(Photo38)にカメラ関係のデバッグメッセージが表示されるようになっている。ただしこれはmain.cppの冒頭で

int gDebug=1;

となっている部分を

int gDebug=0;

にすると、いきなり出なくなるように配慮している。gDebug自身は元々pubiva2kethrpcの中で利用されているデバッグレベルの値で、これにあわせてメッセージの出方を変えるようにしている。

Photo38:デバッグのためもあり、画面にはかなり細かくメッセージを出すようにした

余談になるが、今回利用したシリアルカメラは、(通信がシリアルだけあって)かなり通信が遅い。カメラの解像度は160x120、320x240、640x480の3種類が選べるが、実際に撮影した結果(Photo39~41)では、撮影後のデータ転送時間が

160×120ピクセル:2秒程度 320×240ピクセル:7秒程度 640×480ピクセル:25秒程度

となっている。ほぼファイルサイズに比例、という感じであるが問題なのはこのファイル転送中はWebサーバとして反応できないことで、このあたりの改善は今後の課題かもしれない。設定はmain()の中のカメラの初期化の部分で、cam.setImageSize()の引数で決まる(更に余談だが、Camera_LS_Y201ライブラリでは、なぜか320x240ピクセルの指定が"ImageSize320x280"になっている。撮影した画像はちゃんと320x240ピクセルなので、これは純粋にラベル名だけの問題である)が、テストした感触では320x240ピクセルがちょうど手ごろ、という感じである(7秒くらいならブラウザがタイムアウトすることはまずないため)。

Photo39:160x120ピクセル。ファイルサイズは3.6KB

Photo40:320x240ピクセル(拡大画像)。ファイルサイズは12.2KB

Photo41:640x480ピクセル(拡大画像)。ファイルサイズは47.3KB