Почему система распознавания речи Microsoft соответствует грамматике, хотя ни слова об этой грамматике не сказано?

Я использую C# и System.Speech.Recognition, чтобы загрузить пару простых грамматик, которые я определил. Когда я говорю фразы, соответствующие грамматике, движок распознает грамматику правильно с доверительными отношениями около 0,95.

Но когда я произношу слова, которых нет даже в грамматике (даже из разных языков или тарабарщины), движки случайным образом возвращают совпадение с грамматикой, причем случайный текст никогда не произносится и все еще с высокой достоверностью, например 0,92.

Что-то, что мне нужно установить в объекте SpeechRecognitionEngine или в каждом объекте грамматики, чтобы избежать этой проблемы?

1 ответ

Решение

Я думаю, что нашел решение, которое работает для меня, но все же было бы неплохо найти более элегантное решение, если оно существует:

Я определяю грамматику диктовки и "заполнитель". Затем я загружаю свои грамматики и немедленно их отключаю.

using System.Speech.Recognition;
...

private DictationGrammar dictationGrammar;
private Grammar placeholderGrammar;
private List<Grammar> commands;

public void Initialize()
{
    dictationGrammar = new DictationGrammar();
    recognizer.LoadGrammarAsync(dictationGrammar);

    var builder = new GrammarBuilder();
    builder.Append("MYPLACEHOLDER");        
    placeholderGrammar = new Grammar(builder);
    recognizer.LoadGrammarAsync(placeholderGrammar);

    commands = new List<Grammar>();

    foreach (var grammar in grammarManager.GetGrammars())
    {
        commands.Add(grammar);           
        grammar.Enabled = false;
        recognizer.LoadGrammarAsync(grammar);
    }
}

Затем на событие speechRecognized я добавляю логику, что если распознается местозаполнитель, то включить команды. Если команда распознается, снова включите диктовку и отключите все команды:

private async void speechRecognized(object sender, SpeechRecognizedEventArgs e)
{
    if (e.Result.Grammar == placeholderGrammar)
    {
        //go to command mode
        placeholderGrammar.Enabled = false;
        dictationGrammar.Enabled = false;

        foreach (var item in commands)
            item.Enabled = true;
    }
    else if (commands.Any(x => e.Result.Grammar == x))
    {
        Do_something_with_recognized_command("!!");

        //go back in normal mode
        placeholderGrammar.Enabled = true;
        dictationGrammar.Enabled = true;
    }else {//this is dictation.. nothing to do}
}
Другие вопросы по тегам