.NET Gadgeteer : デジカメを作ってみた (低機能だけど一応完成版)

※以下のコードよりも、プレビューが高速なバージョンの情報も公開しています。こちら でどうぞ。

前の記事で コード 4行でデジカメもどき を作ってみました。

wp_000457

“もどき” というくらいなので、撮影前のプレビューもなければ撮影した写真の保存もしませんw
シャッター代わりのボタンを押すと、その時にカメラで拾っていた画像をディスプレイに表示するというもの。これではカメラとは言えない。が、ともかく、いともあっさりとデジカメっぽいものができてしまいます。

恐るべし、.NET Gadgeteer

ならば性能的にはともかく、機能的には最低限デジカメと呼べるものを作ってみましょうか。


前の記事では、自分の中では分かっていることなので、すっかりハードウェア(モジュール)の構成を書くのを忘れてしまいました orz
一応、Visual Studio のデザイナ画面と物理的に結線したものの写真とは載せましたが。

復習を兼ねて前回~今回のデジカメ作成に使ったモジュールを紹介。いずれも tinyclr.jp で購入可能です(ちなみに本家は tinyclr.com)。

  • FEZ Spider Main Board ・・・ これがないと始まりません。Spider はちょっとお高めなので、少しでもイニシャルコストを抑えたい人は Hydra でも大丈夫なはず
  • USB Client DP Module・・・給電したり、アプリケーションを PC から配置したり、のために必要
  • Button Module・・・今回はカメラのシャッターボタンとして使用
  • USB Camera Module・・・USB カメラ。320×240ピクセルと解像度的にはアレですけど実験ですから
  • Display T35 Module・・・液晶画面。タッチ対応ですが今回の記事の範囲では表示専用。サイズは小さくなりますが、多分 OLED Display Module でも行けるんじゃないかと

ちなみに私は FEZ Spider Kit を買いました。繋がるだけのモジュールがセットになっているので、上のモジュール全部入りです。(個人的には他のモジュールやボードも買い増してますけどね)


モジュールの配置

Visual Studio で .NET Gadgeteer のプロジェクトを開き(or 新規作成)、まずはモジュールの配置と結線をします。
前回の記事からの差分で言うと SDCard を追加しています。

image

※注意: この記事を書いている 7月14日現在では、.NET Micro Framework と Gadgeteer 用パッケージは v4.1 を使ってください。v4.2 ベータが出ていますが、SDCard を繋ぐとスタートアップでいきなり例外を吐いて動作してくれません。v4.2 での対応ももう少しの辛抱だと思いますが、今やると確実にハマります。私はこれにハマってしばらく唸ってました orz


コーディング(1):プレビュー機能

撮影前にカメラでとらえている映像をプレビューできるようにします。
お手軽にタイマーで定期的にカメラモジュールから映像をキャプチャすることにします。
ただし実際にやってみると分かるのですが、この方法だとキャプチャの間隔は毎秒2~3回程度が限界のようです。そこを認識した上でコードを見てみます。

image

インターバルが 100ms のタイマーを作っておきます。
プレビュー中かどうかは他にも取得する方法はありますが(例えば、タイマーの動作を見るなど)、今回はフラグを用意しました。

image

タイマーの Tick イベントハンドラの定義をします。
Camera がキャプチャー可能な状態かどうかを確認してキャプチャーします。前回の記事ですでにカメラの PictureCaptured イベントハンドラは定義してあるので、そちらはそのままで OK。
なお上のコードでは SDCard のイベントハンドラについての記述もありますが、すぐに使うのでちょっとだけ気にしないでおいてください。

image

プレビュー機能の実装の最後に、ボタンの Pressed イベントハンドラを見てみます。
previewing 変数の値を見て、タイマーを起動する/止めるを切り替えています。現在プレビュー中でボタンが押された時には写真撮影の意味なので、その時点で改めて TakePicture します。
また Button モジュールには LED が付いているので、プレビュー状態にあわせてこの LED を点灯/消灯もしています。

