Я работаю над личным проектом с использованием микрофонов в моей квартире, которому я могу давать устные команды. Для этого я использовал 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);
}
}
}
Если имя «Октавиан», оно распознает такие вещи, как «Осьминог», «Октагон», «Фольксваген» и «Вау, правда?». Я четко слышу разницу в связанных аудиоклипах. Любые идеи о том, как сделать это не ужасным, были бы великолепны.