Kinectを使った、音声によるデータ保存と検索のサンプル
参照の追加
VS2010のメニューから「プロジェクト(P)/参照の追加(R)」と選択して、各種コンポーネントを追加しておきます。今回追加するのは、Microsoft.KinectとMicrosoft.Speechの2つです。「.NET」タブ内に表示されていないDLLファイルは「参照」タブからDLLファイルを指定します。
Microsoft.Kinect.dllは、C:\Program Files\Microsoft SDKs\Kinect\v1.5\Assemblies内に存在しますので、これを指定します。
Microsoft.Speech.dllは
C:\Windows\assembly\GAC_MSIL\Microsoft.Speech\11.0.0.0__31bf3856ad364e35\に存在しますので、これを指定してください。このassemblyフォルダ内のGAC_MSILフォルダは「参照の追加(R)」の「参照」タブからでないと参照できません。
マイコンピューターからは、このフォルダは表示されませんので注意してください。
次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックして、リスト3のコードを記述します。
ロジックコードを記述する
リスト3 (MainWindow.xaml.vb)
Option Strict On Imports Microsoft.Kinect Imports System.IO
音声認識を実装するためのクラスが含まれる、Microsoft.Speech.Recognition名前空間をインポートします。
Imports Microsoft.Speech.Recognition
音声認識用のオーディオ形式を表すクラスが含まれる、Microsoft.Speech.AudioFormat名前空間をインポートします。
Imports Microsoft.Speech.AudioFormat
Class MainWindow
一つのKinectセンサーを表すメンバ変数Kinectを宣言します。
Dim Kinect As KinectSensor
XML要素を表すXElementクラス型のメンバ変数xmldocを宣言します。
Dim xmldoc As XElement
音声認識サービスを実行するためのアクセス権を提供するSpeechRecognitionEngineクラス用メンバ変数engineを宣言します。
Dim engine As SpeechRecognitionEngine
ウィンドウが読み込まれた時の処理
Kinectセンサーを開始し、音声認識を開始するDataShowプロシージャを実行します。
Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded DataShow() End Sub
Kinectセンサーを開始し、音声認識を開始する処理
bin\Debugフォルダ内のPersonalInfo.xmlを読み込みます。
Kinectセンサーを開始し、音声認識を開始するcreateSpeechRecognizerプロシージャを実行します。
Private Sub DataShow() xmldoc = XElement.Load("PersonalInfo.xml") If KinectSensor.KinectSensors.Count = 0 Then MessageBox.Show("KINECTが接続されておりません。") Exit Sub Else Kinect = KinectSensor.KinectSensors(0) Kinect.Start() createSpeechRecognizer() End If End Sub
認識させる言葉を登録し、音声認識を開始する処理
音声認識サービスを実行するためのアクセス権を提供する、SpeechRecognitionEngineクラスの新しいインスタンスengineオブジェクトを作成します。
要素を構成するための代替項目の一覧を表すChoicesクラスのインスタンス、sentenceオブジェクトを作成します。Choiceクラスは、GrammarBuilder オブジェクトからのみ直接使用されます。
Descendantsメソッドで、子孫要素であるすべての 要素のコレクションに対して、各要素を変数 result に格納しながら、以下の処理を繰り返します。
要素の値をAddメソッドで、認識させる言葉としてChoicesオブジェクトであるsentenceに追加します。また、Datain、Datasearch、Menu、Save、Continue、Endという語句も追加しておきます。
GrammarBuilderクラスは、単純な入力から複雑な Grammar(構文情報を取得管理するクラス)を構築するためのメカニズムを提供するクラスで、登録された言葉の構文(文法)設定を行い、SpeechRecognitionEngineへと設定します。
Appendメソッドで、登録した言葉を GrammarBuilder オブジェクトとして現在の GrammarBuilder に追加します。
文法のチェックされた言葉(myGrammerBuilder)で初期化された、新しいGrammerクラスのインスタンス、myGrammerオブジェクトを作成します。Grammerクラスは、構文情報を取得および管理するためにランタイムをサポートするクラスです。
SpeechRecognitionEngineクラスのLoadGrammerメソッドで、Grammar によって指定されたとおりに、特定の構文を同期的に読み込みます。
言葉が認識された際には、AddHandlerステートメントで言葉を認識した際に発生するSpeechRecognizedイベントに、イベントハンドラを指定します。
Confidenceプロパティで音声認識の信頼度を設定します。-1が低、0が標準、1が高信頼度となります。-1を指定するとどんな言葉でも反応する恐れがあります。1を指定するとなかなか認識してくれません。今回は信頼度が0.3より大きい場合に、指定した言葉を認識するよう指定しています。
認識された音声(speechArgs.Result.Text)を変数myNameに格納します。myNameの内容で条件分岐を行います。XML文書の要素の子要素の値が、変数myNameの値と同じである、要素を選択するクエリを定義します。結果クエリの個数が0の場合は、「氏名」の入力ボックスに「該当なし」と表示し、処理を抜けます。
定義したクエリ内を変数resultで反復処理しながら、「データ検索画面(この時点では非表示)」の各TextBoxに、該当する要素の内容テキストを表示します。
「Datain」と発声された場合は、メニューと検索画面を非表示にし、「データ入力」画面だけを表示します。
「Datasearch」と発声された場合は、Kinectセンサーを開始し、音声認識を開始するDataShowプロシージャを実行します。要素の個数を取得し、データがない場合は処理を抜けます。データが存在する場合は、各検索結果を表示するTextBoxを空に初期化し、「検索画面」だけを表示します。
「Menu」と発声された時は、「Menu」画面だけを表示します。
「Save」と発声された場合は、「年齢」入力欄に入力された値が数値かどうかを判別して、数値以外であった場合は、「年齢」の入力ボックスにフォーカスを移し、警告メッセージを表示して、処理を抜けます。入力されたデータをXMLに保存するDataSaveプロシージャを実行します。
「Continue」と発声された場合は、メッセージを表示するTextBlock内を空にし、各入力ボックスを空で初期化し、「氏名」の入力ボックスにフォーカスを移します。
「End」と発声された場合は、Kinectセンサーを停止し、音声認識も停止して、Environment.Exit(0)でプログラムを終了します。
Kinectの音声インターフェースは、Kinect.AudioSourceで提供されます。Startメソッドで音声入力を開始します。入力ストリームを取得し、SpeechRecognitionEngine クラスのSetInputToDefaultAudioDeviceメソッドで、SpeechRecognitionEngine の現在のインスタンスに、システム既定のオーディオ入力を割り当てます。
認識操作の後に、RecognizeAsync によって開始された認識を終了しないよう、RecognizeMode.Multipleを指定して、RecognizeAsyncメソッドで非同期音声認識を開始します。
Private Sub createSpeechRecognizer() engine = New SpeechRecognitionEngine() Dim sentence = New Choices() For Each result In From c In xmldoc.Descendants("情報") Select c sentence.Add(result.Element("氏名").Value) Next sentence.Add("Datain") sentence.Add("Datasearch") sentence.Add("Menu") sentence.Add("Save") sentence.Add("Continue") sentence.Add("End") Dim myGrammerBuilder = New GrammarBuilder myGrammerBuilder.Append(sentence) Dim myGrammer = New Grammar(myGrammerBuilder) engine.LoadGrammar(myGrammer) AddHandler engine.SpeechRecognized, Sub(speechSender As Object, speechArgs As SpeechRecognizedEventArgs) Dim confidence As Single = speechArgs.Result.Confidence If confidence > 0.3 Then Dim myName As String = speechArgs.Result.Text Select Case myName Case myName Dim query = From c In xmldoc.Descendants("情報") Where c.Element("氏名").Value.Equals(myName) Select c If query.Count = 0 Then searchNameTextBox.Text = "該当なし" End If For Each result In query searchNameTextBox.Text = result.Element("氏名").Value searchAgeTextBox.Text = result.Element("年齢").Value searchAddressTextBox.Text = result.Element("住所").Value searchCompanyTextBox.Text = result.Element("勤務先").Value Next If myName = "Datain" Then DataIn.Visibility = Windows.Visibility.Visible myStackPanel.Visibility = Windows.Visibility.Collapsed DataSearch.Visibility = Windows.Visibility.Collapsed End If If myName = "Datasearch" Then DataShow() Dim myCountQuery = From c In xmldoc.Descendants("情報") Select c If myCountQuery.Count <= 0 Then Exit Sub Else messageTextBlock.Text = String.Empty searchNameTextBox.Text = String.Empty searchAgeTextBox.Text = String.Empty searchAddressTextBox.Text = String.Empty searchCompanyTextBox.Text = String.Empty myStackPanel.Visibility = Windows.Visibility.Collapsed DataIn.Visibility = Windows.Visibility.Collapsed DataSearch.Visibility = Windows.Visibility.Visible End If End If If myName = "Menu" Then DataIn.Visibility = Windows.Visibility.Collapsed DataSearch.Visibility = Windows.Visibility.Collapsed myStackPanel.Visibility = Windows.Visibility.Visible End If If myName = "Save" Then Try Dim myError As Integer = System.Convert.ToInt16(ageTextBox.Text, 10) Catch ex As Exception ageTextBox.Focus() messageTextBlock.Text = "年齢が不正です。" Exit Sub End Try DataSave() End If If myName = "Continue" Then messageTextBlock.Text = String.Empty nameTextBox.Text = String.Empty ageTextBox.Text = String.Empty addressTextBox.Text = String.Empty companyTextBox.Text = String.Empty nameTextBox.Focus() End If If myName = "End" Then If Kinect.IsRunning = True Then Kinect.Stop() Kinect.AudioSource.Stop() Environment.Exit(0) End If End If Case Else Exit Select End Select End If End Sub Dim audio As KinectAudioSource = Kinect.AudioSource Using s As Stream = audio.Start() engine.SetInputToDefaultAudioDevice() engine.RecognizeAsync(RecognizeMode.Multiple) End Using End Sub
Kinectを使った、音声によるデータ保存と検索のサンプル
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- データを保存し氏名から詳細情報を表示する
- Kinectの音声認識を使ってWebブラウザを操作するサンプル
- センサーの範囲内にいる人間を見つけて撮影・保存するKinectサンプル
- KinectButtonを動的に作成して、ジェスチャーで文字を表示させるサンプル
- Kinectで音声を録音・再生するサンプル
- 入力したデータを分離ストレージに保存し、一覧で表示する
- 時刻とともに、その日の出来事をキャラクターが音声で教えてくれるアプリを作る
- 画面上を流れる数字を暗算して正解を求めるアプリを作ろう(その1)
- キャラクターが音声で応援してくれる脳トレーニングアプリを作ってみよう
- キャラクターが声で天気予報を教えてくれるアプリを作る