Rx と OpenCVSharp を使用して 簡単にカメラキャプチャアプリを作成する


はじめに

 ここ数年はプロジェクトに切れ目が無く(しかもタイトスケジュール)自分の自己鍛錬がおろそかになってましたが、めでたく社内ニートとなりました 。 これを機会に色々なことにチャレンジしてアップしようかと考えています。
 自分の経験分野は C# / WPF / MVVMなので、それを組み合わせてできることを実験していきたいと思います。

カメラキャプチャアプリ

 WPF / MVVM / Rx(Reactive Extensions) / OpenCV を組み合わせると、1時間ほどで、カメラキャプチャアプリが作成できます。
今回はそれを紹介します。

MVVMフレームワーク

Livetは ugaya40 さんが中心となって開発した国産のMVVMフレームワークです。
メジャーなところでは、PRISMMVVM Light Toolkit など色々ありますが、まずは国産というところで安心感があるのではないでしょうか。

Livet導入

Livetの導入は、Livetのセットアッププログラムを入手し、セットアップを行うだけです。

Rx(Reactive Extensions)導入

NuGetで入手します。

OpenCVSharp導入

NuGetで入手します。

作成手順

  1. VS2013を起動して新規プロジェクトを作成する際に「Livet WPF4.5 MVVMアプリケーション」を選択して下さい。

  2. ここで気をつけたいことは、Livetのプロジェクトを作成するとソリュ-ションプラットフォームが「x86」になります。後で導入する「OpenCVSharp」は「AnyCPU」以外だと導入の最後でエラーになりますので、ここで「AnyCPU」を作成して下さい。

    • ソリューションプラットフォームのコンボボックスを選択
    • 「構成マネージャー」を選択し、構成マネージャーを開く
    • 「アクティブソリューションプラットフォーム」から「新規作成」を選択
    • 「新しいソリューションプラットフォーム」の画面が開くので、「Any CPU」が表示されているのを確認して、「OK」を押す。
    • 以上で「Any CPU」が作成されます。

  3. パッケージを導入します。
    [ツール]-[NuGetパッケージマネージャ]-[パッケージマネージャーコンソール]を選択し、NuGetのコンソールを開いて下さい。

  4. Rx(Reactive Extensions)パッケージを導入して下さい。
    PM> Install-Package Rx-WPF

  5. 続いて、OpenCVSharpパッケージを導入して下さい。
    PM>Install-Package OpenCvSharp-AnyCPU

以上で下準備は終わりです。

実装

ViewModel側

ViewModelsのフォルダーの中に、MainWindowViewModel.csがありますので、開いて下さい。
using の追加定義は次の通り

MainWindowViewModel.cs
using System.Reactive.Linq;
using System.Reactive.Concurrency;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using System.Windows.Media.Imaging;

次にpublic void Initialize()付近を次のコードへ書き換えて下さい。

MainWindowViewModel.cs
#region ImageSource 表示画像
private BitmapSource _CaptureImageSource;
/// <summary>
/// 表示画像
/// </summary>
public BitmapSource CaptureImageSource
{
    get
    { return _CaptureImageSource; }
    set
    { 
        if (_CaptureImageSource == value)
            return;
        _CaptureImageSource = value;
        RaisePropertyChanged();
    }
}
#endregion

/// <summary>
/// 初期化
/// </summary>
public void Initialize()
{
    var capture = new CvCapture(0);
    Observable.Interval(TimeSpan.FromMilliseconds(1), DispatcherScheduler.Current)
        .Select(_ => Cv.QueryFrame(capture))
        .Where(frame => frame != null)
        .Subscribe(frame =>
        {
            var bitmapSource = frame.ToBitmapSource();
            frame.Dispose();
            this.CaptureImageSource = bitmapSource;
        });
}

View側

Viewsフォルダーの中にあるMainWindow.xamlを開いて、<Grid>付近を次のように書き換えて下さい。

MainWindow.xaml
<Grid>
    <Image Source="{Binding CaptureImageSource}" />
</Grid>

実行

VS2013の「開始」ボタンを押して、実行して下さい。
PCにWebカメラが付いていたら、画像が現れるはずです。

すごく簡単にキャプチャープログラムができます。