在SpeechRecognizedEventArgs中查找用于Microsoft语音识别的单个匹配短语

时间:2014-02-07 14:08:26

标签: speech-recognition speech sapi

我似乎无法从SpeechRecognizedEventArgs中提取我想要的信息。我的语法有短语“一”和“左箭头”。如果我说两个,一个接一个,我的识别者在语法中发现它们是因为我有一个Max重复五,但我无法区分结果中的阶段。当我想要“一个左箭头”或第一个项目是“一”而第二个是“左箭头”的列表时,SpeechRecognizedEventArgstext是“一个左箭头”。

我找到了一个“单词”属性,这几乎是我想要但不完全的。如果找到逗号分隔的方式的样式,或者找到语法中任何单个阶段的某个事件,那么我将逐个获取它们而不是在不可分离的组中。我的一些代码:

    var cultureInfo = new System.Globalization.CultureInfo("en-US");
    recognizer_ = new SpeechRecognitionEngine(cultureInfo);
    var choices = LoadWordChoices();
    var gb = new GrammarBuilder();
    gb.Append(choices, 1, 5);
    var grammar = new Grammar(gb);
    recognizer_.LoadGrammar(grammar);
    recognizer_.SpeechRecognized +=
        new EventHandler<SpeechRecognizedEventArgs>(recognizer_SpeechRecognized);

事件:

    void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
    {
        // e.g. "one left arrow"
        // when I'd like either "one,left arrow" or a list
        Console.WriteLine(e.Result.Text); 
        // ...
    }

编辑 - 当我说出一个短语时尝试使用语义工作,例如“左箭头”,但当我说“一个左箭头”时,它崩溃并出现以下错误:“mscorlib.dll中发生了'System.Reflection.TargetInvocationException'类型的未处理异常。附加信息:异常已被抛出调用的目标。“这是我的尝试:

        var gb = new GrammarBuilder();
        var choices = new Choices();
        var words = LoadWords(); // string[] of "one", "left arrow" etc.
        foreach (var word in words)
        {
            choices.Add(new SemanticResultValue(word, word));
        }
        gb.Append(choices, 1, 5);
        return gb;

编辑2:包括重现错误的最小工作程序:

class MySpeech
{
    private SpeechRecognitionEngine recognizer_;

    public MySpeech()
    {
        var cultureInfo = new System.Globalization.CultureInfo("en-US");
        recognizer_ = new SpeechRecognitionEngine(cultureInfo);
        var gb = CreateGrammarBuilder();
        var grammar = new Grammar(gb);
        recognizer_.LoadGrammar(grammar);

        recognizer_.SpeechRecognized +=
            new EventHandler<SpeechRecognizedEventArgs>(recognizer_SpeechRecognized);
        recognizer_.SetInputToDefaultAudioDevice();
        recognizer_.RecognizeAsync(RecognizeMode.Multiple);
    }

    private GrammarBuilder CreateGrammarBuilder()
    {
        var gb = new GrammarBuilder();
        var choices = new Choices();
        var words = new string[] { "one", "left arrow" };
        foreach (var word in words)
        {
            choices.Add(new SemanticResultValue(word, word));
        }
        var gbChoices = new GrammarBuilder(choices);
        var key = new SemanticResultKey("press", gbChoices);
        gb.Append(key, 1, 5);
        return gb;
    }

    void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
    {
        Console.WriteLine("Recognized: " + e.Result.Text);
    }
}

2 个答案:

答案 0 :(得分:4)

您希望在语法中使用SemanticResultKeySemanticResultValue个对象,然后您可以使用e.Result.Semantics来提取各种结果。

SemanticValue是字典,值也可以是SemanticValues,从而生成值树。

请注意,SemanticResultValues必须与SemanticResultKeys相关联。

    var gb = new GrammarBuilder();
    var choices = new Choices();
    var words = LoadWords(); // string[] of "one", "left arrow" etc.
    foreach (var word in words)
    {
        choices.Add(new SemanticResultValue(word, word));
    }
    var gbchoices = new GrammarBuilder(choices);
    var key = new SemanticResultKey("words", gbchoices);

    gb.Append(key, 1, 5);  // use implicit conversion from SemanticResultKey to GrammarBuilder

答案 1 :(得分:1)

我摆脱了TargetInvokationException,只需添加一个dictationgrammar。

_speech.LoadGrammar(new Grammar(new Choices(commands)) { Name = "commands" });
_speech.LoadGrammar(new DictationGrammar() { Name = "_background" });

在SpeechRecognized事件中,您可以检查结果是否来自命令字典。

SpeechRecognized += (object sender, SpeechRecognizedEventArgs e) =>
  {
    if (e.Result.Grammar.Name == "commands")
    {
      // command recognized
    }
    else
    {
      // "background noise"
    }
  };

结果是:没有更多的崩溃和非常准确和稳定的命令(或者在你的情况下可能是单个词?)的认可。