Java语音识别非常小的字典

我有MP3音频文件,其中包含计算机留下的语音邮件。

邮件内容始终采用相同的格式,并由同一计算机语音保留,内容略有不同:

“你今天卖了4辆汽车”(其中4辆可以是从0到9的任何东西)。

我一直试图建立Sphinx,但开箱即用的模型并没有太好用。

然后我尝试编写自己的声学模型并且还没有取得更好的成功(30%未被识别是我最好的)。

我想知道语音识别对于这个任务是否有点过分,因为我只有一个声音,一个预期的音频模式和一个非常有限的字典需要被识别。

我可以访问我需要在消息中搜索的十种声音(口述号码)中的每一种。

是否有非VR方法在音频文件中查找声音(如果需要,我可以将MP3转换为其他格式)。

更新:我的解决方案如下

在与Nikolay直接合作之后,我了解到我原来问题的答案是无关紧要的,因为使用Sphinx4和JSGF语法可以达到预期的结果(100%准确度)。

1:由于我的audo文件中的语音非常有限,我创建了一个JSGF语法( salesreport.gram )来描述它。 我在JSpeech Grammar Format页面上提供了创建以下语法所需的所有信息。

#JSGF V1.0; grammar salesreport; public  = ( |  | )+;  = this is your automated automobile sales report;  = you sold  cars today;  = thank you for using this system;  = zero | one | two | three | four | five | six | seven | eight | nine; 

注意: Sphinx在语法中不支持JSGF标记 。 如有必要,可以使用正则表达式来提取特定信息(在我的案例中为销售数量 )。

2:正确格式化音频文件非常重要 。 Sphinx的默认采样率为16Khz(16Khz表示每秒收集16000个样本)。 我使用FFmpeg将我的MP3音频文件转换为WAV格式。

 ffmpeg -i input.mp3 -acodec pcm_s16le -ac 1 -ar 16000 output.wav 

不幸的是,FFmpeg使这个解决方案依赖于操作系统。 我仍然在寻找一种使用Java转换文件的方法,如果/当我找到它时会更新这篇文章。

虽然不需要完成此任务,但我发现Audacity对于处理音频文件很有帮助。 它包括许多用于处理音频文件的实用程序(检查采样率和带宽,文件格式转换等)。

3:由于电话音频具有8kHz的最大带宽(音频中包含的频率范围),我使用了Sphinx en-us-8khz声学模型。

4:我使用lmtool生成了我的字典salesreport.dic

5:使用前面步骤中提到的文件和以下代码(Nikolay示例的修改版本),每次都能100%准确地识别我的语音。

 public String parseAudio(File voiceFile) throws FileNotFoundException, IOException { String retVal = null; StringBuilder resultSB = new StringBuilder(); Configuration configuration = new Configuration(); configuration.setAcousticModelPath("file:acoustic_models/en-us-8khz"); configuration.setDictionaryPath("file:salesreport.dic"); configuration.setGrammarPath("file:salesreportResources/") configuration.setGrammarName("salesreport"); configuration.setUseGrammar(true); StreamSpeechRecognizer recognizer = new StreamSpeechRecognizer(configuration); try (InputStream stream = new FileInputStream(voiceFile)) { recognizer.startRecognition(stream); SpeechResult result; while ((result = recognizer.getResult()) != null) { System.out.format("Hypothesis: %s\n", result.getHypothesis()); resultSB.append(result.getHypothesis() + " "); } recognizer.stopRecognition(); } return resultSB.toString().trim(); } 

这项任务的准确性必须是100%。 以下是与语法一起使用的代码示例:

 public class TranscriberDemoGrammar { public static void main(String[] args) throws Exception { System.out.println("Loading models..."); Configuration configuration = new Configuration(); configuration.setAcousticModelPath("file:en-us-8khz"); configuration.setDictionaryPath("cmu07a.dic"); configuration.setGrammarPath("file:./"); configuration.setGrammarName("digits"); configuration.setUseGrammar(true); StreamSpeechRecognizer recognizer = new StreamSpeechRecognizer(configuration); InputStream stream = new FileInputStream(new File("file.wav")); recognizer.startRecognition(stream); SpeechResult result; while ((result = recognizer.getResult()) != null) { System.out.format("Hypothesis: %s\n", result.getHypothesis()); } recognizer.stopRecognition(); } } 

您还需要确保采样率和音频带宽都与解码器配置相匹配

http://cmusphinx.sourceforge.net/wiki/faq#qwhat_is_sample_rate_and_how_does_it_affect_accuracy

首先,Sphinx仅适用于WAVE文件。 对于非常有限的词汇表,Sphinx在使用JSGF语法文件时应该会产生良好的结果(但在听写模式下却不是那么好)。 我发现的主要问题是它没有提供置信度分数(目前有漏洞)。 您可能想要检查另外三种选择:

  1. 来自Windows平台的SpeechRecognizer 。 它提供易于使用的识别,具有置信度分数和支持语法。 这是C#,但您可以构建本机包装器或自定义服务器。
  2. Google Speech API是一款在线语音识别引擎,每天最多可免费提出50个请求。 这有几个API,但我喜欢JARVIS 。 但要小心,因为没有关于此的官方支持或文档,谷歌可能(并且过去已经有)可以随时关闭此引擎。 当然,您会遇到一些隐私问题(可以将此音频数据发送给第三方吗?)。
  3. 我最近通过ISpeech获得了很好的成绩。 它提供了自己的Java包装器API,免费用于移动应用程序。 与Google API相同的隐私问题。

我自己选择使用第一个选项并在自定义http服务器中构建语音识别服务。 在Sphinx评分问题得到解决之前,我发现它是解决Java语音识别的最有效方法。