1

我正在做一个涉及我公寓里的麦克风的个人项目,我可以向它发出口头命令。为此,我一直在使用 Microsoft Speech API,特别是 C# 中 System.Speech.Recognition 中的 RecognitionEngine。我构造一个语法如下:

// 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 ...

当我实际给它一个命令时,这似乎工作得很好。它还没有误认我的命令之一。不幸的是,它也倾向于将随机谈话作为命令!我试图通过在命令选项对象前面加上一个“名称”(recognitionSystemName)来改善这一点,我将系统称为。奇怪的是,这似乎没有帮助。我将它限制为一组预定的命令短语,所以我认为它能够检测到语音是否不是任何字符串。我最好的猜测是它假设所有声音都是命令并从命令集中选择最佳匹配。任何有关改进此系统以使其不再触发非针对它的对话的建议都会非常有帮助。

编辑:我已将名称识别器移至单独的 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);
        }
    }
}

如果名称是“Octavian”,它会识别“Octopus”、“Octagon”、“Volkswagen”和“哇,真的吗?”之类的东西。我可以清楚地听到相关音频剪辑的差异。任何使这不可怕的想法都会很棒。

4

4 回答 4

2

让我确保我明白,你想要一个短语来区分系统的命令,比如“管家”或“Siri”。所以,你会说“巴特勒,打开电视”。您可以将其构建到您的语法中。

这是一个简单语法的示例,它在识别命令之前需要一个开头短语。它使用语义结果来帮助您理解所说的内容。在这种情况下,用户必须说“打开”或“请打开”或“你能打开”

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

然后,您可以使用以下内容处理语音:

RecognitionResult result = myRecognizer.Recognize();

并检查语义结果,例如:

if(result.Semantics.ContainsKey("item"))
{
   string s = (string)result.Semantics["item"].Value;
}
于 2011-11-01T13:07:56.443 回答
1

我也有同样的问题。我使用的是 Microsoft Speech Platform,因此在准确性等方面可能会有所不同。

我使用 Claire 作为唤醒命令,但它确实也将不同的单词识别为 Claire。问题是引擎会听到您说话并搜索最接近的匹配项。

我没有找到一个很好的解决方案。您可以尝试使用 Confidence 字段过滤已识别的语音。但是我选择的识别器引擎不是很可靠。我只是将我想识别的每个单词都放在一个大的 SRGS.xml 中,并将重复值设置为 0-。我只接受公认的句子,因为 Claire 是第一个词。但是这个解决方案不是我想要的,因为它没有我希望的那么好,但它仍然有一点改进。

我目前正忙于它,随着我的进展,我会发布更多信息。

编辑 1:作为对 Dims 所说的评论:可以在 SRGS 语法中添加“垃圾”规则。你可能想调查一下。 http://www.w3.org/TR/speech-grammar/

于 2011-11-03T08:43:13.237 回答
0

原则上,您需要更新语法或字典以在其中包含“空”或“任何”条目。

于 2011-10-31T17:31:22.800 回答
0

您是否可能只需要在创建/加载要使用的语法之前运行 UnloadAllGrammars() ?

于 2012-03-02T16:11:27.493 回答