我正在制作一个涉及我公寓麦克风的个人项目,我可以发出口头命令 . 为实现这一目标,我一直在使用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 ...
对于我实际上给它命令的情况,这似乎工作得很好 . 它没有试图通过使用"name"(recognitionSystemName)命令Choices对象来改善这种情况,我将系统称为 . 奇怪的是,这并没有任何字符串 . 我最好的猜测是假设所有声音都是命令并从命令集中选择最佳匹配 . 关于改进这个系统的任何建议,以便它不再触发不针对它的对话将是非常有帮助的 .
编辑:我已将名称识别器移动到单独的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 回答
让我确定我理解,你想要一个短语来为系统分配命令,比如“butler”或“Siri” . 所以,你会说“巴特勒,打开电视” . 你可以将它构建到你的语法中 .
下面是一个简单语法的示例,它在识别命令之前需要一个开始短语 . 它使用语义结果来帮助您理解所说的内容 . 在这种情况下,用户必须说“打开”或“请打开”或“你可以打开”
然后,您可以使用以下内容处理语音:
并检查语义结果,如:
我也有同样的问题 . 我正在使用Microsoft语音平台,所以它的准确度可能会有所不同等 .
我正在使用克莱尔作为唤醒命令,但它确实识别出克莱尔的不同词语 . 问题是引擎会听到你发言并搜索最接近的匹配 .
我没有找到一个非常好的解决方案 . 您可以尝试使用“置信度”字段过滤已识别的语音 . 但是我选择的识别器引擎并不是很可靠 . 我只是在一个大的SRGS.xml中抛出我想要识别的每个单词,并将重复值设置为0- . 我只接受认可的句子,因为克莱尔是第一个字 . 但是这个解决方案不是我想要的,因为它不能像我希望的那样好,但它仍然有点改进 .
我现在正忙着它,随着我的进步,我会发布更多信息 .
编辑1:作为对Dims所说的评论:在SRGS语法中可以添加"Garbage"规则 . 你可能想看一下 . http://www.w3.org/TR/speech-grammar/
原则上,您需要更新语法或字典以在其中包含“空”或“任何”条目 .
您是否可能需要在创建/加载要使用的语法之前运行UnloadAllGrammars()?