版权声明:本文为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中的代码:

  1. private void runRecognizerSetup() {
  2. // Recognizer initialization is a time-consuming and it involves IO,
  3. // so we execute it in async task
  4. new AsyncTask<Void, Void, Exception>() {
  5. @Override
  6. protected Exception doInBackground(Void... params) {
  7. try {
  8. Assets assets = new Assets(PocketSphinxActivity.this);
  9. File assetDir = assets.syncAssets();
  10. setupRecognizer(assetDir);
  11. } catch (IOException e) {
  12. return e;
  13. }
  14. return null;
  15. }
  16. @Override
  17. protected void onPostExecute(Exception result) {
  18. if (result != null) {
  19. ((TextView) findViewById(R.id.caption_text))
  20. .setText("Failed to init recognizer " + result);
  21. } else {
  22. switchSearch(KWS_SEARCH);
  23. }
  24. }
  25. }.execute();
  26. }
  27. private void setupRecognizer(File assetsDir) throws IOException {
  28. // The recognizer can be configured to perform multiple searches
  29. // of different kind and switch between them
  30. recognizer = SpeechRecognizerSetup.defaultSetup()
  31. .setAcousticModel(new File(assetsDir, "en-us-ptm"))//设置声学模型的文件夹
  32. .setDictionary(new File(assetsDir, "cmudict-en-us.dict"))//设置字典模型
  33. .setRawLogDir(assetsDir) // To disable logging of raw audio comment out this call (takes a lot of space on the device)
  34. .getRecognizer();
  35. recognizer.addListener(this);
  36. /** In your application you might not need to add all those searches.
  37. * They are added here for demonstration. You can leave just one.
  38. */
  39. // 创建短语监听
  40. recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
  41. //创建命令文件监听
  42. File menuGrammar = new File(assetsDir, "menu.gram");
  43. recognizer.addGrammarSearch(MENU_SEARCH, menuGrammar);
  44. // Create grammar-based search for digit recognition
  45. File digitsGrammar = new File(assetsDir, "digits.gram");
  46. recognizer.addGrammarSearch(DIGITS_SEARCH, digitsGrammar);
  47. // Create language model search
  48. File languageModel = new File(assetsDir, "weather.dmp");
  49. recognizer.addNgramSearch(FORECAST_SEARCH, languageModel);
  50. // Phonetic search
  51. File phoneticModel = new File(assetsDir, "en-phone.dmp");
  52. recognizer.addAllphoneSearch(PHONE_SEARCH, phoneticModel);
  53. }
  54. private void switchSearch(String searchName) {
  55. recognizer.stop();
  56. // If we are not spotting, start listening with timeout (10000 ms or 10 seconds).
  57. if (searchName.equals(KWS_SEARCH))
  58. recognizer.startListening(searchName);
  59. else
  60. recognizer.startListening(searchName, 10000);
  61. }

这里需要注意设置声学模型文件夹的时候不需要写成 sync/ptm-zh,sync不需要写,否则会报错找不到文件。到这里按照 demo 的示例代码基本可以学会重要的方法调用了,如开始监听和结束监听等。

这里再提一下我们创建命令文件监听的时候需要使用的 .gram 文件,其实看一下 demo 中的 .gram 文件我们也知道该如何编写自己的命令文件了

  1. #JSGF V1.0;
  2. grammar menu;
  3. public <item> = 命令词1 | 命令词2 | 命令词3;

一旦开始命令文件监听,则监听器就会监听命令文件中的命令词,当监听到语音的时候就会取出发音最相似的那个命令词返回到监听结果。请注意,这里意思是取出发音最相近的,这导致的时候也许你并没有说这些命令词的任何一个,只是监听器同样会取出他认为最相近的一个返回给结果,也就是表现的识别过于敏感,我在使用过程中还是属于可接受范围内。可以根据自己需求选择短语监听或者命令文件监听。

结束

到这里基本就可以使用 PocketSpinnx 离线语音识别了,一些细节的处理还需要自己阅读 demo 中的代码,代码不多而且容易理解,可以加深对使用的理解,另外,推荐阅读官方文档,能够详细知道项目的运行原理,以及文中没有提到的一些内容,虽然是英文的,但通过单词翻译也不难理解。

