Kinect v2を使って、机の上のリンゴをつかんで移動してみる
![](https://thinkit.co.jp/sites/default/files/styles/main_image_730x/public/main_images/5451_main_8.jpg?itok=5sFla92W)
今回のサンプルは、机の上に置かれたリンゴをつかんで、別な場所に移動するサンプルです。
今回のプログラムも、WPFアプリケーションとして作成します。まずはプロジェクトからの作成です。
プロジェクトを作成する
VS2013メニューの[ファイル]ー[新しいプロジェクト]と選択し、表示される画面から、「テンプレート」に「Visual Basic」を指定し、「WPF アプリケーション」を選択します。名前に「AppleMove」と指定し、「OK」ボタンをクリックします。
画像の追加
ソリューションエクスプローラー内の「AppleMove」を選択し、マウスの右クリックで表示されるメニューから、[追加]ー[新しいフォルダー]と選択し、「Images」というフォルダーを作成します。作成した「Images」フォルダーを選択し、マウスの右クリックで表示されるメニューから、[追加]−[既存の項目]と選択して、リンゴと机のPNG画像2枚を追加しておきます。
これらはダウンロードされたサンプルファイル(AppleMove.zip)に含まれていますので、ご確認ください。
参照設定
参照設定については、連載の第2回目と全く同じですので、そちらを参照してください。
コントロールの配置
「MainWindow.xaml」画面内に、ツールボックスから「Image」コントロールを3個と「Canvas」コントロールを2個配置します。
- 最初のImageは、RGBカメラで室内の様子を映すために使用し、名前を「roomImage」としておきます。
- 次のImageには、ソリューションエクスプローラー内のImagesフォルダーにある机の画像を表示しておきます。
- 3つ目のImageは、名前を「Image1」と指定し、ソリューションエクスプローラー内のImagesフォルダーにあるリンゴの画像を配置しておきます。
- 最初のCanvasは、名前を「appleCanvas」と指定します。移動したリンゴを表示させるための領域です。
- 次のCanvasは、プレイヤーの関節の位置を表示させる領域で、名前を「CanvasBody」と指定しておきます。表示する円の色を透明色にしますので、画面上では見えません。
全て設定すると図1のようになります。
![全てのコントロールを配置した状態](/sites/default/files/545101.jpg)
図1:全てのコントロールを配置した状態
これらのコードを書き出すとリスト1のようになります。
リスト1:MainWindow.xaml
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="424" Width="512"> <Grid> <Image x:Name="roomImage" /> ■(1) <Canvas x:Name="appleCanvas" Width="512" Height="424" Margin="0,-31,-8,0" /> ■(4) <Canvas x:Name="CanvasBody" Width="512" Height="424" Margin="0,-31,-8,0" /> ■(5) <Image Canvas.Left="24" Canvas.Top="256" Width="449" Margin="25,230,30,10" x:Name="deskImage" Stretch="UniformToFill" Source="Images/机.png" /> ■(2) <Image x:Name="Image1" Source="Images/apple.png" Margin="385,179,54,154"/> ■(3) </Grid> </Window>
プログラムコード
次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示されるMainWindow.xam.vbに、リスト2以降のコードを記述します。
名前空間の読み込みとメンバー変数の宣言
リスト2:MainWindow.xaml.vbの一部
Imports Microsoft.Kinect Imports System.ComponentModel Public Class MainWindow Private myKinect As KinectSensor Private myBodyFrameReader As BodyFrameReader Private myBodies As Body() Private myHandPositionX As Double Private myHandPositionY As Double Private myColorSpacePoint As ColorSpacePoint (1) Private myBytesPerPixel As Integer = 4 Private myColorFrameReader As ColorFrameReader = Nothing Private colorBitmap As WriteableBitmap = Nothing Private ColorImagePixelData As Byte() Private BytesPerPixel As Integer = 4 Private commonJoint As Joint (2) Private point As DepthSpacePoint (3) Private myImage As Image (4) Private flag As Boolean = False
連載第2回目と共通の部分が多いので、ここでは異なるメンバー変数の主なものだけ解説しておきます。1.カラー空間における2Dの位置を表す構造体のメンバー変数myColorSpacePointを宣言します。2.身体の関節の位置を表すJoint構造体のメンバー変数commonJointを宣言します。3.距離空間における2Dの位置を表す構造体のメンバー変数pointを宣言します。4.Imageクラス型のメンバー変数myImageを宣言します。
ウインドウが読み込まれた時の処理
リスト3:MainWindow.xaml.vbの一部、リスト2の続き
Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded myKinect = KinectSensor.GetDefault (1) myImage = New Image (2) With myImage (3) .Width = 56 .Height = 56 .Source = New BitmapImage(New Uri("Images/apple.png", UriKind.Relative)) End With 'appleCanvas.Children.Add(myImage) If myKinect Is Nothing = False Then (4) Dim myDepthDescription = myKinect.DepthFrameSource.FrameDescription (5) myKinect.Open() (6) myBodyFrameReader = myKinect.BodyFrameSource.OpenReader (7) AddHandler myBodyFrameReader.FrameArrived, AddressOf myBodyFrameReader_FrameArrived (8) myBodies = New Body(myKinect.BodyFrameSource.BodyCount - 1) {} (9) myColorFrameReader = myKinect.ColorFrameSource.OpenReader (10) Dim myColorFrameDescription As FrameDescription = myKinect.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra) (11) ColorImagePixelData = New Byte(myColorFrameDescription.Width * myColorFrameDescripton.Height * BytesPerPixel – 1) {} (12) colorBitmap = New WriteableBitmap(myColorFrameDescription.Width, myColorFrameDescripton.Height, 96.0, 96.0, PixelFormats.Bgr32, Nothing) (13) AddHandler myColorFrameReader.FrameArrived, AddressOf myColorFrameReader_FrameArrived (13) End If End Sub
- Kinectを使用可能にします。
- 新しいImageのインスタンスmyImageオブジェクトを作成します。
- WidthとHeightを指定し、SourceプロパティにImagesフォルダー内にある「apple.png」を指定します。
- Kinectセンサーが使用可能な状態にある場合は、以下の処理を行います。
- 距離フレームプロパティの形式を取得し、変数myDepthDescriptionで参照します。
- Kinectを動作させます。
- BodyFrameSource.OpenReaderで、ボディ フレームのソース フレームのリーダーを作成し、変数myBodyFrameReaderで参照します。
- myBodyFrameReader.FrameArrivedで、新しいボディフレームの準備ができているときに発生するイベント処理を実行します。
- ボディフレームソースのボディの個数を引数に持った、新しいBodyの配列をmyBodiesに格納します。
- myKinect.ColorFrameSource.OpenReaderで、カラーフレームのソースフレームのリーダーを作成し、myColorFrameReaderメンバー変数で参照します。
- カラー画像の情報をBGRAフォーマットで作成し、変数myColorFrameDescriptionで参照します。
- 配列変数ColorImagePixelDataを確保します。
- ピクセルデータを格納するビットマップを作成し、変数colorBitmapで参照します。
- myColorFrameReader.FrameArrivedでカラーフレーム到着時のイベントを実行します。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Kinect v2で実現する打楽器のバーチャル演奏
- Kinect v2の音声認識で「仮面」を選んで変身してみる
- Kinect v2のジェスチャーでBing Mapsを未来的に直感操作する
- Kinect v2を使った「じゃんけんゲーム」を作る
- Kinect v2のカメラから画像を取り込んで表示する基本プログラム
- Kinectで手の動きとカーソルを連動して操作するサンプル
- Kinectで人体を認識して棒人間を動かすサンプル
- Kinectで手の動きに合わせてモニタ上の画像を動かすサンプル
- Kinect v2のIRセンサーから赤外線画像を読み込む
- Kinect v2の深度センサーから取り込んだ画像を表示する