基于树莓派的“复读机”制作-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 9255|回复: 6

[项目] 基于树莓派的“复读机”制作

[复制链接]
发表于 2019-4-27 14:23 | 显示全部楼层 |阅读模式
前段时间接到个项目需要用到语音识别,语音识别就目前而言,无非就是本地和在线识别两种。随着信息时代的到来,云端服务器以及机器学习也在逐步代替传统的本地识别,这样就极大的提高了语音识别的速度和准确性。

本项目说是一个比赛项目,其实本人更觉得像是一个教程贴。在我查阅了谷歌和百度后以及百度AI开放平台后,我发现想从网上直接找到一个能够先录音再识别的现成程序是满困难的,大多数都是独立的部分,对于一个想制作这个项目的新手而言确实是一个比较头疼的地方。好了废话不多说,直接开始。

首先在制作项目前,我首先需要确认开发平台和方式。其实云端识别做起来很简单,你只需要根据云端服务器的要求上传你想识别的文件,然后再接受处理返回的数据即可完成功能,这样就可以更多的关注项目本身逻辑而不是项目的中的某一个功能。
既然说到是云端,那么我肯定得选一个设备能够联网才行,比如最近很火的ESP32或者ESP8266或者Arduino或者其他单片机加WiFi模块都行,总之得联网。那么这个是一个大前提,还有一个大前提就是,你选择的设备能否较好采集语音信号。语音信号其实是一段模拟量啦,但是根据香农的采样定律,如果你想不失真的恢复模拟信号,那么你的采样频率应该不小于模拟信号频谱中最高频率的2倍。这样一句话其实就是限制了一些平台,比如你想通过Arduino采集(这里指的是使用Arduino封装的语言,比如analogRead)的话,基本都是失败的,采样频率肯定不够,但是如果你用AVR C写的话,说不定就够了。当然你也可以用ESP32走I2S连接外部音频设备去采集。但是我就选择了一个比较偷懒的平台加开发方式,Python加树莓派。

那么首先先要去注册一个有关百度AI的账号来使用这个功能,这里我附上网址就不详细说明了
百度AI开放平台

注册完成后需要创建一个应用是有关百度AI语音部分的,附图是我已经创建好了的,这时候他会给你三个东西,AppID,API Key,Secret Key,这三个东西很关键,请注意,也不要给别人使用
语音API.png 语音KEY.png

OK,到现在为止,云端的准备部分结束了,现在我们需要配置一下树莓派的部分,首先树莓派的音频采集我并没有使用网上比较常见的USB话筒,那玩意灵敏度太低了,必须把嘴巴贴到话筒旁边才有效果,我尝试过修改增益,也不行。就在我一筹莫展之际,我突然发现了Seeed有关于树莓派使用的麦克风矩阵,如图所示。
respeaker.png
效果那真是大大滴棒,噢,这里有打广告的嫌疑。

然后有关于这个麦克风矩阵的安装我也不详细做说明了,在Seeed的WiKi上有,我还是附送网址
Respeaker WiKi

主要讲一下语音识别 & 合成的程序和思路

首先既然是基于百度的云平台,那我们就一定要多关注他的开发指南
百度语音识别
根据SDK,这里的几点非常关键,他首先告诉了我们应该上传不大于60秒的完整录音文件进行识别,然后对录音文件的码率,格式等做了规定。
SDK注意事项.png

那么既然要录音,我们就得先用Python录一段声音,这里我采用的是Pyaudio模块进行录音,首先我们需要安装,以下两个分别是Python2和Python3的,我使用的是Python3,根据你使用的Python版本进行安装。
游客,如果您要查看本帖隐藏内容请回复


CHUNK = 1024     # 缓冲区大小
FORMAT = pyaudio.paInt16     # 录音的位深
CHANNELS = 1     # 声道
RATE = 16000     # 采样率
RECORD_SECONDS = 5     # 录音时间
WAVE_OUTPUT_FILENAME = "output.wav"     # 录音输出的文件名

# 初始化
p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

print("* recording")

# 将缓冲区内的数据读出来
frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
        data = stream.read(CHUNK)
        frames.append(data)

print("* done recording")

# 停止
stream.stop_stream()
stream.close()
p.terminate()

# 将读出来的数据保存为wav文件
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()[/mw_shl_code]

这样去运行程序,你会发现在和程序同一目录下,会生成一个叫output.wav的文件,可以自己尝试播放一下看看是不是刚刚自己的胡言乱语,播放可以用下面这个命令
[mw_shl_code=bash,false]sudo mpg123 output.wav[/mw_shl_code]