これで撮影前にプレビューできます。ボタンを押すと撮影、もう一度ボタンを押すとプレビュー再開という動作になります。


コーディング(2):写真の保存

image

.NET Gadgeteer には StorageDevice というファイルシステムが用意されています。
SDカードの Mount / Unmount イベントハンドラで storage 変数を操作します。

image

SDカードに画像を保存するために、PictureCaptured イベントハンドラを少し変更します。

image

image

SavePicture メソッドでは、storage 変数が null の時は、SDカードが挿入されていないので何もしないで終了します。
SDカードが挿入されていれば、まず DateTime.Now を使って一意のファイル名を決めます。

ファイルシステムにファイルを書き込むには WriteFile メソッドを使います。またしてもそのまんまのメソッド名、簡単ですね。
書き込む内容としては撮影した画像の byte配列です。ということで画像のフォーマットは BMP です。

以上でデジカメは完成。プレビュー間隔が長いこと、写真の解像度/フォーマットはちょっと残念な感じですが、デジカメとしての一連の機能はできました。
簡単ですよね。記述したコードは前回の記事+今回の記事のものだけです。簡単すぎるにも程があるというものです。
場合によっては、もっとパフォーマンスが稼げるデバイスを使うほうがいいこともあると思いますが、組み込みのノウハウがなくても、この程度は作れる、しかも非常に簡単に作れるというのはすごいです。

.NET Gadgeteer、ちょっと注目したくなりません?


全ソースコード

今回の全てのソースコードは以下の通り。(不要な using 句も入ってますが、とりあえずそのままで載せます)

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace GadgeteerApp1
{
    public partial class Program
    {
        GT.Timer timer = new GT.Timer(100);
        bool previewing = false;

        GT.StorageDevice storage;

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            button.ButtonPressed += new Button.ButtonEventHandler(button_ButtonPressed);
            camera.PictureCaptured += new Camera.PictureCapturedEventHandler(camera_PictureCaptured);

            sdCard.SDCardMounted += new SDCard.SDCardMountedEventHandler(sdCard_SDCardMounted);
            sdCard.SDCardUnmounted += new SDCard.SDCardUnmountedEventHandler(sdCard_SDCardUnmounted);

            timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);
            timer.Stop();

            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
        }

        void timer_Tick(GT.Timer timer)
        {
            if (camera.CameraReady)
                camera.TakePicture();
        }

        void camera_PictureCaptured(Camera sender, GT.Picture picture)
        {
            display.SimpleGraphics.DisplayImage(picture, 0, 0);

            if (!previewing)
                SavePicture(picture);
        }

        void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
            if (previewing)
            {
                timer.Stop();
                camera.TakePicture();
                button.TurnLEDOff();
            }
            else
            {
                timer.Start();
                button.TurnLEDOn();
            }

            previewing = !previewing;
        }

        private void SavePicture(GT.Picture picture)
        {
            if (storage == null)
                return;

            string filename = "pict_" + DateTime.Now.ToString("yyyyMMdd-HHmmss") + ".bmp";
            storage.WriteFile(filename, picture.PictureData);
        }

        void sdCard_SDCardMounted(SDCard sender, GT.StorageDevice SDCard)
        {
            storage = SDCard;
        }

        void sdCard_SDCardUnmounted(SDCard sender)
        {
            storage = null;
        }
    }
}

 

せっかくなので実際に撮影した写真も載せときましょうか。

pict_20090101-000148pict_20090101-000254

広告
カテゴリー: .NET Micro Framework タグ: , パーマリンク

.NET Gadgeteer : デジカメを作ってみた (低機能だけど一応完成版) への2件のフィードバック

  1. ピンバック: .NET Gadgeteer : デジカメを作ってみた Part 2 (プレビュー高速版) « 技術との戯れ

  2. ピンバック: .NET Gadgeteer : コード 4行でデジカメ(もどき) « 技術との戯れ

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中