使用Microsoft SpeechRecognitionEngine时如何提高结果的准确性?
How to improve the accuracy of the results when using Microsoft SpeechRecognitionEngine?
我目前正在开发一个 DialerService 的项目。其中一项功能是将录制的 .wav 媒体文件解释为纯文本。我使用 SpeechRecognitionEngine 尝试解释内容,但得到了一些不准确的结果,有时甚至是毫无意义的断句。
.wav 文件是两个或多个客户之间的电话交谈的录音文件,我测试的文件是我与同事进行的非常简单和简短的对话。
所以我的问题是如何提高解释的准确性以及为此目的如何改进我的代码?我知道添加语法可以帮助识别一些关键字,但我需要的是对我从用户那里记录的内容进行大体解释。
下面是我的工作代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Speech.Recognition;
using System.Speech.AudioFormat;
using System.Web;
namespace VoiceRecognition
{
class Program
{
static bool completed;
static void Main(string[] args)
{
using (
SpeechRecognitionEngine recognizer =
new SpeechRecognitionEngine(
new System.Globalization.CultureInfo("en-US")))
{
// Create and load a grammar.
Grammar dictation = new DictationGrammar();
dictation.Name = "Dictation Grammar";
recognizer.LoadGrammar(new DictationGrammar());
recognizer.SetInputToWaveFile(@"C:\Projects2\VoiceRecognition2\conf_with_vincent_1.wav");
// Attach event handlers for the results of recognition.
//recognizer.AudioLevelUpdated += new EventHandler<AudioLevelUpdatedEventArgs>(recognizer_AudioLevelUpdated);
//recognizer.AudioStateChanged += new EventHandler<AudioStateChangedEventArgs>(recognizer_AudioStateChanged);
recognizer.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(recognizer_SpeechRecognized);
recognizer.RecognizeCompleted += new EventHandler<RecognizeCompletedEventArgs>(recognizer_RecognizeCompleted);
// Perform recognition on the entire file.
Console.WriteLine("Starting asynchronous recognition...");
completed = false;
//recognizer.RecognizeAsync();
recognizer.RecognizeAsync(RecognizeMode.Multiple);
// Keep the console window open.
while (!completed)
{
Console.ReadLine();
}
Console.WriteLine("Done.");
}
Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
// Handle the Audio state event.
static void recognizer_AudioStateChanged(object sender, AudioStateChangedEventArgs e)
{
Console.WriteLine("The new audio state is: " + e.AudioState);
}
static void recognizer_AudioLevelUpdated(object sender, AudioLevelUpdatedEventArgs e)
{
Console.WriteLine("The audio level is now: {0}.", e.AudioLevel);
}
// Handle the SpeechRecognized event.
static void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
if (e.Result != null && e.Result.Text != null)
{
Console.WriteLine(" Recognized text = {0}", e.Result.Text);
}
else
{
Console.WriteLine(" Recognized text not available.");
}
}
// Handle the RecognizeCompleted event.
static void recognizer_RecognizeCompleted(object sender, RecognizeCompletedEventArgs e)
{
if (e.Error != null)
{
Console.WriteLine(" Error encountered, {0}: {1}",
e.Error.GetType().Name, e.Error.Message);
}
if (e.Cancelled)
{
Console.WriteLine(" Operation cancelled.");
}
if (e.InputStreamEnded)
{
Console.WriteLine(" End of stream encountered.");
}
completed = true;
}
}
}
另一个class是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Speech.Recognition;
public class SpeechReconizer
{
SpeechRecognitionEngine _speechRecognitionEngine;
public SpeechReconitionResult ReadResult { get; set; }
public SpeechReconizer()
{
Grammar dictation = new DictationGrammar();
dictation.Name = "Dictation Grammar";
_speechRecognitionEngine = new SpeechRecognitionEngine();
_speechRecognitionEngine.SetInputToDefaultAudioDevice();
_speechRecognitionEngine.LoadGrammar(dictation);
_speechRecognitionEngine.InitialSilenceTimeout = TimeSpan.FromSeconds(3);
_speechRecognitionEngine.BabbleTimeout = TimeSpan.FromSeconds(2);
_speechRecognitionEngine.EndSilenceTimeout = TimeSpan.FromSeconds(1);
_speechRecognitionEngine.EndSilenceTimeoutAmbiguous = TimeSpan.FromSeconds(1.5);
_speechRecognitionEngine.RecognizeAsync(RecognizeMode.Multiple);
_speechRecognitionEngine.SpeechRecognized += RecognizerSpeechRecognized;
_speechRecognitionEngine.RecognizeCompleted += RecognizerRecognizeCompleted;
}
public SpeechReconitionResult ReadSpeech(string sourceAudio)
{
ReadResult = new SpeechReconitionResult();
_speechRecognitionEngine.SetInputToWaveFile(sourceAudio);
_speechRecognitionEngine.Recognize();
return ReadResult;
}
private void RecognizerSpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
if (e.Result != null && e.Result.Text != null)
{
ReadResult.Success = true;
ReadResult.Text = e.Result.Text;
}
else
{
ReadResult.Text = "Recognized text not available.";
}
}
private void RecognizerRecognizeCompleted(object sender, RecognizeCompletedEventArgs e)
{
if (e.Error != null)
{
ReadResult.Success = false;
ReadResult.ErrorMessage = string.Format("{0}: {1}",
e.Error.GetType().Name, e.Error.Message);
}
if (e.Cancelled)
{
ReadResult.Success = false;
ReadResult.ErrorMessage = "Operation cancelled.";
}
}
}
public class SpeechReconitionResult
{
public string Text { get; set; }
public bool Success { get; set; }
public string ErrorMessage { get; set; }
public bool Complete { get; set; }
}
测试结果是(在控制台):
Starting asynchronous recognition...
Recognized text = Helence and the globe or east
Recognized text = alarmed
Recognized text = and client thanks
Recognized text = what aren't going to do and that they
Recognized text = aren't goint to rule
Recognized text = working to dear E
Recognized text = N
Recognized text = at dinner
Recognized text = and
Recognized text = that going there
Recognized text = and you have a 98 no problem bars
End of stream encountered.
实际内容是什么:
- 你好文森特。
- 你好,鲍里斯。
-你好吗?
-我没事。
-你今天打算做什么?
-我要看电视,吃晚饭然后回家。
-感谢您有一个愉快的一天。
-没问题。
System.Speech.Recognition 支持默认的 windows 语音识别。它是为单个用户设计的,可以由用户通过 windows 语音识别训练进行训练。
您可能需要的是 Microsoft.Speech.Recognition 库,它专为低质量音频而设计。它的工作方式几乎相同,但是,它不是为听写而设计的。它更多地用于检测来自电话质量音频的命令。如果您想尝试一下,我发现的最新版本在这里:http://www.microsoft.com/en-us/download/details.aspx?id=27226
实际上,我已经使用 C# 测试了几种方法。其中之一是 SrgsToken.Pronunciation.Property 这实际上允许您从 SrgsOneOf 对象创建 “俚语规则”。假设您有一组命令,例如“abandon”,但对方说的是“abandon”。你实际上可以创建一个
SrgsOneOf abandon = new SrgsOneOf(new string[] { "abandan", "abandin", "ah'bandon", abanon });
从 SrgsOneOf 创建“俚语规则”objects.SrgsRule slangRule = new SrgsRule("slang", abandon);
此外,在 C# 中,枚举(或枚举类型)用于将常量名称分配给一组数字整数值。它使常量值更具可读性。我将其应用于我的 switch case 语句,从那时起,响应变得更加准确和清晰。
最后:练习良好的语法建设、投资昂贵的microphone/good质量是必不可少的。许多人忽视的另一个因素是字符串的使用和它可以消耗的内存。使用常量字符串“如下所示”的要点是常量字符串会自动驻留。如果您有 1000 个具有常规字符串字段的类型实例,并且所有实例都存储相同的永远不会更改的字符串,那么将存储 1000 个相等的字符串实例,从而不必要地破坏应用程序的内存配置文件。如果声明字符串常量,“它只会消耗一次内存”。这与直接使用字符串文字的行为相同。与静态只读字符串相比,常量字符串的值直接存储在引用 class.
中
假设我有选择:
选择命令 = new Choices();
commands.Add(new string[] { "scarlett find biochemistry"});
我该如何采取更明智的方法?
回答:
private const string V = "scarlett find biochemistry";
现在:
选择命令 = new Choices(); commands.Add(新字符串[] { V });
这大大改进了我在 YouTube.com 上看到的系统。 Scarlett Extreme
我目前正在开发一个 DialerService 的项目。其中一项功能是将录制的 .wav 媒体文件解释为纯文本。我使用 SpeechRecognitionEngine 尝试解释内容,但得到了一些不准确的结果,有时甚至是毫无意义的断句。
.wav 文件是两个或多个客户之间的电话交谈的录音文件,我测试的文件是我与同事进行的非常简单和简短的对话。
所以我的问题是如何提高解释的准确性以及为此目的如何改进我的代码?我知道添加语法可以帮助识别一些关键字,但我需要的是对我从用户那里记录的内容进行大体解释。
下面是我的工作代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Speech.Recognition;
using System.Speech.AudioFormat;
using System.Web;
namespace VoiceRecognition
{
class Program
{
static bool completed;
static void Main(string[] args)
{
using (
SpeechRecognitionEngine recognizer =
new SpeechRecognitionEngine(
new System.Globalization.CultureInfo("en-US")))
{
// Create and load a grammar.
Grammar dictation = new DictationGrammar();
dictation.Name = "Dictation Grammar";
recognizer.LoadGrammar(new DictationGrammar());
recognizer.SetInputToWaveFile(@"C:\Projects2\VoiceRecognition2\conf_with_vincent_1.wav");
// Attach event handlers for the results of recognition.
//recognizer.AudioLevelUpdated += new EventHandler<AudioLevelUpdatedEventArgs>(recognizer_AudioLevelUpdated);
//recognizer.AudioStateChanged += new EventHandler<AudioStateChangedEventArgs>(recognizer_AudioStateChanged);
recognizer.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(recognizer_SpeechRecognized);
recognizer.RecognizeCompleted += new EventHandler<RecognizeCompletedEventArgs>(recognizer_RecognizeCompleted);
// Perform recognition on the entire file.
Console.WriteLine("Starting asynchronous recognition...");
completed = false;
//recognizer.RecognizeAsync();
recognizer.RecognizeAsync(RecognizeMode.Multiple);
// Keep the console window open.
while (!completed)
{
Console.ReadLine();
}
Console.WriteLine("Done.");
}
Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
// Handle the Audio state event.
static void recognizer_AudioStateChanged(object sender, AudioStateChangedEventArgs e)
{
Console.WriteLine("The new audio state is: " + e.AudioState);
}
static void recognizer_AudioLevelUpdated(object sender, AudioLevelUpdatedEventArgs e)
{
Console.WriteLine("The audio level is now: {0}.", e.AudioLevel);
}
// Handle the SpeechRecognized event.
static void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
if (e.Result != null && e.Result.Text != null)
{
Console.WriteLine(" Recognized text = {0}", e.Result.Text);
}
else
{
Console.WriteLine(" Recognized text not available.");
}
}
// Handle the RecognizeCompleted event.
static void recognizer_RecognizeCompleted(object sender, RecognizeCompletedEventArgs e)
{
if (e.Error != null)
{
Console.WriteLine(" Error encountered, {0}: {1}",
e.Error.GetType().Name, e.Error.Message);
}
if (e.Cancelled)
{
Console.WriteLine(" Operation cancelled.");
}
if (e.InputStreamEnded)
{
Console.WriteLine(" End of stream encountered.");
}
completed = true;
}
}
}
另一个class是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Speech.Recognition;
public class SpeechReconizer
{
SpeechRecognitionEngine _speechRecognitionEngine;
public SpeechReconitionResult ReadResult { get; set; }
public SpeechReconizer()
{
Grammar dictation = new DictationGrammar();
dictation.Name = "Dictation Grammar";
_speechRecognitionEngine = new SpeechRecognitionEngine();
_speechRecognitionEngine.SetInputToDefaultAudioDevice();
_speechRecognitionEngine.LoadGrammar(dictation);
_speechRecognitionEngine.InitialSilenceTimeout = TimeSpan.FromSeconds(3);
_speechRecognitionEngine.BabbleTimeout = TimeSpan.FromSeconds(2);
_speechRecognitionEngine.EndSilenceTimeout = TimeSpan.FromSeconds(1);
_speechRecognitionEngine.EndSilenceTimeoutAmbiguous = TimeSpan.FromSeconds(1.5);
_speechRecognitionEngine.RecognizeAsync(RecognizeMode.Multiple);
_speechRecognitionEngine.SpeechRecognized += RecognizerSpeechRecognized;
_speechRecognitionEngine.RecognizeCompleted += RecognizerRecognizeCompleted;
}
public SpeechReconitionResult ReadSpeech(string sourceAudio)
{
ReadResult = new SpeechReconitionResult();
_speechRecognitionEngine.SetInputToWaveFile(sourceAudio);
_speechRecognitionEngine.Recognize();
return ReadResult;
}
private void RecognizerSpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
if (e.Result != null && e.Result.Text != null)
{
ReadResult.Success = true;
ReadResult.Text = e.Result.Text;
}
else
{
ReadResult.Text = "Recognized text not available.";
}
}
private void RecognizerRecognizeCompleted(object sender, RecognizeCompletedEventArgs e)
{
if (e.Error != null)
{
ReadResult.Success = false;
ReadResult.ErrorMessage = string.Format("{0}: {1}",
e.Error.GetType().Name, e.Error.Message);
}
if (e.Cancelled)
{
ReadResult.Success = false;
ReadResult.ErrorMessage = "Operation cancelled.";
}
}
}
public class SpeechReconitionResult
{
public string Text { get; set; }
public bool Success { get; set; }
public string ErrorMessage { get; set; }
public bool Complete { get; set; }
}
测试结果是(在控制台):
Starting asynchronous recognition...
Recognized text = Helence and the globe or east
Recognized text = alarmed
Recognized text = and client thanks
Recognized text = what aren't going to do and that they
Recognized text = aren't goint to rule
Recognized text = working to dear E
Recognized text = N
Recognized text = at dinner
Recognized text = and
Recognized text = that going there
Recognized text = and you have a 98 no problem bars
End of stream encountered.
实际内容是什么: - 你好文森特。 - 你好,鲍里斯。 -你好吗? -我没事。 -你今天打算做什么? -我要看电视,吃晚饭然后回家。 -感谢您有一个愉快的一天。 -没问题。
System.Speech.Recognition 支持默认的 windows 语音识别。它是为单个用户设计的,可以由用户通过 windows 语音识别训练进行训练。
您可能需要的是 Microsoft.Speech.Recognition 库,它专为低质量音频而设计。它的工作方式几乎相同,但是,它不是为听写而设计的。它更多地用于检测来自电话质量音频的命令。如果您想尝试一下,我发现的最新版本在这里:http://www.microsoft.com/en-us/download/details.aspx?id=27226
实际上,我已经使用 C# 测试了几种方法。其中之一是 SrgsToken.Pronunciation.Property 这实际上允许您从 SrgsOneOf 对象创建 “俚语规则”。假设您有一组命令,例如“abandon”,但对方说的是“abandon”。你实际上可以创建一个 SrgsOneOf abandon = new SrgsOneOf(new string[] { "abandan", "abandin", "ah'bandon", abanon });
从 SrgsOneOf 创建“俚语规则”objects.SrgsRule slangRule = new SrgsRule("slang", abandon);
此外,在 C# 中,枚举(或枚举类型)用于将常量名称分配给一组数字整数值。它使常量值更具可读性。我将其应用于我的 switch case 语句,从那时起,响应变得更加准确和清晰。
最后:练习良好的语法建设、投资昂贵的microphone/good质量是必不可少的。许多人忽视的另一个因素是字符串的使用和它可以消耗的内存。使用常量字符串“如下所示”的要点是常量字符串会自动驻留。如果您有 1000 个具有常规字符串字段的类型实例,并且所有实例都存储相同的永远不会更改的字符串,那么将存储 1000 个相等的字符串实例,从而不必要地破坏应用程序的内存配置文件。如果声明字符串常量,“它只会消耗一次内存”。这与直接使用字符串文字的行为相同。与静态只读字符串相比,常量字符串的值直接存储在引用 class.
中假设我有选择:
选择命令 = new Choices();
commands.Add(new string[] { "scarlett find biochemistry"});
我该如何采取更明智的方法? 回答: private const string V = "scarlett find biochemistry"; 现在: 选择命令 = new Choices(); commands.Add(新字符串[] { V });
这大大改进了我在 YouTube.com 上看到的系统。 Scarlett Extreme