Выдайте команды отличия от обычной речи с SAPI - PullRequest
1 голос
/ 31 октября 2011

Я работаю над личным проектом с использованием микрофонов в моей квартире, которому я могу давать устные команды. Для этого я использовал Microsoft Speech API и, в частности, RecognitionEngine из System.Speech.Recognition в C #. Я строю грамматику следующим образом:

// validCommands is a Choices object containing all valid command strings
// recognizer is a RecognitionEngine
GrammarBuilder builder = new GrammarBuilder(recognitionSystemName);
builder.Append(validCommands);
recognizer.SetInputToDefaultAudioDevice();
recognizer.LoadGrammar(new Grammar(builder));
recognizer.RecognizeAsync(RecognizeMode.Multiple);

// etc ...

Кажется, это работает очень хорошо для случая, когда я фактически даю ему команду. Ни одна из моих команд еще не опознана. К сожалению, это также приводит к случайным разговорам в качестве команд! Я попытался улучшить это, предварительно указав команду Choices объект с «именем» ( распознаваниеSystemName ), к которому я обращаюсь в системе. Как ни странно, это не помогает. Я ограничиваю его набором заранее определенных командных фраз, поэтому я бы подумал, что он сможет обнаружить, если речь не является какой-либо из строк. Мое лучшее предположение состоит в том, что предполагается, что весь звук является командой, и выбирает наилучшее совпадение из набора команд. Любой совет по улучшению этой системы, чтобы она больше не вызывала разговоров, не направленных на нее, был бы очень полезен.

Редактировать: Я переместил распознаватель имен в отдельный SpeechRecognitionEngine, но точность ужасна. Вот небольшой код теста, который я написал для проверки точности:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Speech.Recognition;

namespace RecognitionAccuracyTest
{
    class RecognitionAccuracyTest
    {
        static int recogcount;
        [STAThread]
        static void Main()
        {
            recogcount = 0;
            System.Console.WriteLine("Beginning speech recognition accuracy test.");

            SpeechRecognitionEngine recognizer;
            recognizer = new SpeechRecognitionEngine(new System.Globalization.CultureInfo("en-US"));
            recognizer.SetInputToDefaultAudioDevice();
            recognizer.LoadGrammar(new Grammar(new GrammarBuilder("Octavian")));
            recognizer.SpeechHypothesized += new EventHandler<SpeechHypothesizedEventArgs>(recognizer_SpeechHypothesized);
            recognizer.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(recognizer_SpeechRecognized);
            recognizer.RecognizeAsync(RecognizeMode.Multiple);

            while (true) ;
        }

        static void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            System.Console.WriteLine("Recognized @ " + e.Result.Confidence);
            try
            {
                if (e.Result.Audio != null)
                {
                    System.IO.FileStream stream = new System.IO.FileStream("audio" + ++recogcount + ".wav", System.IO.FileMode.Create);
                    e.Result.Audio.WriteToWaveStream(stream);
                    stream.Close();
                }
            }
            catch (Exception) { }
        }

        static void recognizer_SpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
        {
            System.Console.WriteLine("Hypothesized @ " + e.Result.Confidence);
        }
    }
}

Если имя «Октавиан», оно распознает такие вещи, как «Осьминог», «Октагон», «Фольксваген» и «Вау, правда?». Я четко слышу разницу в связанных аудиоклипах. Любые идеи о том, как сделать это не ужасным, были бы великолепны.

Ответы [ 4 ]

2 голосов
/ 01 ноября 2011

Позвольте мне убедиться, что я понимаю, вы хотите, чтобы фраза для разделения команд системы, типа "дворецкий" или "Сири".Итак, вы скажете: «Батлер, включи телевизор».Вы можете встроить это в свою грамматику.

Вот пример простой грамматики, которая требует вводной фразы, прежде чем она распознает команду.Он использует семантические результаты, чтобы помочь вам понять, что было сказано.В этом случае пользователь должен сказать «Открыть» или «Пожалуйста, откройте» или «Можете ли вы открыть»

    private Grammar CreateTestGrammar()
    {
        // item
        Choices item = new Choices();
        SemanticResultValue itemSRV;
        itemSRV = new SemanticResultValue("I E", "explorer");
        item.Add(itemSRV);
        itemSRV = new SemanticResultValue("explorer", "explorer");
        item.Add(itemSRV);
        itemSRV = new SemanticResultValue("firefox", "firefox");
        item.Add(itemSRV);
        itemSRV = new SemanticResultValue("mozilla", "firefox");
        item.Add(itemSRV);
        itemSRV = new SemanticResultValue("chrome", "chrome");
        item.Add(itemSRV);
        itemSRV = new SemanticResultValue("google chrome", "chrome");
        item.Add(itemSRV);
        SemanticResultKey itemSemKey = new SemanticResultKey("item", item);

        //build the permutations of choices...
        GrammarBuilder gb = new GrammarBuilder();
        gb.Append(itemSemKey);


        //now build the complete pattern...
        GrammarBuilder itemRequest = new GrammarBuilder();
        //pre-amble "[I'd like] a"
        itemRequest.Append(new Choices("Can you open", "Open", "Please open"));

        itemRequest.Append(gb);

        Grammar TestGrammar = new Grammar(itemRequest);
        return TestGrammar;
    }

Затем вы можете обработать речь следующим образом:проверить на семантические результаты, такие как:

if(result.Semantics.ContainsKey("item"))
{
   string s = (string)result.Semantics["item"].Value;
}
1 голос
/ 03 ноября 2011

У меня тоже такая же проблема. Я использую Microsoft Speech Platform, поэтому она может немного отличаться по точности и т. Д.

Я использую Клэр как команду для пробуждения, но это правда, что она распознает и другие слова как Клэр. Проблема в том, что двигатель слышит ваши слова и ищет наиболее близкое совпадение.

Я не нашел действительно хорошего решения для этого. Вы можете попробовать отфильтровать распознанную речь в поле «Доверие». Но это не очень надежно с моим выбранным двигателем распознавателя. Я просто выбрасываю каждое слово, которое хочу распознать, в один большой файл SRGS.xml и устанавливаю значение повтора равным 0-. Я принимаю только признанное предложение, поскольку Клэр - первое слово. Но это решение не то, что я хочу, поскольку оно работает не так хорошо, как хотелось бы, но все же это небольшое улучшение.

В настоящее время я занят этим, и я буду публиковать больше информации по мере продвижения.

РЕДАКТИРОВАТЬ 1: Как комментарий к тому, что говорит Димс: В грамматике SRGS можно добавить правило «Мусора». Возможно, вы захотите разобраться в этом. http://www.w3.org/TR/speech-grammar/

0 голосов
/ 02 марта 2012

Возможно ли, что вам нужно просто запустить UnloadAllGrammars () перед созданием / загрузкой грамматики, которую вы хотите использовать?

0 голосов
/ 31 октября 2011

В принципе, вам нужно обновить либо грамматику, либо словарь, чтобы в них были "пустые" или "все" записи.

...