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


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

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

#MVVMフレームワーク
[Livet](http://ugaya40.hateblo.jp/entry/Livet)は ugaya40 さんが中心となって開発した国産のMVVMフレームワークです。
メジャーなところでは、[PRISM](http://compositewpf.codeplex.com/)や[MVVM Light Toolkit](http://mvvmlight.codeplex.com/) など色々ありますが、まずは国産というところで安心感があるのではないでしょうか。

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

###Rx(Reactive Extensions)導入
NuGetで入手します。

###OpenCVSharp導入
NuGetで入手します。

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

1. ここで気をつけたいことは、Livetのプロジェクトを作成するとソリュ－ションプラットフォームが「x86」になります。後で導入する「OpenCVSharp」は「AnyCPU」以外だと導入の最後でエラーになりますので、ここで「AnyCPU」を作成して下さい。
<p/>
 * ソリューションプラットフォームのコンボボックスを選択<br/>![1.png](https://qiita-image-store.s3.amazonaws.com/0/28247/f6ad602e-5125-2aac-fe55-888bcf751320.png)
 * 「構成マネージャー」を選択し、構成マネージャーを開く
 * 「アクティブソリューションプラットフォーム」から「新規作成」を選択<br/>![2.png](https://qiita-image-store.s3.amazonaws.com/0/28247/fed229d9-9074-72c5-2a02-8a6aa8deef0c.png)
 *  「新しいソリューションプラットフォーム」の画面が開くので、「Any CPU」が表示されているのを確認して、「OK」を押す。<br/>![3.png](https://qiita-image-store.s3.amazonaws.com/0/28247/ca23c074-c3bc-da10-4013-262eda8431f3.png)
 *  以上で「Any CPU」が作成されます。<br/>![4.png](https://qiita-image-store.s3.amazonaws.com/0/28247/50615bbc-dc69-b88b-c7a8-b86392364165.png)
<p/>
1. パッケージを導入します。
\[ツール]-\[NuGetパッケージマネージャ]-[パッケージマネージャーコンソール]を選択し、NuGetのコンソールを開いて下さい。
<p/>
1. Rx(Reactive Extensions)パッケージを導入して下さい。
`PM> Install-Package Rx-WPF`
<p/>
1. 続いて、OpenCVSharpパッケージを導入して下さい。
`PM>Install-Package OpenCvSharp-AnyCPU`

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

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

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

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

```csharp: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>`付近を次のように書き換えて下さい。

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

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

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