安卓平台使用pocketSphinx离线语音识别
版权声明:本文为elecdog原创文章,可以转载,但必须在明确位置注明出处!谢谢合作。
关于语音识别,国内已经有比较好的公司推出相关的服务了,比如百度免费的离在线融合语音识别以及讯飞收费的在线和离线语音识别服务。这里不作过多介绍,需要的同学可以直接去官网阅读接入文档。这里要介绍的是一个离线语音识别的开源项目——CMU PocketSpinnx,在安卓开发中的使用。在智能家居 APP 开发中常需要在没法联网的设备识别一些比较简单的命令词,百度的离在线融合语音识别识别率还不错,不过在设备连接局域网的情况下仍然优先使用在线识别,导致识别时间太长或者转换不过来,讯飞离线语音识别没有使用过,因为是收费的,而且对于个人开发者价格也不便宜,相比较之下,PocketSpinnx则是完全离线的语音识别,只要按照要求部署项目,识别率也差强人意。
首先我们可以通过 PocketSpinnx 官网的介绍来了解该离线语音识别项目的工作原理,能够加深对项目使用的理解。下面我们一步一步来把PocketSpinnx的离线语音识别功能引入到我们自己的项目中来。
获取语言模型
首先我们需要把想要识别的命令词编写成命令集,打开 Sublime Text 新建 txt 文件,编码采用 utf-8,每一行写一个命令词,如图所示:

