使用 pocketsphinx 模块, 实现唤醒词功能.
运行环境:
win10 + Python3.6.2
安装模块包:
地址: https://pypi.org/project/pocketsphinx/
- > pip install pocketsphinx
- C:\Users\qpf10>pip install pocketsphinx
- Collecting pocketsphinx
- Downloading https://files.pythonhosted.org/packages/52/53/30b12c3e4de918e32e73e9d635b4c9e1765512acc94ad0b51bfe960b54c9/pocketsphinx-0.1.15-cp36-cp36m-win_amd64.whl (29.1MB)
100% |████████████████████████████████| 29.1MB 104kB/s
- Installing collected packages: pocketsphinx
- Successfully installed pocketsphinx-0.1.15
pypi 官方简介:
Pocketsphinx 是 CMU Sphinx 语音识别开源工具包的一部分.
这个包为使用 SWIG 和 Setuptools 创建的 CMU Sphinxbase 和 Pocketsphinx 库提供了一个 python 接口.
一, 运行官方自带案例 - LiveSpeech
有道翻译: 它是一个迭代器类, 用于从麦克风连续识别或关键字搜索.
在 pycharm 中运行代码, 完美运行.
- import os
- from pocketsphinx import LiveSpeech, get_model_path
- model_path = get_model_path()
- speech = LiveSpeech(
- verbose=False,
- sampling_rate=16000,
- buffer_size=2048,
- no_search=False,
- full_utt=False,
- hmm=os.path.join(model_path, 'en-us'),
- lm=os.path.join(model_path, 'en-us.lm.bin'),
- dic=os.path.join(model_path, 'cmudict-en-us.dict')
- )
- for phrase in speech:
- print("phrase:", phrase)
- print(phrase.segments(detailed=True))
运行后, 我说了两句 (发音不标准), 一句 hello, 一句 hello Word, 显示结果: 感觉识别的很有问题... 虽说不标准, 但是不至于这个情况.
- Allocating 32 buffers of 2500 samples each
- phrase: i'm
- [('<s>', -7, 37837, 37890), ('<sil>', -6, 37891, 38010), ("i'm(2)", -913, 38011, 38064), ('[SPEECH]', -6069, 38065, 38070), ('</s>', 0, 38071, 38078)]
- phrase: hello or earth
- [('<s>', -5, 186767, 186778), ('hello', -9386, 186779, 186834), ('or', -3672, 186835, 186854), ('earth', -1192, 186855, 186904), ('</s>', 0, 186905, 186907)]
二, 运行中文语言模型内容
参考博客:
添加中文语言模型和中文声学模型
中文相关文件下载地址:
> 1. 声学模型: zh_broadcastnews_16k_ptm256_8000.tar.bz2
> 2. 语言模型: zh_broadcastnews_64000_utf8.DMP
> 3. 拼音字典: zh_broadcastnews_utf8.dic
拷贝到 model 文件夹下:
> 将文件放到 PHTHON_HOME 的 pocketsphinx 模块包下, 我这里是在 C:\Python36\Lib\site-packages\pocketsphinx\model
放代码: 没有变化, 只是加载的目录文件变了.
- import os
- from pocketsphinx import LiveSpeech, get_model_path
- model_path = get_model_path()
- speech = LiveSpeech(
- verbose=False,
- sampling_rate=16000,
- buffer_size=2048,
- no_search=False,
- full_utt=False,
- hmm=os.path.join(model_path, 'zh/zh_broadcastnews_16k_ptm256_8000'),
- lm=os.path.join(model_path, 'zh/zh_broadcastnews_64000_utf8.DMP'),
- dic=os.path.join(model_path, 'zh/zh_broadcastnews_utf8.dic')
- )
- for phrase in speech:
- print("phrase:", phrase)
- print(phrase.segments(detailed=True))
运行后的结果, 还是非常的不准确. 虽说带点东北口音, 但是识别的还是挺差的... 说的, 你好, 你好吗, 滚. 还说了挺多其他的, 都没有很好的效果, 就不贴了.
运行后, 半天才反应过来开始识别, 不知道是什么原因, 刚开始我还以为是程序监听不到语音呢.
Allocating 32 buffers of 2500 samples each
phrase: 尼 尔 奥
[('<s>', 2, 2645708, 2645714), ('尼', -357, 2645715, 2645771), ('尔 (2)', -2, 2645772, 2645811), ('奥', -42088, 2645812, 2645853), ('</s>', 0, 2645854, 2645857)]
phrase: 尼 尔 欧盟
[('<s>', -2, 2828757, 2828765), ('尼', -11911, 2828766, 2828782), ('尔 (2)', -2519, 2828783, 2828837), ('欧盟', 0, 2828838, 2828868), ('</s>', 0, 2828869, 2828872)]
phrase: 不同
[('<s>', 1, 3023056, 3023061), ('不同', -18424, 3023062, 3023128), ('</s>', 0, 3023129, 3023133)]
还会出现如下这种空的情况 - -!:
- phrase:
- [('<s>', -4, 6295811, 6295819), ('++incomplete++', 0, 6295820, 6295973), ('</s>', 0, 6295974, 6296015)]
三, 运行自定义的中文语言模型内容
这里有个前提: 我只把 pocketsphinx 当做唤醒词来使用.
具体操作步骤
编辑一个自定义的 keyword.txt 文本, 里面写入打算唤醒的中文词语, 和发音可能混淆的词 (如果拼音相同只记录一个就行). 再添加一些其他的乱七八糟的词, 这样匹配的时候就不会一直匹配唤醒词了.(唤醒词的重点)
以小贝为例, 则 keyword.txt 中的内容如下:
小贝
小魏
巧倍
啊
呵呵
哈哈
么么哒
在 [ http://www.speech.cs.cmu.edu/tools/lmtool-new.html ] 上面训练上一步的 keyword 文本. 会生成 "随机数. lm" 和 "随机数. dic", 下载这两个文件就可以. 用来替代语言模型和拼音字典.
如:
1234.lm
1234.dic
编辑下载的随机数. dic 文件, 对照着 zh_broadcastnews_utf8.dic 的拼音字典, 更改成与其同样格式的内容. 原字典中不一定会有相同的词语, 有的话, 就按照原先的写, 没有的话, 就按照单个发音的写上就可以.
例如:
小贝 x i ao b ei
小魏 x i ao w ei
巧倍 q i ao b ei
啊 a as
.
.
.
在代码中, 替换掉对应的 lm 和 dic 路径.
- import os
- from pocketsphinx import LiveSpeech, get_model_path
- model_path = get_model_path()
- speech = LiveSpeech(
- verbose=False,
- sampling_rate=16000,
- buffer_size=2048,
- no_search=False,
- full_utt=False,
- hmm=os.path.join(model_path, 'zh/zh_broadcastnews_16k_ptm256_8000'),
- lm=os.path.join(model_path, 'zh/1234.lm'), # 这个目录位置自己设置
- dic=os.path.join(model_path, 'zh/1234.dic') # 同上
- )
- for phrase in speech:
- print("phrase:", phrase)
- print(phrase.segments(detailed=True))
- # 只要命中上述关键词的内容, 都算对
- if str(phrase) in ["小贝", "小魏", "巧倍"]:
- print("正确识别唤醒词")
来源: http://blog.51cto.com/feature09/2300352