«前の日記(2017年03月06日) 最新 次の日記(2017年03月22日)» 編集

日々をアレコレ

-広告-


2017年03月07日

SRGSを使った音声認識の定義をする

音声コマンドでBトレインショーティーを走らせる では、SRGS文法を使って制約を作り、特定の言葉に対する非同期な音声認識するという方法で音声コマンドを実現させている。OSだったり、利用環境だったりで利用できる認識できる言語が決まっているようで、僕が使っている環境だと日本語のWindowsデスクトップやモバイルだと日本語だけが、Raspberry Pi向けのWindows IoT Coreだと英語のみが認識可能っぽい。その辺に気をつけながらまずは、SRGS文法を使った制約を定義したファイルは次のように定義するといいらしい。

<?xml version="1.0" encoding="utf-8" ?>
<grammar
  xmlns="http://www.w3.org/2001/06/grammar"
  version="1.0"
  xml:lang="ja-JP"
  root="commands"
  tag-format="semantics/1.0">
  <rule id="commands">
    <one-of>
      <item>
        <one-of>
          <item>進め</item>
          <item>行け</item>
        </one-of>
        <tag> out.cmd="Forward"; </tag>
      </item>
      <item>
        戻れ <tag> out.cmd="Backward"; </tag>
      </item>
      <item>
        止まれ <tag> out.cmd="Stop"; </tag>
      </item>
    </one-of>
  </rule>
</grammar>
  1. <grammar> タグの中の lang属性は利用する言語に応じて変えること。今回の場合は日本語なので「ja-JP」を指定。
  2. <grammar> タグの中の root属性は認識を開始する制約について指定する。今回は単純なコマンドに使うので、一つだけしか定義してないけど、「玄関/廊下/洗面所/台所」「の」「ライト/換気扇」「を」「点ける/消す」みたいな感じで、複雑なパターンを定義することもできるらしい。 。
  3. <rule> タグを使ってコマンドを定義。

    1. 上の例では、前進、後退、停止の3パターンのコマンドを発行するために、それぞれが該当する要素を<item>タグを3つ定義し、<one-of> タグでまとめることで、いずれかを認識させている。
    2. それぞれの <item> には <tag> で認識した場合に発生するイベントで受け取るためのデータを定義している。今回の場合、cmd要素に、ForwardBackwordStopがデータして渡される。
    3. さらに、前進の要素については、さらに <one-of> タグを使って、「進め」と「行け」を両方同じコマンドとして認識するように定義。

この定義ファイルを \Grammar\Command.xml に保存した場合、音声認識を開始するには次のようなコードを実行すればよい。

var recognizer = new SpeechRecognizer();
recoginizer.ContinuousRecognitionSession.ResultGenerated += (session, args) =>
{
    // 制約を満たした認識をすると、args.Result.SemanticInterpretation.Propertiesは"cmd"をキーとして持つ
    if (!args.Result.SemanticInterpretation.Properties.ContainsKey("cmd")) return;

    // 最初に認識したコマンドを取得
    var command = args.Result.SemanticInterpretation.Properties["cmd"][0];

   // commandに応じた処理を書いていく
};

var grammerFile = await Package.Current.InstalledLocation.GetFileAsync("Grammar\Command.xml");

var grammarConstraint = new SpeechRecognitionGrammarFileConstraint(grammerFile);

recognizer.Constraints.Add(grammarConstraint);

var result = await recognizer.CompileConstraintsAsync();

var isStarted= result.Status == SpeechRecognitionResultStatus.Success;

if (isStarted)
{
    // 非同期な音声認識を開始
    await _recognizer.ContinuousRecognitionSession.StartAsync();
}

本当はもう少しエラー処理やらなんやら書いておく必要があるけど、そのへんはまた別途。


-広告-

«前の日記(2017年03月06日) 最新 次の日記(2017年03月22日)» 編集