PocketSphinx on Raspberry pi 3

这篇博客是关于如何在树莓派上用 ReSpeaker 4-mic 阵列模块 +PocketSphinx+Python 实现语音识别。由于PocketSphinx和Python都是第一次接触,有很多不熟悉的概念和用法,文档也看得云里雾里,不过最后好歹是把sample跑起来了~撒花🎊

关于CMUSphinx

CMUSphinx(简称Sphinx)是美国卡内基梅隆大学开发的一系列语音识别系统的总称。
它的版本不断更新 :Sphinx,Sphinx2,Sphinx3,Sphinx4(Java),PocketSphinx(c)。我在这里使用的就是PocketSphinx,自它开始,Sphinx可以运行在嵌入式设备里了,比如手机和树莓派。Pocket就是“口袋”的意思,在名字上已经完全体现出来这一版本的特征了。
虽然PocketSphinx是用C实现的,如图所示:

但并不意味着只能使用C语言来开发应用。通过 SWIG (Simplified Wrapper and Interface Generator) ,就可以把C/C++的接口封装成其他语言的接口(大概就这么个意思吧),比如 Python ,ruby,java,C#…目前项目已有的版本如下:

在这里我使用的是Python版本的。

安装Sphinx模块

在树莓派上面打开终端,执行下面两条命令即可。当然安装前为了保证下载体验,一般是需要给树莓派换源。然而我因为有ss代理,所以就配置了一通,用上了自己的代理😉

1
2
python -m pip install --upgrade pip setuptools wheel
pip install --upgrade pocketsphinx

如果你向我一样是个python+Linux双重小白,不熟悉目录结构,也搞不清楚模块都安装到哪里去了,可以使用下面的命令

1
pip show pocketsphinx

结果如下:

1
2
3
4
5
6
7
8
9
10
Name: pocketsphinx
Version: 0.1.15
Summary: Python interface to CMU Sphinxbase and Pocketsphinx libraries
Home-page: https://github.com/bambocher/pocketsphinx-python
Author: Dmitry Prazdnichnov
Author-email: dmitry@prazdnichnov.name
License: BSD
Location: /usr/local/lib/python3.5/dist-packages
Requires:
Required-by:

模块安装好后的结构为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.
├── data
│   └── goforward.raw
├── __init__.py
├── model # 存放语言包
│   ├── cmudict-en-us.dict # 拼音字典文件
│   ├── en-us # 声学模型文件夹
│   │   ├── feat.params
│   │   ├── mdef
│   │   ├── means
│   │   ├── noisedict
│   │   ├── README
│   │   ├── sendump
│   │   ├── transition_matrices
│   │   └── variances
│   └── en-us.lm.bin #语言模型文件
├── _pocketsphinx.cpython-35m-arm-linux-gnueabihf.so
├── pocketsphinx.py
└── __pycache__
├── __init__.cpython-35.pyc
└── pocketsphinx.cpython-35.pyc

注:我之前不知道这个树状图是怎么搞出来的,查了才知道是用了 tree 命令。
btw,知道这个模块在哪里装着很有必要,因为后面更换默认语言包(默认只会识别英语)要用到.

我在安装的时候还报了个错:

问题出在我的树莓派上面没有安装 libpulse-dev
libpulse-dev:PulseAudio client development headers and libraries

1
sudo apt-get install libpulse-dev

ReSpeaker 4-Mics 阵列

这个模块是淘宝上面买的,199块钱····傻贵。别的文章里用的大都是USB麦克风,20几块钱一个。哎,自己买的哭着也要用下去。

把模块插到树莓派上之后开始装驱动,注意这个模块不可以热插拔。一套完整的操作如下:

1
2
3
4
5
6
sudo apt-get update
sudo apt-get upgrade
git clone https://github.com/respeaker/seeed-voicecard.git
cd seeed-voicecard
sudo ./install.sh
reboot

重启之后这个麦克风模块就启动了。接下来可以试试跑一下这个模块的sample:让灯闪
首先打开SPI

