書籍転載:Intel RealSense SDKセンサープログラミング(5)
WPF(Visual Studio)+RealSenseで作る表情感知アプリ
― Chapter 9 Visual Studioで作る「WPFデスクトップ」アプリケーション ―
インテル RealSenseを活用したサンプルアプリケーション開発の第2弾として、Visual StudioとRealSenseを組み合わせる方法を紹介する。
前々回と前回は、インテル RealSense SDKとUnityを使ったサンプルアプリケーションを実際に作成してみました。
書籍転載について
本コーナーは、翔泳社発行の書籍『Intel RealSense SDKセンサープログラミング』の中から、特にBuild Insiderの読者に有用だと考えられる項目を編集部が選び、同社の許可を得て転載したものです。
『Intel RealSense SDKセンサープログラミング』の詳細や購入は翔泳社のサイトや目次ページをご覧ください。プログラムのダウンロードも、翔泳社のサイトから行えます。
ご注意
本記事は、書籍の内容を改変することなく、そのまま転載したものです。このため用字用語の統一ルールなどはBuild Insiderのそれとは一致しません。あらかじめご了承ください。
■
本章では、Windowsデスクトップで稼働するWPF(Windows Presen tation Foundation)アプリでRealSenseを使う方法を紹介します。WPFアプリの画面デザインやプログラム構造は、Windows 10で稼働する「Windows 10 universal app」でも通用するノウハウです。その時が来たときに、なるべくそのままのコードで動くコードとなるように配慮してサンプルアプリを開発しました。
9-1 表情と気分とコーヒーと
本章でとりあげるサンプルは、「Sensor & Coffee」というアプリです。Sensor & Coffeeは、インテル RealSense 3Dカメラでセンシングした表情を基にして、その日の気分にあったコーヒーを教えてくれるというものです。
9-1-1 Sensor & Coffee
WPFアプリとしてのサンプルには何が良いかを考えたとき、やはりWPFが実際に使われる機会の多い分野が良いだろうと思いました。そうしてアイデア出しを進めるうちに、やはりゲームよりも業務アプリ、もしかしたらB to Cアプリがよいのではないかという考えに至りました。こうして方向性を絞り込めたとき思い浮かんだのが、以前に作成した、そのときの気分に合ったコーヒーを教えてくれる「Selfi & Coffee」というアプリで、これをRealSense対応にしようと決めました。
今回とりあげるSensor & Coffeeは、カフェのレジでコーヒーのオーダーに迷ったときに使われることを想定しています。そのため、なるべく操作は簡単に、そして必要なときにだけセンシングすることでレジに並んだ人を不用意にセンシングしないように配慮しています。
9-2 画面デザイン
利用シーンが決まったので、その利用シーンにマッチするような画面遷移(画面の流れ)や画面デザインを検討します。同時にどのタイミングでどのようなセンサー値を取得するのかも考えます。この検討の過程で場合によっては、もっと適切なセンサーが必要になるかも知れません。その点、RealSenseは様々なセンシング機能を備えており、懐の深い対応が可能なので、センサー変更が必要になる場面はかなり少ないデバイスといえるでしょう。
9-2-1 全体の動き
まずはアプリの画面遷移(画面の流れ)を決めて、それから個々の画面デザインを詰めていきましょう。今回は、以下の4画面で構成することにします。
- 「TRY 画面」ではアプリの説明を行う
- カメラ画面」でカウントダウンののち自撮りを行う
- 「結果画面」では自撮りと測定の結果を表示する
- 最後に「お勧め画面」で測定結果から判定したお勧めコーヒーを表示する
RealSenseは2の「カメラ画面」において画像表示とセンシングのために使うことにしましょう。
9-2-2 画面デザイン
全体の流れが決まったら、個々の画面のデザインを行います。今回の画面デザインは「Selfi & Coffee」というアプリのデザインを踏襲しています。このアプリのデザインは301 Inc.*1さんにご協力を頂きました。すごくふんわりした依頼なのにアプリ作成意欲がモリモリ湧いてくるような素晴らしいデザインでしたので、改めてお願いをして本サンプルアプリにもデザインを使わせて頂きました。ありがとうございます。
- *1 301 Inc.
それでは、みなさんにも本章を読み進める意欲がモリモリ湧いてくるように、完成したアプリの動きをまずご紹介しましょう。
9-3 開発プロジェクトの用意
Visual StudioでWPFアプリを作成するために、画面定義やコードの記述に先立ってWPFアプリケーションプロジェクトに行っておく準備について説明します。
9-3-1 新規プロジェクトの作成
Visual Studioを起動したらWPFアプリを作成するために[ファイル]メニューから[新しいプロジェクト]メニューをクリックして「新しいプロジェクト」ダイアログを開き、WPFアプリのプロジェクトを作成します。WPFアプリのプロジェクトを作るための指定は次のようになります(図9.3)。
- 1[テンプレート]をクリック
- 2開発言語の中から[Visual C#]をクリック
- 3アプリ形態の中から[Windows デスクトップ]をクリック
- 4テンプレート一覧から[WPF アプリケーション]をクリック
- 5[名前]欄にアプリ名を入れる(本アプリでは「SensorCoffee」と入力)
- 6入力内容を確認したら[OK]をクリック
9-3-2 インテル RealSense SDKの設定
本章ではOSが64ビットの場合でもVisual StudioでのWPFエディタでの動作を考えてソリューションプラットフォームとして「x86」、つまり、32ビットを指定している事を前提とします。ソリューションプラットフォームを「Any CPU」から「x86」へ切り替えるには、Visual Studioの[ビルド]メニューから[構成マネージャー]をクリックして、「構成マネージャー」ダイアログを開いて行います(図9.4)。
- 1[アクティブソリューションプラットフォーム]ドロップダウンリストをクリック
- 2[x86]を選択する。もし、「x86」がなければ[新規作成]を選択
- 3[新しいプラットフォームを入力または選択してください]コンボボックスで[x86]を選択
- 4[OK]をクリック
ソリューションプラットフォームの設定が完了したら、32ビットのインテル RealSense SDKの設定を行います。インテル RealSense SDKの設定の詳細は、本書の「Chapter 2 Visual Studioによる開発の準備」(※転載対象外)を参照してください。
9-3-3 プロジェクト構造の作成
本章で作成するサンプルアプリでは、ロジック部分と画面デザインを明確に分離しています。そして、ロジックと画面デザインに含まれているコードを視覚的にもわかりやすくするために、ロジックはModelsフォルダ、画面デザインはViewsフォルダに格納します。
このようにしておけばセンサー関連のコードと画面デザインが分離できるので、画面デザインをデザイナーさんにお願いするようなときに便利です。
ロジックと画面デザイン以外にも、画像ファイルを格納するフォルダやデザイン用のサンプルデータを提供するクラスを格納するフォルダなども用意しておきます。
Visual Studioで図9.5のような各フォルダを作成しておいてください。
9-3-4 データバインディングとM-V-VM
本章のサンプルではデータバインディング(Binding)という方法を使ってロジックと画面を接続しています(図9.6)。
この方法の特徴は、画面デザイン(UI)とロジックを分離できる点にあります。画面デザインの中でText="{Binding A}"
としているのですが、プロパティAは存在している必要はありません。プロパティAがあればプロパティAの値が自動的にTextに割り当てられますし、なければTextには値が設定されないだけでコンパイルエラーにも実行時エラーにもなりません。
つまり、ViewModelのプロパティの実装状態を気にせず画面デザインを進めていくことができます。このように分離しておけばロジックを変更してセンサーを差し替えたり、UIを変更して別アプリにしたりすることも容易です。本章のサンプルアプリも別のセンサー用に作成したアプリのロジックをRealSense用に差し替えたものをベースにしています。
Bindingを使えば実装とは離れて画面デザインができることがわかりましたが、それでは、XAMLではどのようにしてプロパティAの値が更新されたときに表示を更新するのでしょうか。XAML側において一定間隔でプロパティの値が変更されるのをチェックする方法も考えられるでしょうが、それでは画面項目数が多くなると更新チェック処理が煩雑になってしまいます。じつは、WPFではINotifyPropertyChanged
インタフェースを使って更新時の通知をXAMLに伝搬するような仕組みが用意されています。
- 1プロパティAの値を更新
- 2PropertyChangedイベントを発生させる
- 3ターゲット側でイベントをキャッチ
- 4イベントパラメーターに指定されたプロパティAの値を取得してプロパティに設定
9-4 画面の作成
Sensor & Coffeeアプリの画面定義について説明します。
9-4-1 画面全体構成の作成
デザイナーさんに作成していただいた画面デザインは、そのまま使う画像部分と文字などの部分とを分離して利用します。そのため、納品してもらうデザインの画像データは、あらかじめ利用部材ごとにレイヤーを分けてもらえるように伝えておくと、開発作業もとても楽になりますし、デザイナーさんに何度もパーツの切り出しをお願いしなくても済みます。
最初に確認したように、今回のアプリは次の4つの画面から構成されています。
- Try画面
- カメラ画面
- 結果画面
- お勧め画面
この1つ1つをページとして定義し、ナビゲーションウィンドウ(MainWindow.xaml)を使って画面間の移動を制御するようにしましょう。Visual Studioで[Views]フォルダを右クリックして図9.8のようにメニューを選び、「新しい項目の追加」ダイアログで[ウィンドウ]を選択して名前を「MainWindow.xaml」にしてから[追加]をクリックします。するとViewsフォルダに「MainWindow.xaml」が追加できます。
今回は単なるウィンドウではなくナビゲーションウィンドウを使うので、ViewsフォルダにMainWindow.xamlが追加されたら、その中身をリスト9.1のように書き換えておきます。
<NavigationWindow
x:Class="SensorCoffee.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Sensor Coffee" Height="854" Width="480"
ResizeMode="NoResize" ShowsNavigationUI="False"
WindowStartupLocation="CenterScreen" >
</NavigationWindow>
|
次に、MainWindow.xamlを右クリックして[コードの表示]を選択し、MainWindow.xamlのコードビハインド側であるMainWindow.xaml.csを開いてリスト9.2のように書き換えます。
using System.Windows.Navigation;
namespace SensorCoffee.Views
{
public partial class MainWindow : NavigationWindow
{
public MainWindow()
{
InitializeComponent();
this.DataContext = App.MainVM;
this.NavigationService.Navigate(new LaunchPage());
}
}
}
|
App.MainVM
やLaunchPage()
の部分がしばらくはビルドエラーとなりますが、後で解消するので気にせず作業を進めていきましょう。
同様にして、Viewsフォルダを右クリックして[追加]→[新しい項目]を選択し、「新しい項目の追加」ダイアログで[ページ]を選んで4つのページも追加します(図9.9)。
- 1「Try 画面」をLaunchPage.xamlという名前で追加
- 2「カメラ画面」をCameraPage.xamlという名前で追加
- 3「結果画面」をResultPage.xamlという名前で追加
- 4「お勧め画面」をCoffeePage.xamlという名前で追加
9-4-2 CameraPageの作成
画面の中でも特に重要なのがCameraPage.xamlになります。この画面はインテルReal Sense 3Dカメラが捉えた画像を表示しながら、同時に表情もセンシングするときに表示する画面です。この画面のデザインは次のようになります。
この画面を定義するためのXAMLコードは、リスト9.3のようになります。
<Page
x:Class="SensorCoffee.Views.CameraPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SensorCoffee.Views"
mc:Ignorable="d"
d:DesignHeight="854" d:DesignWidth="480" Background="#FFE5DBD0" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition />
<RowDefinition Height="80" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Background="#736357"/>
<Grid Grid.Row="1">
<Image Source="{Binding ColorImageElement}" Stretch="UniformToFill" HorizontalAlignment="Center" />
<TextBlock Text="{Binding Counter}" FontSize="500" Foreground="#FF00B26C" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
<Label Grid.Row="2" Background="#736357"/>
</Grid>
</Page>
|
この画面定義の中で特に重要なのがImageコントロールです。
<Image Source="{Binding ColorImageElement}"
Stretch="UniformToFill"
HorizontalAlignment="Center" />
|
ColorImageElement
という要素をBindingしてSource
プロパティに指定しています。この指定によりColorImageElement
の内容を画像として表示してくれます。内容が変われば自動的に表示も変わりますので、RealSenseのようにカメラがとらえた映像が1枚1枚送られてきて、それを次々に表示することでカメラプレビュー表示となるようなときに非常に便利です。
このColorImageElement
がどこから来るかといえば、コードビハインド側でDataContext
に次のような指定をしておきます。
this.DataContext = App.MainVM;
|
このままだとApp.MainVM
の部分でビルドエラーが出ます。
9-4-3 App.xaml.csの更新
MainWindow.xaml.csやCameraPage.xaml.csのコンパイルエラーを解消するためにApp.xamlのコードビハインド側であるApp.xaml.csをリスト9.4のように更新します。
using System.Windows;
namespace SensorCoffee
{
public partial class App : Application
{
private static SensorCoffee.ViewModels.MainViewModel _MainVM = null;
public static SensorCoffee.ViewModels.MainViewModel MainVM
{
get
{
if (_MainVM == null)
{
_MainVM = new SensorCoffee.ViewModels.MainViewModel();
}
return _MainVM;
}
}
}
}
|
これでビルドエラーの箇所が、App.xaml.csのMainViewModel
の部分に変わります。
9-4-4 MainViewModelクラスの追加
ソリューションエクスプローラで[ViewModels]フォルダを右クリックし、[追加]→[新しい項目]と選択して、ウィンドウやページと同じように[クラス]を指定してダイアログで「MainViewModel.cs」という名前のクラスを追加します。
作成された「MainViewModel.cs」の中でColorImageElement
を定義します(リスト9.5)。
private Models.RSModel RS = new Models.RSModel();
public ImageSource ColorImageElement
{
get { return this.RS.ColorImageElement; }
set { this.RS.ColorImageElement = value; }
}
|
これで表示側の準備が整いましたのでいよいよセンシング部分に取り掛かりましょう。
■
次回は、今回に続き、RealSenseとVisual Studioを使ったサンプルアプリケーションを実際に作成してみます。
※以下では、本稿の前後を合わせて5回分(第3回~第7回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
3. RealSense SDK Unity ToolkitによるUnityアプリ開発の基礎
インテル RealSense SDK Unity Toolkitの概要と、それがUnity向けに用意している各種機能を紹介する。
5. 【現在、表示中】≫ WPF(Visual Studio)+RealSenseで作る表情感知アプリ
インテル RealSenseを活用したサンプルアプリケーション開発の第2弾として、Visual StudioとRealSenseを組み合わせる方法を紹介する。
6. Visual Studioで活用するRealSenseセンシング機能
RealSenseとVisual Studioを使ったサンプルアプリケーションで、RealSenseのセンサーから情報を取得してみる。
7. openFrameworksで作成するメディアアート入門
インテル RealSenseを活用したサンプルアプリケーション開発の第3弾として、openFrameworksとRealSenseを組み合わせる方法を紹介する。