関西MSP勉強会~Kinect編~ ハンズオン資料 Kinectで身長を計測しよう!
-
Upload
yasutomo-imairi -
Category
Technology
-
view
625 -
download
5
Transcript of 関西MSP勉強会~Kinect編~ ハンズオン資料 Kinectで身長を計測しよう!
ハンズオン講座
~Kinectで身長を計測しよう!~
Microsoft Student Partners Fellow
同志社大学大学院
今入 康友(通称:いまにゅー)
Twitter: @imanyu
Facebook: facebook.com/imanyu
ハンズオンの概要
• Kinectセンサーを使ったデスクトップアプリを作る
•骨格情報から頭と足の位置をセンサーで取得し,その距離を基に計算
• 頭の座標にずれがあるので,深度情報より頭の頂点を求める
WPFアプリケーション
• WPF|Windows Presentation Foundation
•魅力的な外観のユーザーエクスペリエンスを持つWindowsクライアントアプリケーションを作成するための次世代プレゼンテーションシステム
•ビュー(XAML)とロジック(C#/VisualBasic)を分けて作成
• XAMLとC#/VBが連携してプログラムが動きます
•もっと詳しいことを知りたい人はMSDNのWindows Presentation Foundationをご覧ください(http://msdn.microsoft.com/ja-jp/library/ms754130%28v=vs.110%29.aspx)
ザ ム ル
XAMLとC#について
Button
XAML C#
Clickイベント
Clickイベント
{丸の色を青色に変える;
三角を移動させる;
}
目に見える部分を担当(ユーザが見る・使うものを提供)
目に見えない部分を担当(計算したり,XAMLに命令したり)
Hello World!
Kinectセンサー|Kinect for Windows
•ジェスチャーや音声を認識できるセンサーデバイス
• XBOX 360のゲームシステムとして登場
• 3D深度センサー,RGBカメラ,指向性マイクアレイを搭載
開発環境
• Windows 8.1• Windows 7 環境でも大丈夫です
• Visual Studio Professional 2013
• Kinect for Windows SDK v1.8
•グループで1台の機材なので,分担してプログラミングをしよう!
プロジェクトの作成
•ファイル → 新規作成 → プロジェクト
• Visual C# → Windows デスクトップ → WPFアプリケーションを選ぶ
•名前を「KinectHeightMeasure」と入力して,OKを押す
参考資料
•プロジェクトの中身• Properties|プロジェクトの設定が色々入ってる
• 参照設定|ライブラリやアセンブリなどの管理
• App.config|Settings.settingsの中身が記述されてる
• App.xaml/App.xaml.cs|起動時の設定など
• MainWindow.xaml/MainWindow.xaml.cs|メインのプログラムが記述されてる
•今日使うのは,参照設定とMainWindow.xamlとMainWindow.xaml.csを使います
MainWindow.xamlを見てみよう
•初期画面はこんな感じ
これがXAML
デザイナウィンドウXAMLで書かれたものがグラフィカルに表示されるところ
とりあえず実行してみよう
•プロジェクト作成直後の状態で実行できます
•デバッグ → デバッグ開始 / デバッグなしで開始を押してみましょう• F5 または Ctrl + F5 でもOK
•何も表示されないウィンドウが表示されます• ×で閉じてください
ちょこっと勉強会のための用意
•今作ったプロジェクト内のソースを別のものに置き換えます
• MainWindow.xaml内のソースをデスクトップ上「kinect_source_xaml.txt」の中身をコピーして置き換えてください
• MainWindow.xaml.cs内のソースをデスクトップ上「kinect_source_cs.txt」の中身をコピーして置き換えてください
MainWindow.xamlに書き足そう
•ウィンドウサイズを変更• <Window>内のHeightとWidthの数値を変更する
• Height|350 → 511
• Width|525 → 648
•ウィンドウタイトルを変更• <Window>内のTitleを変更する
• Title|MainWindow → Kinectで身長計測
MainWindow.xamlに書き足そう
• KinectのRGBカメラの映像を出すコントロールを追加• <Image>コントロールを使用
• x:Name=“Kinect_image”|コントロールの名前
• Height=“480”|コントロールの高さ
• Width=“640”|コントロールの幅
• <Image x:Name=“kinect_image” Height=“480” Width=“640” /> 【1】
参照設定を追加しよう
• Kinect SDKをプログラムで使用するために参照設定を追加する
• 参照設定を右クリック → 参照の追加 → 左ペインの参照→参照をクリック「C:\Program Files\Microsoft SDKs\Kinect\v1.8\Assemblies」の中からMicrosoft.Kinect.dllを選択して追加を押す
•参照設定にMicrosoft.Kinectが追加されたらOK
MainWindow.xaml.csに書き足そう
• Kinect SDKを使えるようにしましょう• usingを追加しよう
• using Microsoft.Kinect; 【2】
MainWindow.xaml.csに書き足そう
• Kinectセンサーを用意しよう• private KinectSensor kinect;|Kinectセンサーを格納するインスタンス
• try { … } catch { … }|例外処理
• KinectSensor.KinectSensors.Count()|接続されているKinectセンサーの数を数える
• kinect = KinectSensor.KinectSensors[0];|Kinectセンサーを取得する
【3】
【4】
MainWindow.xaml.csに書き足そう
• ColorStream,SkeletonStream,DepthStreamを設定しよう
• RGBストリームを許可する|640×480の大きさ,30フレーム/秒に設定
• 深度ストリームを許可する|640×480の大きさ,30フレーム/秒に設定
• 骨格ストリームを許可する
※Streamとは…
Kinectから送られてくるデータの流れのこと
【5】
MainWindow.xaml.csに書き足そう
•フレームが届いた時の処理を設定する• kinect.AllFramesReady += kinect_AllFramesReady;
• += と書いて,TABキーを2回押すと,自動的にkinect_AllFramesReadyメソッドが生成
• Kinectを開始する• kinect.Start();
【6】
【7】
MainWindow.xaml.csに書き足そう
• ColorImageFrameが届いた時の処理• ColorImageFrame colorFrame = e.OpenColorImageFrame()
• ColorImageFrameを取得する
• colorFrame.CopyPixelDataTo(colorPixel);• colorFrameのピクセルデータをcolorPixel(byte配列)にコピーする
• kinect_image.Source = BitmapSource.Create(~~~~);• XAMLのkinect_imageのSourceにBitmapSourceを代入する
【8】
MainWindow.xaml.csに書き足そう
• DepthImageFrameとSkeletonFrameが届いた時の処理• DepthImageFrame depthFrame = e.OpenDepthImageFrame()
• DepthImageFrameを取得する
• SkeletonFrame skeletonFrame = e.OpenSkeletonFrame()• SkeletonFrameを取得する
【9】
MainWindow.xaml.csに書き足そう
•身長計測用メソッド「MeasureHeightメソッド」を呼び出す• kinect_AllFramesReadyメソッド内で呼び出す
【10】
MainWindow.xaml.csに書き足そう
•身長計測用メソッド「MeasureHeightメソッド」を作ろう• メソッド名:MeasureHeight
• 戻り値の型:void
• 引数1:DepthImageFrame
• 引数2:SkeletonFrame
• private void MeasureHeight(DepthImageFrame depthFrame, SkeletonFrame skeletonFrame) { }
MainWindow.xaml.csに書き足そう
•骨格情報を取得しよう• Skeleton[] skeletons = new skeleton[skeletonFrame.SkeletonArrayLength];
• 骨格情報を格納する配列を用意
• skeletonFrame.CopySkeletonDataTo(skeletons);• 骨格情報を取得する 【11】
MainWindow.xaml.csに書き足そう
•トラッキングされている人物を検出• skeletons[playerIndex].TrackingState == SkeletonTrackingState.Tracked
• TrackedになるまでplayerIndexを1ずつ多くしていく
• if (playerIndex == skeletons.Length)• もしTrackedのものがなければ,処理を中断
• Skeleton skeleton = skeletons[playerIndex++];• トラッキングされている人物のSkeletonだけを取得
• ※DepthImagePixel内のplayerIndexは1から始まるので,playerIndex++とする
【12】
【13】
MainWindow.xaml.csに書き足そう
•各種骨格を取得する• Joint head_joint = skeleton.Joints[JointType.Head];
• Joint footLeft_joint = skeleton.Joints[JointType.FootLeft];
• Joint footRight_joint = skeleton.Joints[JointType.FootRight];
• 各ジョイントがTrackedされていなければ処理を中断
【14】
MainWindow.xaml.csに書き足そう
•深度イメージのデータを取得する• DepthImagePixel[] depthPixel = new DepthImagePixel[depthFrame.PixelDataLength];
• DepthImagePixel構造体の配列を用意
• 16bitの深度情報
• プレイヤーインデックス
• depthFrame.CopyDepthImagePixelDataTo(depthPixel);• depthPixelに深度データを取得する
【15】
MainWindow.xaml.csに書き足そう
•頭の頂点を探そう• kinect.CoordinateMapper.MapSkeletonPointToDepthPoint();
• 骨格データから深度データに座標変換をする
• 認識しているプレイヤーの頭のY座標を1ずつ小さくしていき頂点を探す
• headDepth.Yを更新して,元の骨格データに座標変換する
headDepth.Y
top
y
x
【16】
【17】
【18】
MainWindow.xaml.csに書き足そう
• foot_jointを作成する• Joint foot_joint = footLeft_joint.Position.Y < footRight_joint.Position.Y ?
footLeft_joint : footRight_joint;• 左右のY座標が小さい方を足のY座標とする
• 三項演算子| “条件? trueの時 : falseの時;”
•頭と足のY座標を取得する• double head_y = head_joint.Position.Y;
• double foot_y = foot_joint.Position.Y;
【19】
【20】
MainWindow.xamlに書き足そう
•身長を表示するコントロールを用意しよう• <TextBlock>コントロールを使用
• x:Name=“height_textblock”|名前
• FontSize=“35”|文字の大きさ
• FontWeight=“Bold”|太文字に
• Foregroud=“Red”|文字色を赤色
• <TextBlock x:Name=“height_textblock” Text=“---cm”HorizontalAlignment=“Left” VerticalAlignment=“Top” Foreground=“Red” FontSize=“35” FontWeight=“Bold” />
• Text=“---cm”|表示する文字
• HorizontalAlignment=“Left”|左を基準
• VerticalAlignment=“Top”|上を基準
【21】
MainWindow.xaml.csに書き足そう
•身長を計算しよう• 頭のY座標 – 足のY座標の絶対値が身長となる(単位:メートル)
• Math.Abs()を使用して絶対値を計算する
• 単位がメートルなので100倍してセンチメートルに変換する
• ToStringメソッドで,小数点第一位までを表示する• 小数点第二位で四捨五入される
• 計算結果をXAMLのheight_textblockに表示させる【22】
MainWindow.xaml.csに書き足そう
•身長をわかりやすく表示させよう• 体の横に線(細い四角)を描画する
• 線の真ん中に,身長を表示させる
• 身長をわかりやすく表示するメソッド「DrawHeightメソッド」を作成する• メソッド名:DrawHeight
• 戻り値の型:void
• 引数1:SkeletonPoint|頭
• 引数2:SkeletonPoint|足
MainWindow.xaml.csに書き足そう
•身長をわかりやすく表示させるメソッド「DrawHeightメソッド」を呼び出す• MeasureHeightメソッド内で呼び出す
【23】
MainWindow.xaml.csに書き足そう
• SkeletonPointをColorImagePointに座標変換する• kinect.CoordinateMapper.MapSkeletonPointToColorPointを使用する
【24】
MainWindow.xamlに書き足そう
•追加の情報を載せるコントロールを用意しよう• <Canvas>コントロールを使用
• x:Name=“height_canvas”|コントロールの名前
• Height=“480”|コントロールの高さ
• Width=“640”|コントロールの幅
• <Canvas x:Name=“height_canvas” Height=“480” Width=“640” />
【25】
MainWindow.xaml.csに書き足そう
•線(細い四角形)を作成して,height_canvasに追加しよう• Rectangleで四角形を作成
• Margin:左上右下の位置を設定する
• height_canvas.Children.Addで四角形を追加• height_canvas.Children.Clear();|追加する前に以前追加されたものをすべてクリアする
• height_textblockの位置を調整
【26】
【27】
【28】
完成!!