2014-02-07 77 views
2

我似乎无法从SpeechRecognizedEventArgs中提取我想要的信息。我的语法有短语“一”和“左箭头”。如果我同时说出两者之间的关系,那么我的识别者会发现他们的语法是因为我的最大重复次数是五次,但是我无法区分结果中的相位。 SpeechRecognizedEventArgstext是“一个向左箭头”,当我想要“一个,左箭头”或列表中的第一个项目是“一个”,第二个是“左箭头”。在SpeechRecognizedEventArgs中为Microsoft语音识别找到单个匹配的短语

我发现了一个“Words”属性,它几乎是我想要的,但并不完全。如果风格使得它们逗号分开,或者某个事件发生在语法中的任何单个阶段被找到,那么我将它们逐一地取代它们,而不是在一个不可分割的组中。我的一些代码:

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); 
    } 
} 

回答

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 
+0

我已经尝试了一些变体,但是当我使用多个短语时它会一直崩溃。我更新了代码。有任何想法吗? –

+0

@PhloxMidas你能用示例和堆栈回溯来更新/开始一个新问题吗? –

+0

@PhloxMidas没有看到你的编辑;更新的答案 –

1

我摆脱了TargetInvokationException,只需添加一个口述语法。

_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" 
    } 
    }; 

结果是:没有更多的崩溃和非常准确和稳定的命令(或在您的情况下,也许单个词?)识别。