Kinect v2のジェスチャーでBing Mapsを未来的に直感操作する
2015年1月14日(水)

Microsoft HTTP Client Librariesのインストール
WPFではデフォルトではHttpClientクラス(System.Net.Http名前空間)が使用できません。そこで、NuGetから必要なライブラリーをインストールします。
「NuGet パッケージの管理」ダイアログの検索欄に「Microsoft HTTP Client」と入力すると、「Microsoft HTTP Client Libraries」が表示されるので、「インストール」をクリックします(図8)。
Microsoft ASP.NET Web API Client Librariesのインストール
これも同様の手順で「Microsoft ASP.NET Web API Client Libraries」を検索し、「Microsoft ASP.NET Web API 2.2 Client Libraries」をインストールします(図9)
プログラムコード
次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xam.vbにリスト2のコードを記述します。
名前空間の読み込みとメンバー変数の宣言
リスト2:MainWindow.xaml.vbの一部
01 | Imports Microsoft.Maps.MapControl.WPF (1) |
02 | Imports System.Net.Http (2) |
03 | Imports Microsoft.Kinect |
04 | Imports System.ComponentModel |
05 | Class MainWindow |
06 | Private myKinect As KinectSensor |
07 | Private myBodyFrameReader As BodyFrameReader |
08 | Private myBodies As Body() |
09 |
10 | Private myHandPositionX As Double |
11 | Private myHandPositionY As Double |
12 | Private myColorSpacePoint As ColorSpacePoint (3) |
13 | Private MyBytesPerPixel As Integer = 4 |
14 |
15 | Private myColorFrameReader As ColorFrameReader = Nothing |
16 | Private colorBitmap As WriteableBitmap = Nothing |
17 | Private ColorImagePixelData As Byte() |
18 | Private BytesPerPixel As Integer = 4 |
19 | Private commonJoint As Joint (4) |
20 | Private point As DepthSpacePoint (5) |
21 | Private Index As Integer = 0 |
22 | Private no As Integer = 0 |
ほとんどが連載の第2回と同じですので、ここでは新しく登場するものを中心に解説しておきます。
- Bing Mapsの各プロパティやメソッドの含まれる、「Microsoft.Maps.MapControl.WPF」名前空間を読み込みます。
- HTTP 属性のクラスが含まれるSystem.Net.Http名前空間を読み込みます。
- カラー空間における2Dの位置を表す構造体のメンバー変数myColorSpacePointを宣言します。
- 身体の関節の位置を表すJoint構造体のメンバー変数、commonJointを宣言します。
- 距離空間における2Dの位置を表す構造体のメンバー変数pointを宣言します。
ウインドウが読み込まれた時の処理
リスト3:MainWindow.xaml.vbの一部(リスト2の続き)
01 | Private Async Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded |
02 | Dim client As New HttpClient (1) |
03 | Dim myPin As New Pushpin (2) |
04 | Dim myAddress As String = "愛媛県松山市道後" (3) |
05 | Dim addressUri = String.Format("http://www.geocoding.jp/api/?v=1.1&q={0}", myAddress) (4) |
06 | Dim myResponse = Await client.GetStringAsync(New Uri(addressUri, UriKind.Absolute)) (5) |
07 | Dim doc = XElement.Parse(myResponse) (6) |
08 | Dim myAddressLatitude = doc.Descendants("coordinate").Elements("lat").Value (7) |
09 | Dim myAddressLongitude = doc.Descendants("coordinate").Elements("lng").Value |
10 | Dim myLabel As New Label (8) |
11 | With myLabel |
12 | .Content = myAddress |
13 | .Foreground = New SolidColorBrush(Colors.Navy) (9) |
14 | .Background = New SolidColorBrush(Colors.Beige) |
15 | .FontSize = 20 |
16 | End With |
17 |
18 | Dim myLocation As New Location (10) |
19 | myLocation.Latitude = myAddressLatitude (11) |
20 | myLocation.Longitude = myAddressLongitude |
21 | myPin.Location = New Location(myAddressLatitude, myAddressLongitude) (12) |
22 | MapLayer.SetPosition(myLabel, myLocation) (13) |
23 |
24 | myMap.SetView(myLocation, 16) (14) |
25 | myMap.Children.Add(myPin) (15) |
26 | myMap.Children.Add(myLabel) |
27 |
28 | myKinect = KinectSensor.GetDefault (16) |
29 | If myKinect Is Nothing = False Then (17) |
30 | Dim myDepthDescription = myKinect.DepthFrameSource.FrameDescription (18) |
31 | myKinect.Open() (19) |
32 | myBodyFrameReader = myKinect.BodyFrameSource.OpenReader (20) |
33 | AddHandler myBodyFrameReader.FrameArrived, AddressOf myBodyFrameReader_FrameArrived (21) |
34 | myBodies = New Body(myKinect.BodyFrameSource.BodyCount - 1) {} (22) |
35 | myColorFrameReader = myKinect.ColorFrameSource.OpenReader (23) |
36 | Dim myColorFrameDescription As FrameDescription = myKinect.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra) (24) |
37 | ColorImagePixelData = New Byte(myColorFrameDescription.Width * myColorFrameDescription.Height * BytesPerPixel - 1) {} (25) |
38 | colorBitmap = New WriteableBitmap(myColorFrameDescription.Width, myColorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, Nothing) (26) |
39 | End If |
40 | End Sub |
- HttpClientのインスタンスclientオブジェクトを作成します。
- PushPinクラスのインスタンスmyPinオブジェクトを作成します。
- 変数myAddressに「愛媛県松山市道後」と指定します。
- 変数addressUriにGeocodingのWeb APIを使用して、住所を指定してリクエストを作成します。
詳細については、Geocoding Web APIのサイトを参照してください。 - 指定したURIにGET要求を送信し、非同期操作で応答本体を文字列として返すGetStringAsyncメソッドに変数myAddressを指定し、返される結果XMLを変数myResponseに格納します。
- XElement.Parseメソッドで返されたmyResponseの内容を、文字列として読み込みます。
- 読み込んだXMLから、coordinate要素のlatの値を変数myAddressLatitudeに、lngの値を変数myAddressLongitudeに格納します。
- 新しいLabelのインスタンスmyLabelオブジェクトを作成します。
- ContentプロパティにmyAddress変数の値を指定し、文字色にNavy、背景色にBeige、文字サイズに20を指定します。
- 新しいLocationのインスタンスmyLocationオブジェクトを作成します。
- LatitudeとLongitudeの両プロパティに、それぞれ変数myAddressLatitude、myAddressLongitudeの値を指定します。
- PushPinの位置を変数myAddressLatitudeとmyAddressLongitudeの位置に指定します。
- MapLayerクラスのSetPositionメソッドで、マップレイヤー内にLabelの位置を設定します。
- SetViewメソッドで、指定された中心部に位置、ズーム レベル、方位、およびピッチにマップビューを設定します。この場合myLocationの位置に「16」レベルでズームインします。
- myMapにAddメソッドでピンとLabelを追加します。
- Kinectセンサーを使用可能にします。
- Kinectセンサーが使用可能な状態にある場合は、以下の処理を行います。
- 距離フレームプロパティの形式を取得し、変数myDepthDescriptionで参照します。
- Kinectを動作させます。
- BodyFrameSource.OpenReaderで、ボディ フレームのソース フレームのリーダーを作成し、変数myBodyFrameReaderで参照します。
- myBodyFrameReader.FrameArrivedで、新しいボディフレームの準備ができているときに発生するイベント処理を実行します。
- ボディフレームソースのボディの個数を引数に持った、新しいBodyの配列をmyBodiesに格納します。
- myKinect.ColorFrameSource.OpenReaderで、カラー フレームのソース フレームのリーダーを作成し、myColorFrameReaderメンバー変数で参照します。
- カラー画像の情報をBGRAフォーマットで作成し、変数myColorFrameDescriptionで参照します。
- 配列変数ColorImagePixelDataを確保します。
- ピクセル データを格納するビットマップを作成し、変数colorBitmapで参照します。
連載バックナンバー
Think ITメルマガ会員登録受付中
Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。