入手树莓派也有两年有余了,其实有很多有趣的想法,比如智能小车,智能感知,智能捕捉等等,也买了不少传感器件,组装小车的配件都买了,买组件的激情到是很高,但缺少了去实现动力(是懒吧),也就一直尘封着,偶尔翻出来见见光之后就又再次封装了起来!
偶尔的一次看到了 百度语音-永久免费智能语音开放平台 感觉挻有趣的,于是决定搞起,至于动力,也许看过 树莓派之 RGB LED 跑马灯 就会明白,就不在累述,也是分享中的其中一个示例,此示例整体来说实现相对比较容易,百度语音也已为 Python 提供了在线访问的 RestApi SDK,所以需要我们自己来实现的内容相对还是比较少的。同时小米也推出了自己的 水滴平台 [水滴平台为可以落地的小米全生态硬件产品提供语音服务,使用它可以为硬件设备提供功能,使用户能够以更直观的方式使用语音与设备进行交互。] 我也算是个米粉,这里就不多说了,有兴趣的同学可以了解一下 ^_^ 。
软件工程师的工作不是写程序, 而是合理使用工具解决问题,对此个人是比较认同的,术业有专攻,我们只需专注于做自己想做的一块,其余的就由专业的人去完成。于 Python 而言,其提供了很强大类库供我们去使用以及去定制化自己需要的!
说了这么多,先让我们了解一下此次示例使用的元件 树莓派、USB 声卡、百度语音 API、开发语言是 Python (由于没有 USB 声卡,只好在笔记本上进行了演示,查看资料说树莓派端对 pyaudio 并不兼容,可以用 arecord 进行录音,目前为止还未在树莓派上做测试,当前也就只有按照 Win10 测试过程来讲了)。

