在本指南中,详细记录了如何在Raspberry Pi上设置Porcupine以启用唤醒词检测,让树莓派拥有语音识别功能。
Porcupine是Picovoice团队开发的一款唤醒词检测引擎。热词/唤醒词检测就是用来监听一个关键词,然后触发预设的程序。谷歌助理和Alexa都利用了这些功能。例如,当你说 “Alexa “时,它就会唤醒设备,让它听你的命令。
热词检测引擎的难点在于利用它尽可能少的处理能力,同时不断地监听该关键词。在教程中,我将向你展示如何使用Porcupine实现其中的唤醒词部分。这样,当你说一个特定的词时,你就可以让一个动作发生。
Porcupine的设计是高度精确的,同时也是轻巧的,是树莓派的好搭档。Porcupine最大的一个缺点是,如果没有企业授权,它不允许为树莓派创建热词。你只能使用内置的唤醒词:“americano“, “blueberry“, “bumblebee“, “grapefruit“, “grasshopper“, “picovoice“, “porcupine““terminator“.
设备清单
以下是完成本教程在树莓Pi上安装Porcupine所需的全部设备清单,点击链接可直达特别优惠购买。
建议
可选
我在运行最新版本的Raspberry Pi OS Lite版(Buster版本)的Raspberry Pi 4上测试了本教程。
为Porcupine准备Raspberry Pi的音频配置
在本节中,将在Raspberry Pi上设置音频配置。这样做将帮助Porcupine唤醒词检测选择正确的设备来使用。
1. 先找到麦克风和设备号。
为了能够做到这一点,需要利用以下命令。
arecord -l
从这个命令中,你会得到一个响应,就像下面所说的那样。记下你的麦克风的卡号和设备号。
**** List of CAPTURE Hardware Devices ****
card 2: Microphone [Yeti Stereo Microphone], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
2. 虽然本教程不需要,但也应该检索音频输出的设备和卡号。
要检索音频输出的这些数字,请输入以下命令。
aplay -l
以下是该命令的输出示例。记下你的卡号和设备号,以获得你想要的输出。
**** List of PLAYBACK Hardware Devices ****
card 0: b1 [bcm2835 HDMI 1], device 0: bcm2835 HDMI 1 [bcm2835 HDMI 1]
Subdevices: 4/4
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
card 1: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
Subdevices: 4/4
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
请注意,树莓派的3.5mm接口会被标为模拟、bcm2835 ALSA或bcm385耳机。HDMI输出应识别为bcm2835 IEC958/HDMI。
3. 手上有了所有的值之后,就可以去修改ALSA配置文件了。
运行以下命令开始在Pi用户的主目录下创建.asoundrc文件。
nano /home/pi/.asoundrc
4. 在这个文件中,需要输入以下几行。这些行将设置音频驱动程序,并帮助它知道应该与哪些设备进行交互。
在这段代码中,请确保用你在步骤1和步骤2中得到的值代替<卡号>和<设备号>。
pcm.!default {
type asym
capture.pcm "mic"
playback.pcm "speaker"
}
pcm.mic {
type plug
slave {
pcm "hw:<card number>,<device number>"
}
}
pcm.speaker {
type plug
slave {
pcm "hw:<card number>,<device number>"
}
}
5. 一旦输入完成后,按CTRL + X,然后按Y,最后按ENTER键保存。
安装Porcupine Wake字检测库
在本节中,展示如何将Porcupine Python库安装到Raspberry Pi上,并验证它是否工作。
1. 在将Porcupine安装到Raspberry Pi之前,需要确保所有的东西都是最新的。
要更新操作系统,请运行以下两个命令。
sudo apt update
sudo apt full-upgrade
2. 接下来,安装运行Porcupine软件所需的软件包。
这些软件包主要包括Python和port音频库。
通过运行以下命令安装我们需要的软件包。
sudo apt install python3 python3-pip python3-all-dev python3-pyaudio portaudio19-dev libsndfile1
3. 现在使用Python包管理器来下载pvporcupine
库。
运行以下命令来安装库。
sudo pip3 install pvporcupine
请注意,这个过程可能需要一些时间,因为有许多软件依赖的软件包。
4. 现在运行以下命令来测试Porcupine唤醒词引擎是否工作。
pvporcupine_mic --keywords porcupine
运行这个命令会运行porcupine
引擎。现在需要做的就是说出 “porcupine
“这个词。
一旦它检测到这个关键词被说出来,会看到命令行中出现下面的文字。
detected keyword
这个响应表明Porcupine软件已经成功监听了您的麦克风,并检测到了关键词。
在Python中使用Porcupine
在本节中,展示如何在Python中的Raspberry Pi上使用Porcupine热词检测库。
你很快就会发现,这是一个相当简单易用的库,只需要几行代码就能实现唤醒词检测。如果您在完成本指南后还想了解更多,请务必查看我的 Python 指南。
1. 先在主目录下创建一个新的Python,名为 “pimylifeup_voicedetector.py”。
通过运行下面的命令开始编写这个脚本。
nano pimylifeup_voicedetector.py
2. 在该文件中,输入以下代码:
在输入代码的时候会解释每一部分代码的作用。
A. 首先要在这个文件中加入 “shebang”。
#!/usr/bin/env python3
这一行有助于告诉操作系统,它需要使用 Python 3 解释器来解释我们的脚本。
B. 为了开始这段代码,需要导入要依赖的包。
这些包中的每一个包都对在Raspberry Pi上运行的唤醒词检测脚本都很重要。
import struct
import pyaudio
import pvporcupine
导入的第一个包,struct是用来将音频输入解包成Porcupine期望的东西。
第二个包,pyaudio,允许我们从连接到Raspberry Pi的麦克风中创建一个音频流,可以将其输入到Porcupine检测引擎中。
最后一个导入是最重要的一个包。pvporcupine库让我们与Porcupine软件进行交互,实时监听热词检测。
C. 下一步是创建一些变量来存储Porcupine、PyAudio和我们由PyAudio创建的音频流的句柄。
porcupine = None
pa = None
audio_stream = None
这样做是为了在脚本出现问题或被终止时,可以干净利落地关闭一切。
D. 接下来,需要用try语句开始下面的部分。
try:
以下所有的部分都需要稍微缩进。try 语句允许我们在某些事情导致脚本终止或崩溃时干净利落地退出。
E. 有了所有的导入,现在可以创建一个唤醒词到Porcupine库。
porcupine = pvporcupine.create(keywords=["picovoice", "blueberry"])
这个.create()函数创建了一个Porcupine唤醒词检测库的句柄,可以将音频送入其中。在这个调用中,可以指定要监听的关键字。由于只能用Picovoice提供的,所以需要用以下其中一种。americano“, “blueberry“, “bumblebee“, “grapefruit“, “grasshopper“, “picovoice“, “porcupine““terminator“。
在我的例子中,我指定的关键词是 “picovoice “和 “blueberry”。Porcupine可以监听多个关键词。如果你想监听所有可能的关键词,可以用keywords=pvporcupine.KEYWORDS代替。
F. 在下一行,需要使用pyaudio创建一个句柄,使我们能够与PortAudio进行交互。
pa = pyaudio.PyAudio()
我将PyAudio库提供的句柄存储在pa变量中,并使用它来监听麦克风。
G.立即将PyAudio提供的句柄投入使用,打开一个音频流。
audio_stream = pa.open(
rate=porcupine.sample_rate,
channels=1,
format=pyaudio.paInt16,
input=True,
frames_per_buffer=porcupine.frame_length)
为了创建这个音频流,输入了豪猪库提供给的一些信息。
把采样率定在porcupine
提供给我们的默认数值。
每个缓冲区的帧数设置为Porcupine软件所期望的数量。这个值通常是512帧。
除此以外,还有一些其他的东西,传递到要打开的音频流中。将通道强制为1,设置成正在期待输入,并将音频格式设置为INT16。
H. 现在已经准备好了音频流和创建了Porcupine唤醒词检测库的句柄,需要开始一个无限循环。
while True:
只需要在Python中创建一个无限循环,就是使用一个while循环,然后是True。由于该值永远为真,所以循环将运行到脚本被强制终止。
请记住,以下部分都需要缩进,因为它们属于循环。
I. 每次循环时,都需要从音频流中读入一些数据。
pcm = audio_stream.read(porcupine.frame_length)
pcm = struct.unpack_from("h" * porcupine.frame_length, pcm)
使用之前创建的音频流来读取麦克风的输入,指定Porcupine提供的帧长。在收到音频数据回传后,再使用unpack_from函数将音频数据解包成唤醒词检测引擎所期望的内容。将这些结果值存储到pcm变量中。
J. 在这个阶段,可以让Porcupine唤醒词检测来处理刚刚抓取的音频流。
keyword_index = porcupine.process(pcm)
我们需要利用Porcupine句柄中的.process()函数,并传入存储在pcm变量中的音频数据。
如果定义了多个关键字,这个函数将返回检测到的关键字的索引,这个索引基于数组或输入文件的顺序,第一个关键字为索引0。这个索引是基于数组或输入文件的顺序,第一个关键字的索引为0。如果你只定义了一个关键字,那么这个函数将在检测到时返回True。如果没有检测到关键字,那么Porcupine过程函数将返回-1。我们将这个值存储到我们的keyword_index变量中。
K. 接下来,终于可以检查一下关键词是否被检测到了。
if keyword_index >= 0:
print("Hotword Detected")
如果唤醒词处理器返回的值大于或等于0,就可以认为热词被检测到了。在我的例子中,如果满足了正确的条件,就会打印出 “热词检测 “的文本。
L. 现在已经完成了代码的大脑,需要用finally:语句来结束它。
finally:
通过在 “try “后面使用 “finally”,能够运行一些东西,清理所有创建的句柄。即使 try 中的某些东西导致 Python 脚本崩溃,这些语句也应该被触发。
M. 在我们的最终声明中,我们要做的第一件事就是清理porcupine
库。
这一部分格外重要,因为Porcupine库不依赖于垃圾收集器。
if porcupine is not None:
porcupine.delete()
你会看到,在清理Porcupine之前,首先要确保它的变量porcupine仍然没有设置为None。如果设置为None,则意味着从未创建过句柄,运行.delete()函数将导致异常。
N. 接下来,需要确保关闭音频流。
if audio_stream is not None:
audio_stream.close()
就像porcupine库
一样,需要确保audio_stream不为空。
如果已经设置了一些东西,调用流上的.close()函数来清理它并停止与麦克风的连接。
O. 最后需要做的是检查PyAudio句柄。
if pa is not None:
pa.terminate()
同样,只在句柄被分配了一个值的情况下才会尝试清理它。在这种情况下,需要使用PyAudios .terminate()函数来清理它。
3. 如果正确输入了所有内容,应该最终得到以下代码:
#!/usr/bin/env python3
import struct
import pyaudio
import pvporcupine
porcupine = None
pa = None
audio_stream = None
try:
porcupine = pvporcupine.create(keywords=["picovoice", "blueberry"])
pa = pyaudio.PyAudio()
audio_stream = pa.open(
rate=porcupine.sample_rate,
channels=1,
format=pyaudio.paInt16,
input=True,
frames_per_buffer=porcupine.frame_length)
while True:
pcm = audio_stream.read(porcupine.frame_length)
pcm = struct.unpack_from("h" * porcupine.frame_length, pcm)
keyword_index = porcupine.process(pcm)
if keyword_index >= 0:
print("Hotword Detected")
finally:
if porcupine is not None:
porcupine.delete()
if audio_stream is not None:
audio_stream.close()
if pa is not None:
pa.terminate()
4. 如果所有的代码看起来都是正确的,你可以通过按,CTRL + X,然后按Y,然后按ENTER键来保存文件。
5. 脚本写好了,现在可以测试一下,看看它是否有效。
要做到这一点,需要做的是使用python3,然后是我们的脚本名称pimylifeup_voicedetector.py。
pimylifeup_voicedetector.py
5. 在脚本运行的情况下,每当你提到一个定义的唤醒词时,你应该会看到以下文字出现。
Hotword Detected
如果你完全按照我的教程,这些关键词应该是 “picovoice “或 “blueberry
“。
希望到这里,你现在能对如何在Raspberry Pi上使用Porcupine唤醒词引擎有了一些了解。如果你在本指南中遇到任何问题,欢迎在下方留言。
欢迎转载,请留下出处链接:Labno3 » 树莓派语音识别,详细步骤安装和配置Porcupine检测唤醒词