如何混合语法(规则)&使用C#中的SpeechRecognizer进行听写(言论自由)

时间:2010-06-15 16:07:48

标签: c# speech-recognition sapi voice-recognition

我非常喜欢微软最新的语音识别(和SpeechSynthesis)产品。

http://msdn.microsoft.com/en-us/library/ms554855.aspx

http://estellasays.blogspot.com/2009/04/speech-recognition-in-cnet.html

但是我觉得在使用语法时我有点受限。

不要误会我的语法,语法识别确切地指出了要注意的单词/短语,但是如果我想要它能够识别出一些我没有理解的东西呢?或者我想解析一个半预定命令名和一半随机字的短语?

例如......

情景A - 我说“谷歌[漏油事件]”,我希望它能用括号中的搜索结果打开Goog​​le,这可能是任何内容。

情景B - 我说“找到[曼彻斯特]”,我想让它在谷歌地图或其他任何未预先确定的地方搜索曼彻斯特

我希望它知道'谷歌'和'定位'是命令,它是参数后面的东西(可能是任何东西)。

问题:有没有人知道如何混合使用预先确定的语法(语音识别应该识别的单词)和不在预定语法中的单词?

代码片段..

using System.Speech.Recognition;

...
...

SpeechRecognizer rec = new SpeechRecognizer();
rec.SpeechRecognized += rec_SpeechRecognized;

var c = new Choices();
c.Add("search");

var gb = new GrammarBuilder(c);
var g = new Grammar(gb);
rec.LoadGrammar(g);
rec.Enabled = true; 

...
...

void rec_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
    if (e.Result.Text == "search")
    {
        string query = "How can I get a word not defined in Grammar recognised and passed into here!";

        launchGoogle(query);
    }
}

...
...


private void launchGoogle(string term)
{
    Process.Start("IEXPLORE", "google.com?q=" + term);
}

2 个答案:

答案 0 :(得分:5)

你可以试试这样的...... 它指定了已知命令的列表..但也允许您在之后使用打开的口述。 它期望在开放式听写之前有一个命令..但你可以扭转这个......然后追加 但是,通过在命令类型(“”)中添加空格,它还可以让您直接进入听写部分。

Choices commandtype = new Choices();
commandtype.Add("search");
commandtype.Add("print");
commandtype.Add("open");
commandtype.Add("locate");

SemanticResultKey srkComtype = new SemanticResultKey("comtype",commandtype.ToGrammarBuilder());

 GrammarBuilder gb = new GrammarBuilder();
 gb.Culture = System.Globalization.CultureInfo.CreateSpecificCulture("en-GB");
 gb.Append(srkComtype);
 gb.AppendDictation();

 Grammar gr = new Grammar(gb);

然后在识别器上使用结果文本等

private void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
    System.Console.WriteLine(e.Result.Text);

}

如果您愿意,可以向结构添加更多选项和SemanticResultKeys以制作更复杂的模式。也是一个通配符(例如gb.AppendWildcard();)。

答案 1 :(得分:4)

您有两种选择:

  1. 您可以使用GrammarBuilder::AppendDictation将听写节点用于自由文本。问题在于,由于识别器没有任何上下文,因此识别不是最高质量的。
  2. 您可以使用textbuffer节点并使用GrammarBuilder::Append(String, SubsetMatchingMode)提供一组项目。这将为识别器提供足够的上下文,以获得高质量的识别,而无需每次都重建整个语法树。