首先需要配置 百度语音 SDK 类库,执行 sudo pip install baidu-aip ,具体使用可以查看官方 在线语音识别 Python SDK 文档 ;执行 sudo apt-get install python-wave* 安装 wave 类库,执行 sudo pip install pyaudio 安装 pyaudio 类库 (Windows系统f需要使用 pip 执行),相关环境安装好后,就可以编写代码啦。
本示例分为语音识别和语音合成以及本地录音功能,先了解一下文件目录结构:
1 2 3 4 5
| |——test.py # 测试文件 |——speech # 语音 API 包目录 | |——__init__.py # 语音 API 导出类 | |——rpi_record.py # 本地录音 API | |——rpi_speech.py # 百度语音识别、语音合成功能封装
|
来看一下 rpi_speech.py 文件,下面代码中的常量APP_ID 在百度云控制台中创建,常量 API_KEY 与 SECRET_KEY 是在创建完毕应用后,系统分配给用户的,均为字符串,用于标识用户,为访问做签名验证,可在 AI 服务控制台中的 应用列表 中查看,如果还没有应用则需要先创建新应用,具体示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| """ 百度语音功能封装 """ import sys from aip import AipSpeech APP_ID = '你的 App ID' API_KEY = '你的 Api Key' SECRET_KEY = '你的 Secret Key' def speech(file_path): """ 语音识别 --- *file_path 音频路径*
原始语音的录音格式目前只支持评测 8k/16k 采样率 16bit 位深的单声道语音 压缩格式支持:pcm(不压缩)、wav、amr 系统支持语言种类:中文(zh)、粤语(ct)、英文(en) """ print(file_path, "开始语音识别") file_stream = _get_file_content(file_path) result = speechs(file_stream) print("语音识别结束") return result def speechs(file_stream): """ 语音识别 --- *file_stream 音频流*
原始语音的录音格式目前只支持评测 8k/16k 采样率 16bit 位深的单声道语音 压缩格式支持:pcm(不压缩)、wav、amr 系统支持语言种类:中文(zh)、粤语(ct)、英文(en) """ """ 初始化AipSpeech对象 """ baiduAipSpeech = AipSpeech(APP_ID, API_KEY, SECRET_KEY) result = baiduAipSpeech.asr(file_stream, "wav", 16000, {'lan': 'zh'}) return result def _get_file_content(file_path): """ 读取文件 """ with open(file_path, 'rb') as fp: return fp.read() def synthesis(text, file_path): """ 语音合成 ---- *text 需要合成语音的文字*
*file_path 保存语音合成文件路径* """ """ 初始化AipSpeech对象 """ baiduAipSpeech = AipSpeech(APP_ID, API_KEY, SECRET_KEY) print("开始语音合成") result = baiduAipSpeech.synthesis( text, 'zh', 1, {"spd": 5, "per": 4, "pit": 5}) print("语音合成结束") if not isinstance(result, dict): with open(file_path, 'wb') as f: f.write(result) print(file_path, ",语音合成保存成功") return True print(result, ",语音保存失败") return False
|
接下来是 rpi_record.py 文件,本地录音 API,本示例是使用 pyaudio 类库实现的,具体示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| """ 本地录音 API """ import base64 import datetime import os import sys import time import wave import numpy as np from pyaudio import PyAudio, paInt16 class RpiApiRecord(): """ 本地录音 API --- 原始语音的录音格式目前只支持评测 8k/16k 采样率 16bit 位深的单声道语音 压缩格式支持:pcm(不压缩)、wav、amr 系统支持语言种类:中文(zh)、粤语(ct)、英文(en) """ __NUM_SAMPLES = 2000 __SAMPLING_RATE = 16000 __LEVEL = 2000 def __init__(self, compressed_fromat=".wav"): """ *compressed_fromat 压缩格式支持:pcm(不压缩)、wav、amr* """ self.__compressed_fromat = compressed_fromat def __save_wave_file(self, file_patch, data): """将data中的数据保存到名为filename的WAV文件中""" wf = wave.open(file_patch, 'wb') wf.setnchannels(1) wf.setsampwidth(2) wf.setframerate(self.__SAMPLING_RATE) wf.writeframes(b"".join(data)) wf.close() def record(self, total_time=5): """ 开启声音输入 ---- *total_time 录音时长,单位秒,默认5秒*
返回结果:音频路径 """ save_buffer = [] first = True begin_time = 0 temp = 0 pa = PyAudio() stream = pa.open(format=paInt16, channels=1, rate=self.__SAMPLING_RATE, input=True, frames_per_buffer=self.__NUM_SAMPLES) while True: if first: string_auto_data = stream.read(self.__NUM_SAMPLES) audio_data = np.fromstring(string_auto_data, dtype=np.long) temp = np.max(audio_data) print(temp) if temp > self.__LEVEL and first: first = False temp = 0 print("检测到信号,五秒后开始") for i in range(1, 6, 1): print(i, "s") time.sleep(1) print('开始录音,计时', total_time, '秒') begin_time = time.time() if first: continue string_auto_data = stream.read(self.__NUM_SAMPLES) save_buffer.append(string_auto_data) time_count = time.time() - begin_time print("录音进行中,第", time_count, "s") if time_count > total_time: """ 压缩格式支持 pcm(不压缩)、wav、amr """ file_path = sys.path[0] + "\\" + datetime.datetime.now().strftime( "%Y-%m-%d_%H_%M_%S") + self.__compressed_fromat self.__save_wave_file(file_path, save_buffer) save_buffer = [] first = True print(file_path, "保存成功正在进行语音识别") return file_path
|
然后就是导出类文件 __init__.py,具体示例代码如下:
1 2 3 4 5 6 7 8 9 10
| """ 音频 API """ from .rpi_record import RpiApiRecord from .rpi_speech import speech, speechs __version__ = "0.0.0.1"
|
最后就是见证奇迹的时刻了,是不是有些激动,创建 test.py 文件,具体示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| import datetime import sys from speech import RpiApiRecord, rpi_speech def test_speech(): """ 百度语音识别功能 ---- *返回:语音识别的结果* """ file_path = sys.path[0] + "\\2017-09-22_09_37_45.wav" """调用百度语音识别接口,接收语音识别结果""" result = rpi_speech.speech(file_path) print(result) return result def test_speechs(): """ 测试本地录音,百度语音识别功能 ---- *返回:语音识别的结果* """ api_record = RpiApiRecord(".wav") """接收本地录音存放地址""" file_path = api_record.record(10) """调用百度语音识别接口,接收语音识别结果""" result = rpi_speech.speech(file_path) print(result) return result def test_synthesis(): """ 测试百度语音合成功能 ----
*返回:语音合成文件路径* """ """保存语音合成文件路径""" file_path = sys.path[0] + "\\" + datetime.datetime.now().strftime( "%Y-%m-%d_%H_%M_%S") + ".wav" result = rpi_speech.synthesis("你好吗,最近过得怎么样呢,嘿嘿!", file_path) print("语音合成结果:", result) return file_path def test_synthesis_speech(): """ 百度语音合成后,使用百度语音识别 """ file_path = test_synthesis() """调用百度语音识别接口,接收语音识别结果""" result = rpi_speech.speech(file_path) print(result) if __name__ == "__main__": print("进入 main 方法") test_speechs() print("离开 main 方法")
|
最基础的语音识别是不是感觉挻容易实现,其实可以在此基础上做些扩展,比如当前我想的,可以通过声音定位声源,测试声距,通过测定声源位置,启动并驱动电机,使摄像头捕捉人像并跟踪,同时摄像头也可以识别出人脸等,是不是很有画面感呢!再者还可以实现人机对话,声音感知等等,越想是不是越激动啦,过程还是需要自己动手去实现,乐趣更多的还是在实践的过程中 ^_^。
参考文档:
文中图片引用: