离线语音唤醒引擎SnowBoy可以实现离线语音热词的检测,可发起一个安全、完整的语音交互界面。
百度云语音识别API可实现在线的语音识别和语音合成功能。结合离线语音唤醒和语音识别技术可以实现完整、安全的语音交互,实现语音机器人、语音控制等功能。
获取更多信息请查看:https://github.com/dalinzhangzdl/AI_Car_Raspberry-pi
一、snowboy介绍、安装与测试
Snowboy 是一款高度可定制的唤醒词检测引擎,可以用于实时嵌入式系统,并且始终监听(即使离线)。当前,它可以运行在 Raspberry Pi、(Ubuntu)Linux 和 Mac OS X 系统上。唤醒词用于,发起一个完整的语音交互界面。除了此,唤醒词还可以用于其他用途,比如执行简单的命令和控制动作。在一个棘手的解决方案中,它可以运行完整的自动语音识别(ASR,Automatic Speech Recognition)来执行热词检测。在这种情况下,设备将在自动语音识别转录中观察特定的触发词。转录中观察特定的触发词。 另外,当使用基于云的解决方案时,它也不会保护您的隐私。幸运的是,Snowboy 被创造出来,解决这些问题。
SnowBoy参考官网英文文档 http://docs.kitt.ai/snowboy/
Snowboy 具有以下的特性:
下面动手实践安装和使用snowboy,为我们的语音交互添加隐私保护功能。
https://s3-us-west-2.amazonaws.com/snowboy/snowboy-releases/rpi-arm-raspbian-8.0-1.2.0.tar.bz2
电脑解压下载的文件到snowboy,并上传至树莓派
确保树莓派安装好 ‘swig’,’sox’, ‘portaudio’, ‘atlas’。
安装指令如下:
sudo apt-get install swig3.0 python-pyaudio sox
pip install pyaudio
sudo apt-get install libatlas-base-dev
测试录音: rec temp.wav
测试没有问题后进入SnowBoy文件夹测试官方demo,测试时最好接上音频输出装置:
命令:
sudo python demo.py resources/snowboy.umdl
说出唤醒词 “snowboy” 会触发唤醒系统,树莓派的音频会输出ding ding ding声
二、离线语音唤醒控制LED灯
本小节我们采用snowboy实现一个智能家居的一个小项目,实现语音唤醒控制LED灯。
下面我们分析一下snowboy实现离线唤醒的代码:
#_*_ coding:UTF-8 _*_
# @author: zdl
# snowboy demo代码分析
# 使用snowboy离线唤醒实现控制LED灯
# reference: http://docs.kitt.ai/snowboy/#my-trained-model-works-well-on-laptops-but-not-on-pi-s
# 导入SDK包
import snowboydecoder
import sys
import signal
interrupted = False
def signal_handler(signal, frame):
global interrupted
interrupted = True
def interrupt_callback():
global interrupted
return interrupted
# 判断命令行执行指令是否传入唤醒词模型,无则退出程序
if len(sys.argv) == 1:
print("Error: need to specify model name")
print("Usage: python demo.py your.model")
sys.exit(-1)
# 唤醒词模型为输入的参数,这里可以进行修改
#model = sys.argv[1]
model = 'resources/snowboy.umdl' # 修改model,指定其文件名
# capture SIGINT signal, e.g., Ctrl+C
signal.signal(signal.SIGINT, signal_handler)
# 唤醒词检测函数,调整sensitivity参数可修改唤醒词检测的准确性
detector = snowboydecoder.HotwordDetector(model, sensitivity=0.5)
print('Listening... Press Ctrl+C to exit')
# main loop
# 回调函数 detected_callback=snowboydecoder.play_audio_file
# 修改回调函数可实现我们想要的功能
detector.start(detected_callback=snowboydecoder.play_audio_file,
interrupt_check=interrupt_callback,
sleep_time=0.03)
# 释放资源
detector.terminate()
结合demo函数的分析,实现属于自己的语音唤醒平台,我们只需要修改三个参数:
1、修改model model = ‘resources/snowboy.umdl’ # 修改model,指定model文件名
2、修改热词检测灵敏度,detector = snowboydecoder.HotwordDetector(model, sensitivity=0.5) # 修改sensitivity的值
3、修改回调函数 detected_callback= own_callbacks
下面实现离线唤醒触发点亮LED灯:这里我们依然采用snowboy官方的唤醒词模型snowboy.umdl,只是修改回调函数,程序如下:
1、定义own_callback
def own_callback():
LED.lighton() # 点亮LED灯
2、修改detected_callback
detected_callback = own_callback # 注意回调函数后面不在加括号
三、语音控制及语音机器人
结合语音识别和离线语音唤醒的知识,实现一个语音唤醒和语音控制的综合性实验控制LED灯的开关,本实验的LED灯不是220V家用的,如果需要扩展,添加一个继电器即可。下面我们需要将语音唤醒和语音识别结合起来,并采用我们自己个性唤醒词。上一节探讨过使用语音唤醒实现LED灯的控制,我们只是简单的修改了回调函数就实现了功能。那么如何实现语音唤醒和语音识别的结合呢?下面可以分析一下。
语音唤醒的流程如下图:
有了这个图是不是比较直观,我们把语音识别放在回调函数中即可实现语音唤醒和语音识别的功能,snowboy和语音识别都是采用pyaudio录音,如果同时使用会出现设备冲突,所以在使用语音识别之前需要关闭snowboy功能,语音识别完毕打开snowboy功能即可。所以回调函数的编写就比较清晰,程序流程图如下:
结合上述的流程图,可以很清晰的实现语音交互控制,所以我们基于上面的流程图实现一个语音交互机器人,可以实现简单的语音对话,语音控制,天气查询等功能。下面附上主程序的源码:
#_*_ coding:UTF-8 _*_
# @author: zdl
# 实现离线语音唤醒和语音识别,实现一些语音交互控制
# 导入包
import snowboydecoder
import sys
import signal
import record_monitor as recordMonitor # pyaudio语音监测程序
interrupted = False
def signal_handler(signal, frame):
global interrupted
interrupted = True
def interrupt_callback():
global interrupted
return interrupted
# 回调函数,语音识别在这里实现
def callbacks():
global detector
# 语音唤醒后,提示ding两声
snowboydecoder.play_audio_file()
snowboydecoder.play_audio_file()
# 关闭snowboy功能
detector.terminate()
# 开启语音识别
recordMonitor.monitor()
# 打开snowboy功能
wake_up() # wake_up —> monitor —> wake_up 递归调用
# 热词唤醒
def wake_up():
global detector
model = 'snowboy.pmdl' # 唤醒词为 SnowBoy
# capture SIGINT signal, e.g., Ctrl+C
signal.signal(signal.SIGINT, signal_handler)
# 唤醒词检测函数,调整sensitivity参数可修改唤醒词检测的准确性
detector = snowboydecoder.HotwordDetector(model, sensitivity=0.5)
print('Listening... please say wake-up word:SnowBoy')
# main loop
# 回调函数 detected_callback=snowboydecoder.play_audio_file
# 修改回调函数可实现我们想要的功能
detector.start(detected_callback=callbacks, # 自定义回调函数
interrupt_check=interrupt_callback,
sleep_time=0.03)
# 释放资源
detector.terminate()
if __name__ == '__main__':
wake_up()
# 关闭snowboy功能
detector.terminate()
# 开启语音识别
recordMonitor.monitor()
# 打开snowboy功能
wake_up() # wake_up —> monitor —> wake_up 递归调用
这几句代码实现了重复语音唤醒的功能,snowBoy和语音识别都采用pyaudio实现录音,一起使用时会抛出IO异常,所以需要先关闭snowboy功能然后开启语音识别功能,语音识别完毕需要释放pyaudio,然后开启snowboy功能。语音识别和语音控制的都封装在monitor()函数中。