Как смешивать грамматику (правила) и диктовку (свободную речь) с 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();).