然后访问网址 http://www.speech.cs.cmu.edu/tools/lmtool-new.html 生成语言模型(国内访问不稳定,需自备梯子),点击选择文件,选择刚才编写的命令集文件 command.txt,然后点击COMPILE KNOWLEDGE BASE按钮就可以生成语言模型,如图:
这里生成了好几个文件,我们可以把整个 .tgz 文件下载下来解压缩,其中得到的 .lm 文件就是我们需要的语言模型。
获取字典模型
字典模型的作用,就是告诉语音识别器中文的发音,这样他才能认得中文,字典模型很简单,首先到 PocketSpinnx 的资源网盘,进入 Mandarin 文件夹,下载一个后缀为 .dic 的文件,里面涵盖了很多普通话的发音,查找到我们的命令词,找不到完整命令词的也可以找单个字的发音,然后参考这个 .dic 文件的格式,在上一步获取到的 .lm 语言模型文件中还有一个 .dic 文件,补充完整这个 .dic 文件的发音,如图所示:
这样字典模型就算是完成了。
获取声学模型
同样是在资源网盘的 Mandarin 文件夹下,下载 .tar.bz2 的压缩文件解压后,得到如下声学模型文件:
在项目中导入接口
在以上必要文件都准备好之后,我们可以在 PocketSpinnx 开源的安卓 demo中直观地了解具体的用法,项目结构如图所示:
我们可以把 demo 中的 aars 和 models 导入到我们自己的项目中,快速集成相关接口。demo 中 en-us-ptm 中的是英文的声学模型,为了能够识别中文,我们可以依样画葫芦新建一个 ptm-zh 文件夹,放入我们前面获取的普通话声学模型。同时,还需要把我们的语言模型和字典模型放进来,准备工作算是完成了。
获取识别器
现在我们已经可以在项目中调用相关的 API 了,首先需要获取最重要的语音识别器类SpeechRecognizer,如demo中的代码:
private void runRecognizerSetup() {
// Recognizer initialization is a time-consuming and it involves IO,
// so we execute it in async task
new AsyncTask<Void, Void, Exception>() {
@Override
protected Exception doInBackground(Void... params) {
try {
Assets assets = new Assets(PocketSphinxActivity.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
} catch (IOException e) {
return e;
}
return null;
}
@Override
protected void onPostExecute(Exception result) {
if (result != null) {
((TextView) findViewById(R.id.caption_text))
.setText("Failed to init recognizer " + result);
} else {
switchSearch(KWS_SEARCH);
}
}
}.execute();
}
private void setupRecognizer(File assetsDir) throws IOException {
// The recognizer can be configured to perform multiple searches
// of different kind and switch between them
recognizer = SpeechRecognizerSetup.defaultSetup()
.setAcousticModel(new File(assetsDir, "en-us-ptm"))//设置声学模型的文件夹
.setDictionary(new File(assetsDir, "cmudict-en-us.dict"))//设置字典模型
.setRawLogDir(assetsDir) // To disable logging of raw audio comment out this call (takes a lot of space on the device)
.getRecognizer();
recognizer.addListener(this);
/** In your application you might not need to add all those searches.
* They are added here for demonstration. You can leave just one.
*/
// 创建短语监听
recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
//创建命令文件监听
File menuGrammar = new File(assetsDir, "menu.gram");
recognizer.addGrammarSearch(MENU_SEARCH, menuGrammar);
// Create grammar-based search for digit recognition
File digitsGrammar = new File(assetsDir, "digits.gram");
recognizer.addGrammarSearch(DIGITS_SEARCH, digitsGrammar);
// Create language model search
File languageModel = new File(assetsDir, "weather.dmp");
recognizer.addNgramSearch(FORECAST_SEARCH, languageModel);
// Phonetic search
File phoneticModel = new File(assetsDir, "en-phone.dmp");
recognizer.addAllphoneSearch(PHONE_SEARCH, phoneticModel);
}
private void switchSearch(String searchName) {
recognizer.stop();
// If we are not spotting, start listening with timeout (10000 ms or 10 seconds).
if (searchName.equals(KWS_SEARCH))
recognizer.startListening(searchName);
else
recognizer.startListening(searchName, 10000);
}
这里需要注意设置声学模型文件夹的时候不需要写成 sync/ptm-zh,sync不需要写,否则会报错找不到文件。到这里按照 demo 的示例代码基本可以学会重要的方法调用了,如开始监听和结束监听等。
这里再提一下我们创建命令文件监听的时候需要使用的 .gram 文件,其实看一下 demo 中的 .gram 文件我们也知道该如何编写自己的命令文件了
#JSGF V1.0;
grammar menu;
public <item> = 命令词1 | 命令词2 | 命令词3;
一旦开始命令文件监听,则监听器就会监听命令文件中的命令词,当监听到语音的时候就会取出发音最相似的那个命令词返回到监听结果。请注意,这里意思是取出发音最相近的,这导致的时候也许你并没有说这些命令词的任何一个,只是监听器同样会取出他认为最相近的一个返回给结果,也就是表现的识别过于敏感,我在使用过程中还是属于可接受范围内。可以根据自己需求选择短语监听或者命令文件监听。
结束
到这里基本就可以使用 PocketSpinnx 离线语音识别了,一些细节的处理还需要自己阅读 demo 中的代码,代码不多而且容易理解,可以加深对使用的理解,另外,推荐阅读官方文档,能够详细知道项目的运行原理,以及文中没有提到的一些内容,虽然是英文的,但通过单词翻译也不难理解。
安卓平台使用pocketSphinx离线语音识别的更多相关文章
- Android离线语音识别(PocketSphinx)
近期做项目.用到离线语音识别.整了好久,查了好多方法.最终完毕.网上资料有点乱,并且大部分就是那几个人写的.一群人转!以下我总结一下.也为后来人行个方便. 关于环境配置我就不多说了.我就是依照这个教程 ...
- 安卓平台 全面支持软解和硬解的SDK-Demo源代码开放
专业做视频编解码的SDK开发工作. 2015年12月1日10:46:55: 更新到1.5.0版本 功能列表: 基本播放: 1,正常播放, 支持MP4,FLV,AVI,TS,3GP,RMVB,WM,WM ...
- 在Unity3D中实现安卓平台的本地通知推送
[前言] 对于手游来说,什么时候需要推送呢?玩过一些带体力限制的游戏就会发现,我的体力在恢复满后,手机会收到一个通知告诉我体力已完全恢复了.这类通知通常是由本地的客户端发起的,没有经过服务端. 在安卓 ...
- ionic3 打包安卓平台环境搭建报错解决方案总结
1.jvm虚拟机提供的运行空间小于项目所需的空间是报错.如图: 解决方法:在环境变量中配置jvm的运行内存大小,大于所需的内存即可. 其中:-Xmx512M可根据实际提示情况,进行更改,如1024M, ...
- Unity切换到安卓平台Shader丢失(opengl)
Unity安卓平台shader平台丢失 Unity的工程切换到Android平台后,运行游戏出现shader丢失 解决办法:在Unity桌面图标的快捷方式后添加 -force-gles20 示例:&q ...
- cocos2d-x 3.0 WIN7+VS2012 安卓平台搭建
***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...
- cocos2d-x hello world及安卓平台迁移
本节和大家一起新建一个项目工程,并通过cygwin迁移至android平台. 以下是本节主要内容: 利用cocos2d-x自带脚本,生成测试工程,并测试运行: 将该测试项目通过cyg ...
- 安卓平台ARM Mali OpenCL例子-灰度转换(转)
手头一块RK3288的板子,在板子上测试了一张1080p的彩色图灰度转换的OpenCL例子.OpenCL没有任何优化.例子请移步这里. 该例子是编译成安卓平台下的可执行程序. 进入jni文件夹,进行如 ...
- phongap开发中安卓平台上如何调用第三方播放器来播放HLS视频
前文曾经讲了关于在安卓平台上利用phonegap开发播放HLS的解决方案,其实最好的方案就是自己针对HLS视频开发自己的播放器,但是开发播放器是一个浩大的工程,必须对原生安卓开发非常熟悉,并且对视频播 ...
随机推荐
- Spring学习(24)--- AOP之 Aspect instantiation models(aspect实例模式)特别说明
重要: schema-defined aspects只支持singleton model,即 基于配置文件的aspects只支持单例模式
- Ubuntu下Tomcat初始配置
1.下载tomcat安装包 从tomcat官方网站http://tomcat.apache.org下载安装包,然后解压到某个目录,比如: ~/opt/apache-tomcat-7.0.63官方文档中 ...
- winform / Dev全局皮肤组件
话不多说先上效果图. 由于这是单独的测试项目, 用于演示Dev控件的皮肤样式, 所以上面只是演示了部分控件的效果. 下面则是一些实际项目中的截图: Dev的控件样式不仅美观丰富, 上面仅皮肤设置就有4 ...
- java 字符串全排列 和 去重
用递归进行排序 , 用TreeSet 去重. public class test { public static void main(String []args){ String str = &quo ...
- VS2017专业版和企业版激活密钥
VS2017专业版和企业版激活密钥 Professional: KBJFW-NXHK6-W4WJM-CRMQB-G3CDH Enterprise: NJVYC-BMHX2-G77MM-4XJMR-6Q ...
- Linux: 安装NVIDIA显卡驱动
Linux(Fedora25, 64bit)台式机配备了NVIDIA显卡GTX950,但是仅仅使用开源驱动nouveau,无法发挥NVIDIA显卡的性能,所以可以考虑使用官方提供的显卡驱动. # 先安 ...
- CSS(3)实现水平垂直居中效果
CSS实现水平垂直居中对齐 在CSS中实现水平居中,会比较简单.常见的,如果想实现inline元素或者inline-block元素水平居中,可以在其父级块级元素上设置text-align: cente ...
- google和oracle闹掰,Java 会不会被抛弃?
眼花缭乱的编程语言 程序界的语言实在太多,但有一种语言不得不说,那就是java语言,Java语言是Android系统的主要开发语言,现在和Google的关系不是很好,但是他会被淘汰吗?下面简单地分析一 ...
- js将时间戳转成格式化的时间
function getLocalTime(nS){ return new Date(parseInt(nS) * 1000).toLocaleString().replace(/年|月/g, &qu ...
- thinkphp中fetch渲染模板的处理
<script type="text/javascript"> function xiugai(elm){ var formData1=$("#a1_&quo ...