1
2
3
4
sudo raspi-config
选择 Interfacing Options
选择 SPI
enable

再来一波如下的操作:

1
2
3
4
5
6
7
pi@raspberrypi:~ $ cd /home/pi
pi@raspberrypi:~ $ git clone https://github.com/respeaker/4mics_hat.git
pi@raspberrypi:~ $ cd /home/pi/4mics_hat
pi@raspberrypi:~/4mics_hat $ sudo apt install python-virtualenv # install python virtualenv tool
pi@raspberrypi:~/4mics_hat $ virtualenv --system-site-packages ~/env # create a virtual python environment
pi@raspberrypi:~/4mics_hat $ source ~/env/bin/activate # activate the virtual environment
(env) pi@raspberrypi:~/4mics_hat $ pip install spidev gpiozero # install spidev and gpiozero

我其实不太理解为什么要弄虚拟环境?我试了一下那个sample是可以直接运行的。

连续识别(continuous recognition)

准备好之后就可以试试跑PocketSphinx的sample程序LiveSpeech了,它会连续识别语音内容,并输出到终端上。不过注意,它默认是英文语音,想测试得说英语。
源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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'), # (Hidden Markov Model) 隐马尔可夫模型 ,声学模型
lm=os.path.join(model_path, 'en-us.lm.bin'), # (Language Model) 语言模型
dic=os.path.join(model_path, 'cmudict-en-us.dict') # 拼音字典
)
for phrase in speech:
print("phrase:", phrase)
print(phrase.segments(detailed=True))

当然这个程序还是没有跑起来,运行的时候报错了。

Opening audio device(null) for capture: Connection refused

1
2
3
4
5
6
7
8
9
Error opening audio device (null) for capture: Connection refused
Traceback (most recent call last):
File "sphinx.py", line 14, in <module>
dic=os.path.join(model_path, 'cmudict-en-us.dict')
File "/usr/local/lib/python3.5/dist-packages/pocketsphinx/__init__.py", line 206, in __init__
self.ad = Ad(self.audio_device, self.sampling_rate)
File "/usr/local/lib/python3.5/dist-packages/sphinxbase/ad_pulse.py", line 124, in __init__
this = _ad_pulse.new_Ad(audio_device, sampling_rate)
RuntimeError: new_Ad returned -1

我明明装了mic,驱动都正常。后来查了好多资料才发现是一个叫 PulseAudio的软件没装,树莓派没有自带这个东西。还能怎么办,装就完了,这次不求甚解了:

1
2
sudo apt-get install pulseaudio
sudo reboot

跑起来之后试了一下,识别效果惨不忍睹。

更换中文语言包

  1. 下载中文语言包
  2. 解压得:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    .
    ├── README
    ├── zh_cn.cd_cont_5000
    │   ├── feat.params
    │   ├── feature_transform
    │   ├── mdef
    │   ├── means
    │   ├── mixture_weights
    │   ├── noisedict
    │   ├── transition_matrices
    │   └── variances
    ├── zh_cn.dic
    └── zh_cn.lm.bin
  3. 复制到model文件夹

    1
    2
    3
    sudo cp -a zh_cn.cd_cont_5000/ /usr/local/lib/python3.5/dist-packages/pocketsphinx/model
    sudo cp zh_cn.dic /usr/local/lib/python3.5/dist-packages/pocketsphinx/model
    sudo cp zh_cn.lm.bin /usr/local/lib/python3.5/dist-packages/pocketsphinx/model
  4. 需要更改一下三段代码

    1
    2
    3
    hmm=os.path.join(model_path, 'zh_cn.cd_cont_5000'),
    lm=os.path.join(model_path, 'zh_cn.lm.bin'),
    dic=os.path.join(model_path, 'zh_cn.dic')

更换之后确实可以识别中文了,然,识别率依然低得惊人

关键字查找(keyword search)

我在项目里使用pocketSphinx目的仅仅是让它识别指定的关键词,所以我需要着重考虑这一方面。

鼓励一下:D