录音完成了,项目完成了50%了,然后接下来做语音识别,同样的,还是去看刚刚的SDK说明,文档中写了我们需要安装一个python的模块,同样还是有Python2和3之间的区别,我用的是3
[mw_shl_code=bash,true]pip install baidu-aip
pip3 install baidu-aip[/mw_shl_code]

完成后,我们根据SDK的要求和给的Example尝试下
[mw_shl_code=python,true]from aip import AipSpeech

APP_ID = ""
API_KEY = ""
SECRET_KEY = ""

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

def get_file_content(filePath):
        with open(filePath, 'rb') as fp:
                return fp.read()

res = dict( client.asr(get_file_content('output.wav'), 'wav', 16000, {
    'dev_pid': 1537,
}) )

print(res)[/mw_shl_code]

这里首先需要把我刚刚说的那三个重要的参数换成你自己的,然后保证output.wav的文件存在。
这里有几个可选的参数,在SDK文档中有说明,比如这个dev_pid,就可以修改识别方式
sdk参数.png dev_pid参数.png

如果一切正常的话,我们已经可以在打印出来的数据里面看到了我们刚刚说的话。那么到这里整个项目就已经完成了百分之七八十。

最后我们做语音合成,语音合成其实和语音识别很像,也是参考SDK文档
语音合成SDK说明

最后我附上完整的程序
[mw_shl_code=python,true]# -*- coding: UTF-8 -*-

import pyaudio
import wave
from aip import AipSpeech
import os

CHUNK = 1024     # 缓冲区大小
FORMAT = pyaudio.paInt16     # 录音的位深
CHANNELS = 1     # 声道
RATE = 16000     # 采样率
RECORD_SECONDS = 5     # 录音时间
WAVE_OUTPUT_FILENAME = "output.wav"     # 录音输出的文件名

# 初始化
p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

print("* recording")

# 将缓冲区内的数据读出来
frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
        data = stream.read(CHUNK)
        frames.append(data)

print("* done recording")

# 停止
stream.stop_stream()
stream.close()
p.terminate()

# 将读出来的数据保存为wav文件
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()

APP_ID = "你的APP_ID"
API_KEY = "你的API_KEY"
SECRET_KEY = "你的SECRET_KEY"

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

# 打开文件
def get_file_content(filePath):
        with open(filePath, 'rb') as fp:
                return fp.read()

# 语音识别
res = dict( client.asr(get_file_content('output.wav'), 'wav', 16000, {
    'dev_pid': 1537,
}) )

# 判断是否有数据
if res["err_no"] == 0:
        outPutText = res["result"][0]
        print(outPutText)
else :
        outPutText = "错误啦!"

# 语音合成
result = client.synthesis(outPutText, 'zh', 1, {
    'vol': 5, 'per': 4,
})

# 生成mp3文件
if not isinstance(result, dict):
        with open('auido.mp3', 'wb') as f:
                f.write(result)

# 播放
os.system("sudo mpg123 auido.mp3")

# 删除临时文件
os.remove('output.wav')
os.remove('auido.mp3')
print("done")[/mw_shl_code]
发表于 2019-5-5 14:04 | 显示全部楼层
不加上这一句玩玩么:
[mw_shl_code=python,true]outPutText = outPutText.replace("吗", "").replace("?", "。").replace("你", "我")

C:\>py
Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> "你有智能吗?".replace("吗", "").replace("?", "。").replace("你", "我")
'我有智能。'
>>> "你是智能的吗?".replace("吗", "").replace("?", "。").replace("你", "我")
'我是智能的。'
>>> "你能对话吗?".replace("吗", "").replace("?", "。").replace("你", "我")
'我能对话。'
>>> "人工智能会胜利吗?".replace("吗", "").replace("?", "。").replace("你", "我")
'人工智能会胜利。'
>>>[/mw_shl_code]
 楼主| 发表于 2019-7-17 10:19 | 显示全部楼层
seesea 发表于 2019-5-5 14:04
不加上这一句玩玩么:
[mw_shl_code=python,true]outPutText = outPutText.replace("吗", "").replace("?" ...

我会加的哈哈哈哈哈
发表于 2019-7-17 10:21 | 显示全部楼层
PPeach 发表于 2019-7-17 10:19
我会加的哈哈哈哈哈

发表于 2019-11-26 16:02 | 显示全部楼层
桃子老师V5
发表于 2020-10-26 20:06 | 显示全部楼层
好厉害,我也试试
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 02:37 , Processed in 0.141036 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表