Kinectの音声認識を使ってWebブラウザを操作するサンプル

2012年7月12日(木)
薬師寺 国安

次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト5のコードを記述します。

ロジックコードを記述する

リスト5 (MainWindow.xaml.vb)

Option Strict On

Imports Microsoft.Kinect
Imports Coding4Fun.Kinect.Wpf

音声認識用のオーディオ形式を表すクラスが含まれる、Microsoft.Speech.AudioFormat名前空間をインポートします。

Imports Microsoft.Speech.AudioFormat

音声認識を実装するためのクラスが含まれる、Microsoft.Speech.Recognition名前空間をインポートします。

Imports Microsoft.Speech.Recognition

Imports System.IO

Class MainWindow
  Dim myKinect As KinectSensor

XMLの要素を表すXElementクラス用オブジェクト変数xmldocを宣言します。

  Dim xmldoc As XElement
 
  Dim index As Integer

音声認識サービスを実行するためのアクセス権を提供するSpeechRecognitionEngineクラス用メンバ変数engineを宣言します。

  Dim engine As SpeechRecognitionEngine
 
  Dim words As String

ウィンドウが読み込まれた時の処理

XElement.LoadメソッドでXML文書ファイル(URL.xml)を読み込みます。

要素を構成するための代替項目の一覧を表すChoicesクラスのインスタンス、sentenceオブジェクトを作成します。Descendantsメソッドで、子孫要素であるすべての 要素のコレクションに対して、各要素を変数 result に格納しながら、以下の処理を繰り返します。

name要素の属性”tolower”の値をAddメソッドで、認識させる言葉としてChoicesオブジェクトであるsentenceに追加します。新しいTextBlockのインスタンスmyTextBlockオブジェクトを作成します。文字サイズ、文字の太さを指定し、Textプロパティに属性”tolower”の値を指定します。これらのプロパティの設定されたTextBlockをStackPanelに追加します。これで、StackPanel内にサイト名が表示されます。

認識される言葉として、サイト名の他に、Back、Next、Endを追加しておきます。

Kinectが接続されている場合はKinectを作動させます。

GrammarBuilderクラスは、単純な入力から複雑な Grammar(構文情報を取得管理するクラス)を構築するためのメカニズムを提供するクラスで、登録された言葉(builder)の構文設定を行い、SpeechRecognitionEngineへと設定します。詳細な解説に付いては、「音声認識」の解説を参照してください。

言葉が認識された際には、AddHandlerステートメントで言葉を認識した際に発生するSpeechRecognizedイベントに、イベントハンドラを指定します。Confidenceプロパティで音声認識の信頼度を設定します。-1が低、0が標準、1が高信頼度となります。-1を指定するとどんな言葉でも反応する恐れがあります。1を指定するとなかなか認識してくれません。今回は信頼度が0.5より大きい場合に、指定したサイトに遷移するよう指定しています。

認識された音声(speechArgs.Result.Text)を変数wordsに格納します。wordsの内容で条件分岐を行います。XML文書のname要素の属性”tolower”の値がwordsの値と同じならname 要素の内容テキストのURLに遷移します。wordsの値がEndの場合はEnvironment.Exit(0)でプログラムを終了します。Backの場合は後のページに戻り、Nextの場合は次のページを表示します。

Kinectの音声インターフェースは、Kinect.AudioSourceで提供されます。Startメソッドで音声入力を開始します。入力ストリームを取得し、SpeechRecognitionEngine クラスのSetInputToDefaultAudioDeviceメソッドで、SpeechRecognitionEngine の現在のインスタンスに、システム既定のオーディオ入力を割り当てます。

複数の音声認識が可能なように、RecognizeMode.Multipleを指定して、RecognizeAsyncメソッドで非同期音声認識を開始します。