安卓平台使用pocketSphinx离线语音识别的更多相关文章

  1. Android离线语音识别(PocketSphinx)

    近期做项目.用到离线语音识别.整了好久,查了好多方法.最终完毕.网上资料有点乱,并且大部分就是那几个人写的.一群人转!以下我总结一下.也为后来人行个方便. 关于环境配置我就不多说了.我就是依照这个教程 ...

  2. 安卓平台 全面支持软解和硬解的SDK-Demo源代码开放

    专业做视频编解码的SDK开发工作. 2015年12月1日10:46:55: 更新到1.5.0版本 功能列表: 基本播放: 1,正常播放, 支持MP4,FLV,AVI,TS,3GP,RMVB,WM,WM ...

  3. 在Unity3D中实现安卓平台的本地通知推送

    [前言] 对于手游来说,什么时候需要推送呢?玩过一些带体力限制的游戏就会发现,我的体力在恢复满后,手机会收到一个通知告诉我体力已完全恢复了.这类通知通常是由本地的客户端发起的,没有经过服务端. 在安卓 ...

  4. ionic3 打包安卓平台环境搭建报错解决方案总结

    1.jvm虚拟机提供的运行空间小于项目所需的空间是报错.如图: 解决方法:在环境变量中配置jvm的运行内存大小,大于所需的内存即可. 其中:-Xmx512M可根据实际提示情况,进行更改,如1024M, ...

  5. Unity切换到安卓平台Shader丢失(opengl)

    Unity安卓平台shader平台丢失 Unity的工程切换到Android平台后,运行游戏出现shader丢失 解决办法:在Unity桌面图标的快捷方式后添加 -force-gles20 示例:&q ...

  6. cocos2d-x 3.0 WIN7+VS2012 安卓平台搭建

    ***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...

  7. cocos2d-x hello world及安卓平台迁移

        本节和大家一起新建一个项目工程,并通过cygwin迁移至android平台.      以下是本节主要内容: 利用cocos2d-x自带脚本,生成测试工程,并测试运行: 将该测试项目通过cyg ...

  8. 安卓平台ARM Mali OpenCL例子-灰度转换(转)

    手头一块RK3288的板子,在板子上测试了一张1080p的彩色图灰度转换的OpenCL例子.OpenCL没有任何优化.例子请移步这里. 该例子是编译成安卓平台下的可执行程序. 进入jni文件夹,进行如 ...

  9. phongap开发中安卓平台上如何调用第三方播放器来播放HLS视频

    前文曾经讲了关于在安卓平台上利用phonegap开发播放HLS的解决方案,其实最好的方案就是自己针对HLS视频开发自己的播放器,但是开发播放器是一个浩大的工程,必须对原生安卓开发非常熟悉,并且对视频播 ...

随机推荐

  1. 关于AD9516芯片的硬件设计和FPGA程序编写心得

    最近在做一个项目,其中有涉及时钟芯片AD9516的硬件设计和软件编程,有些使用心得,供大家参考讨论. AD9516,这是一个由ADI公司设计的14路输出时钟发生器,具有亚皮秒级抖动性能,还配有片内集成 ...

  2. 依赖注入之Autofac使用总结

    依赖倒置?控制反转(IOC)? 依赖注入(DI)? 你是否还在被这些名词所困扰,是否看了大量理论文章后还是一知半解了? 今天我想结合实际项目,和正在迷惑中的新手朋友一起来学习和总结依赖注入Autofa ...

  3. spring非controller类获取service方法

    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); pushMessageServ ...

  4. MySQL基础语法------增删改查

    1.增 1.1建立数据库 create database test2; 格式:create database <数据库名> 1.2建表 create table student( sno ...

  5. 学习总结------Servlet控制器的简单运用

    前言: 今天将简单的模拟 MVC模式 对Servlet控制器运行 若有不好或不对的地方,欢迎各位大神进行指导! 1.MVC模式(图) MVC全名是Model View Controller,是模型(m ...

  6. JVM高级特性-三、垃圾收集之判断对象存活算法

    一.概述 运行时数据区中,程序计数器.虚拟机栈.本地方法栈都是随线程而生随线程而灭的 因此,他们的内存分配和回收是确定的,在方法或线程结束时就回收.而Java堆和方 法区则是不确定的,程序运行过程中创 ...

  7. 什么是Css Hack?ie6,7,8的hack分别是什么?

    针对不同的浏览器写不同的CSS code的过程,就是CSS hack. 示例如下: 1 2 3 4 5 6 7 8 9 10 11 12 #test       { width:300px; heig ...

  8. 关于MATLAB处理大数据坐标文件2017622

    今天新提交了一次数据,总量达到10337个,本以为成绩会突飞猛进,没想到还是不如从前 但是已经找到人工鼠标轨迹的程序,有待完善,接下来兵分四路:找特征.决策树.完善人工轨迹程序,使其可以将生成的数据自 ...

  9. Elasticsearch5.0.1安装

    最新研究了下ES5.0,ES就是为高可用和可扩展而生的,你可以很方便的增加也减少一个节点.顺便记录下安装过程,也方便以后查看. 1            安装部骤 1.1    安装JDK ES依赖于 ...

  10. 基于Angularjs实现图片上传和下载

    根据ng-file-uoload实现文件上传和下载实现 网上down下来ng-file-uoload.js,在项目中记得引入服务哦. 示例代码: FileUploaderCtrl.$inject = ...