Как смешивать грамматику (правила) и диктовку (свободную речь) с SpeechRecognizer в С#

Мне очень нравятся предложения по распознаванию речи в Microsoft (и SpeechSynthesis).

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

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

Однако, я чувствую, что при использовании грамматик я несколько ограничен.

Не поймите меня неправильно, грамматики отлично подходят для того, чтобы говорить о распознавании речи точно, какие слова/фразы нужно искать, однако что, если я хочу, чтобы он узнал что-то, о чем я не сказал? Или я хочу разобрать фразу, которая представляет собой половину предварительно определенного имени команды и половины случайных слов?

Например..

Сценарий A. Я говорю "Google [Oil Spill]", и я хочу, чтобы он открыл Google с результатами поиска для термина в скобках, который может быть любым.

Сценарий B. Я говорю "Найдите [Манчестер]", и я хочу, чтобы он искал Манчестер в Картах Google или что-то еще, что не было предопределено

Я хочу, чтобы он знал, что "Google" и "Найти" являются командами, и что происходит после того, как они являются параметрами (и могут быть любыми).

Вопрос: Кто-нибудь знает, как смешивать использование заранее определенных грамматик (слова распознавания речи должны распознаваться) и слова не в его заранее определенной грамматике?

Кодовые фрагменты..

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

Ответ 1

У вас есть два варианта:

  • Вы можете использовать диктовку node для свободного текста, используя GrammarBuilder:: AppendDictation. Проблема в том, что, поскольку у распознавателя нет никакого контекста, распознавания не являются самым высоким качеством.
  • Вы можете использовать textbuffer node и предоставить набор элементов, используя GrammarBuilder:: Append (String, SubsetMatchingMode). Это даст распознавателю достаточный контекст для получения качественных признаний без необходимости перестраивать все дерево грамматики каждый раз.

Ответ 2

Вы можете попробовать что-то вроде этого... Он определяет список известных команд.. но также позволяет использовать открытую диктовку впоследствии. Он ожидает, что будет приведена команда перед открытой диктовкой.. но вы можете отменить это... и добавить Однако, добавив пробел в тип команды (""), он также позволит вам перейти прямо к части диктовки.

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();).