ColorStream.EnableメソッドでRGBカメラの動作を開始し、AddHandlerステートメントで、RGBカメラのフレーム更新イベントを追加します。

  Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    xmldoc = XElement.Load("URL.xml")
    Dim sentence As Choices = New Choices
 
    For Each result In From c In xmldoc.Descendants("name") Select c
      If result.Value <> String.Empty Then
        sentence.Add(result.Attribute("tolower").Value)
        Dim myTextBlock As New TextBlock
        myTextBlock.FontSize = 20
        myTextBlock.FontWeight = FontWeights.Bold
        myTextBlock.Text = result.Attribute("tolower").Value
        stackPanel1.Children.Add(myTextBlock)
      End If
    Next
 
    With sentence
      .Add("Back")
      .Add("Next")
      .Add("End")
    End With
 
    If KinectSensor.KinectSensors.Count > 0 Then
      myKinect = KinectSensor.KinectSensors(0)
      myKinect.Start()
    End If
 
    Dim builder As GrammarBuilder = New GrammarBuilder
      builder.Append(sentence)
      Dim myGrammer As Grammar = New Grammar(builder)
      engine = New SpeechRecognitionEngine
      engine.LoadGrammar(myGrammer)
 
      AddHandler engine.SpeechRecognized, Sub(speechSender As Object, speechArgs As SpeechRecognizedEventArgs)
                 Dim confidence As Single = speechArgs.Result.Confidence
                 If confidence > 0.5 Then
                   words = speechArgs.Result.Text
                   Select Case words
                     Case words
                       Dim query = From c In xmldoc.Descendants("name") Where c.Attribute("tolower").Value.Equals(words) Select c
                       For Each result In query
                         webBrowser1.Navigate(New Uri(result.Value, UriKind.Absolute))
                       Next
 
                     If words = "End" Then
                       If myKinect.IsRunning = True Then
                         myKinect.Stop()
                         myKinect.AudioSource.Stop()
                       End If
                       Environment.Exit(0)
                     End If
 
                     If words = "Back" Then
                       If webBrowser1.CanGoBack = True Then
                         webBrowser1.GoBack()
                       End If
                     End If
 
                     If words = "Next" Then
                       If webBrowser1.CanGoForward = True Then
                         webBrowser1.GoForward()
                       End If
                     End If
                 Case Else
                   Exit Select
               End Select
             End If
                 End Sub
 
    Dim audio As KinectAudioSource = myKinect.AudioSource
    Using s As Stream = audio.Start()
          engine.SetInputToDefaultAudioDevice()
          engine.RecognizeAsync(RecognizeMode.Multiple)
    End Using
 
    Try
           myKinect.ColorStream.Enable()
           AddHandler myKinect.ColorFrameReady, AddressOf myKinect_ColorFrameReady
    Catch ex As Exception
        MessageBox.Show(ex.Message)
        Close()
    End Try 
  End Sub

RGBカメラのフレームが更新されたことを通知するイベント

sourceImageという名前を持つImageコントロールのSourceプロパティに、e.OpenColorImageFrameメソッドで、新しいフレームのRGBカメラの情報を取得し、Coding4Fun.Kinect.Wpfの拡張メソッドであるToBitmapSourceで、myColorImageをBitmapSourceに変換して指定します。これで、Imageコントロール内にカラーの実画像(実写)が表示されます。このメソッドで取得するColorImageFrameは、Usingで括るか、明示的にDisposeする必要があります。

  Private Sub myKinect_ColorFrameReady(sender As Object, e As ColorImageFrameReadyEventArgs)
    Using myColorImage As ColorImageFrame = e.OpenColorImageFrame
      sourceImage.Source = myColorImage.ToBitmapSource
    End Using
  End Sub

ウィンドウが閉じられる時に発生するイベント

Kinectセンサーが動作している時は、RGBカメラのフレーム更新イベントを破棄し、StopメソッドでKinectセンサーを停止し、音声認識も停止します。最後にDisposeメソッドでリソースを解放します。

  Private Sub MainWindow_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles Me.Closing
    If myKinect Is Nothing = False Then
      If myKinect.IsRunning = True Then
        RemoveHandler myKinect.ColorFrameReady, AddressOf myKinect_ColorFrameReady
        myKinect.Stop()
        engine.RecognizeAsyncStop()
        myKinect.Dispose()
      End If
    End If 
  End Sub
End Class

今回のサンプルは以上で終了です。PCに話しかけるのは慣れないと少々恥ずかしいですが、最近はスマートフォンなども音声認識が流行っていますし、自分しかいない場合でしたら恥ずかしさもないと思うので、ぜひ試してみてください。

それでは、次回もお楽しみに。

  • Kinectに音声認識させるサンプルプログラム

  • Kinectの音声認識を使ってWebブラウザを操作するサンプル

薬師寺国安事務所

薬師寺国安事務所代表。Visual Basic プログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。1997年に薬師寺聖とコラボレーション・ユニット PROJECT KySS を結成。2003年よりフリーになり、PROJECT KySS の活動に本格的に参加、.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。Windows Phoneアプリ開発を経て、現在はWindows ストア アプリを多数公開中

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています