参照の追加
参照の追加
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
- この記事のキーワード