Kinect v2の音声認識で「仮面」を選んで変身してみる
2015年1月6日(火)

プログラムコード
次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbにリスト3のコードを記述します。今回もだいぶ長いので、頑張って下さい。
名前空間の読み込みとクラスの作成
リスト3:MainWindow.xaml.vbの一部
Imports Microsoft.Kinect Imports Microsoft.Speech.AudioFormat Imports Microsoft.Speech.Recognition Imports KinectSensor_KinectAudioStream Public Class Mask Public Property 画像名 As String End Class Class MainWindow
名前空間の読み込みについては、第2回目の解説を参照してください。
Maskクラス内で、文字列型の「画像名」というプロパティを定義します。
メンバー変数の宣言
リスト4:MainWindow.xaml.vbの一部、リスト3の続き
Private xmldoc As XElement 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 point As DepthSpacePoint (2) Private SpeechEngine As SpeechRecognitionEngine Const SpeechID As String = "SR_MS_ja-JP_Kinect_11.0" Private myKinectAudioStream As KinectAudioStream Private Index As Integer = 0 Private myImage As Image (3) Private myMask As String (3)
ほとんどが、第2回目と同じですので、異なるメンバー変数の主なものだけ解説しておきます。
- カラー空間における2Dの位置を表す構造体のメンバー変数myColorSpacePointを宣言します。
- 距離空間における2Dの位置を表す構造体のメンバー変数pointを宣言します。
- Image型のメンバー変数、myImageとmyMaskを宣言します。
ウインドウが読み込まれた時の処理
リスト5:MainWindow.xaml.vbの一部、リスト4の続き
Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded xmldoc = XElement.Load("mask.xml") (1) Dim maskList As New List(Of Mask) (2) For Each result In From c In xmldoc.Descendants("画像名") Select c maskList.Add(New Mask With {.画像名 = "Images/" & result.Value}) (3) Next ListBox1.ItemsSource = maskList (4) myKinect = KinectSensor.GetDefault (5) If myKinect Is Nothing = False Then Dim myDepthDescription = myKinect.DepthFrameSource.FrameDescription (6) myKinect.Open() (7) myBodyFrameReader = myKinect.BodyFrameSource.OpenReader (8) AddHandler myBodyFrameReader.FrameArrived, AddressOf myBodyFrameReader_FrameArrived (9) myBodies = New Body(myKinect.BodyFrameSource.BodyCount - 1) {} (10) myColorFrameReader = myKinect.ColorFrameSource.OpenReader (11) Dim myColorFrameDescription As FrameDescription = myKinect.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra) (12) ColorImagePixelData = New Byte(myColorFrameDescription.Width * myColorFrameDescription.Height * BytesPerPixel - 1) {} (13) colorBitmap = New WriteableBitmap(myColorFrameDescription.Width, myColorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, Nothing) (14) AddHandler myColorFrameReader.FrameArrived, AddressOf myColorFrameReader_FrameArrived (15) Dim myAudioBeamList As IReadOnlyList(Of AudioBeam) = myKinect.AudioSource.AudioBeams (16) Dim myAudioStream = myAudioBeamList(0).OpenInputStream (17) myKinectAudioStream = New KinectAudioStream(myAudioStream) (18) End If SpeechEngine = New SpeechRecognitionEngine(SpeechID) (19) Dim myWord As New Choices (20) With myWord .Add("うえ") .Add("した") End With Dim myGrammarBuilder As New GrammarBuilder myGrammarBuilder.Culture = SpeechEngine.RecognizerInfo.Culture myGrammarBuilder.Append(myWord) (21) Dim myGrammar As New Grammar(myGrammarBuilder) (22) SpeechEngine.LoadGrammar(myGrammar) (23) AddHandler SpeechEngine.SpeechRecognized, AddressOf speechEngine_SpeechRecognized (24) myKinectAudioStream.SpeechActive = True (25) SpeechEngine.SetInputToAudioStream(myKinectAudioStream, New SpeechAudioFormatInfo(EncodingFormat.Pcm, 16000, 16, 1, 32000, 2, Nothing)) (26) SpeechEngine.RecognizeAsync(RecognizeMode.Multiple) (27) End Sub
- XElement.Loadメソッドで「Mask.xml」を読み込みます。
- Maskクラス型の新しいリストであるmaskListを作成します。
全ての子孫要素「画像名」用の内容を変数resultに格納しながら、以下の処理を行います。 - maskListオブジェクトに、Maskクラスの「画像名」プロパティに、「画像名」要素の値を、フォルダー名である「Images」を連結して、Addメソッドで追加します。
- ListBox1のItemsSourceプロパティにmaskListオブジェクトを追加します。これで、ListBoxにマスク画像の一覧が表示されます。
- Kinectセンサーを使用可能にします。
Kinectセンサーが使用可能な状態にある場合は、以下の処理を行います。 - 距離フレームプロパティの形式を取得し、変数myDepthDescriptionで参照します。
- Kinectを動作させます。
- BodyFrameSource.OpenReaderで、ボディ フレームのソース フレームのリーダーを作成し、変数myBodyFrameReaderで参照します。
- myBodyFrameReader.FrameArrivedで、新しいボディフレームの準備ができているときに発生するイベント処理を実行します。
- ボディフレームソースのボディの個数を引数に持った、新しいBodyの配列をmyBodiesに格納します。
- myKinect.ColorFrameSource.OpenReaderで、カラー フレームのソース フレームのリーダーを作成し、myColorFrameReaderメンバー変数で参照します。
- カラー画像の情報を作成し、変数myColorFrameDescriptionで参照します。
- 配列変数ColorImagePixelDataを確保します。
- ピクセル データを格納するビットマップを作成し、変数colorBitmapで参照します。
- myColorFrameReader.FrameArrivedでカラーフレーム到着時のイベントを実行します。
- オーディオビームを取得し、配列変数myAudioBeamListに格納します。
- OpenInputStreamで音声入力設定を行い、変数myAudioStreamで参照します。
- myAudioStreamで初期化された新しいKinectAudioStreamのインスタンスである、myKinectAudioStreamオブジェクトを作成します。
- 定数メンバー変数SpeechIDで初期化された、新しいSpeechRecognitionEngineのインスタンス、SpeechEngineオブジェクトを作成します。
- Choicesクラスは、要素を構成するための代替項目の一覧を表すクラスで、GrammarBuilder オブジェクトからのみ直接使用されます。認識させる言葉をAddメソッドで登録します。ここでは「うえ」と「した」の2語を登録しています。
- GrammarBuilderクラスは、単純な入力から複雑な Grammar(構文情報を取得管理するクラス)を構築するためのメカニズムを提供するクラスで、登録された言葉の構文(文法)を設定します。Appendメソッドで、登録した言葉(myWord)を myGrammarBuilder オブジェクトに追加します。
- 文法のチェックされた言葉(myGrammarBuilder)で初期化された、新しいGrammarクラスのインスタンス、myGrammarオブジェクトを作成します。Grammarクラスは、構文情報を取得および管理するためのランタイムをサポートするクラスです。
- SpeechRecognitionEngineクラスのLoadGrammarメソッドで、Grammar によって指定されたとおりに、特定の構文を同期的に読み込みます。
- SpeechEngine.SpeechRecognizedで音声が認識された時に、音声認識処理を行います。
- SpeechActiveプロパティにTrueを指定し、オーディオストリームの変換をアクティブにします。この記述がないと音声が認識されませんので、注意して下さい。
- SetInputToAudioStreamメソッドで認識エンジンに入力設定を行います。
- 複数の音声認識が可能なように、RecognizeMode.Multipleを指定して、RecognizeAsyncメソッドで非同期音声認識を開始します。
連載バックナンバー
Think ITメルマガ会員登録受付中
Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。
全文検索エンジンによるおすすめ記事
- Kinect v2を使って、机の上のリンゴをつかんで移動してみる
- Kinect v2で実現する打楽器のバーチャル演奏
- Kinect v2のカメラから画像を取り込んで表示する基本プログラム
- Kinect v2を使った「じゃんけんゲーム」を作る
- Kinect v2のジェスチャーでBing Mapsを未来的に直感操作する
- Kinect v2のIRセンサーから赤外線画像を読み込む
- Kinect v2の深度センサーから取り込んだ画像を表示する
- Kinectの音声認識を使ってWebブラウザを操作するサンプル
- 声で選んだアイテムをプレイヤーの身体に装着・連動させるKinectサンプル
- KinectButtonを動的に作成して、ジェスチャーで文字を表示させるサンプル