最近用树莓派实现了一个能和人对话的机器人,简要介绍一下。
树莓派(Raspberry Pi)是世界上最流行的微型电脑主板,是开源硬件的领导产品,它为学生计算机编程教育而设计,只有信用卡大小,且价格低廉。支持linux(debian)等操作系统。最重要的是资料完善,社区活跃。
我用的是树莓派B+版本,基本配置是博通BCM2836处理器,4核900M主频,1G RAM。
我的目标是做成一个和人对话的机器人,这就需要机器人有输入设备和输出设备。输入设备是麦克风,输出可以是HDMI、耳机或音响,我这里用了音响。下面是我的树莓派照片。4个USB接口分别连了无线网卡、无线键盘、麦克风、音响供电。
我们可以把机器人的对话分成三个部分:听、思考、说。
“听”,是把人说的话记录下来,并转换成文字。
“思考”,就是根据不同的输入给出不同的输出。比如,对方说“现在时间”,你就可以回答“现在是北京时间xx点xx分”。
“说”,是把文字转换成语音,并播放出来。
这三个部分涉及到大量语音识别、语音合成、人工智能等技术,这些都是要花大量时间精力研究的,好在有些公司已经开放了接口给客户使用。这里,我选择了百度的API。下面分别说明这三个部分的实现。
“听”
首先是把人说的话录制下来,我使用了arecord工具。命令如下:
-
arecord -D "plughw:1" -f S16_LE -r 16000 test.wav
其中,-D参数后接录制设备,连接麦克风后,树莓派上有2个设备:内部设备和外部usb设备,plughw:1代表使用外部设备。-f表示录制的格式,-r表示声音采样频率。由于后面提到的百度语音识别对音频文件格式是有要求的,我们需要录制成符合要求的格式。另外,在这里我没有指定录制的时间,它会一直录制下去,直到用户按下ctrl-c。录制后的音频文件保存为test.wav。
接下来,我们要把音频转换成文字,即语音识别(asr),百度的语音开放平台提供了免费的服务,并支持REST API
文档见:
流程基本就是获取token,把需要识别的语音信息、语音数据、token等发送给百度的语音识别服务器,就能获取到对应的文字。因为服务器支持REST API,我们可以用任何语言来实现客户端的代码,这里使用的是python
-
# coding: utf-8
-
-
import urllib.request
-
import json
-
import base64
-
import sys
-
-
def get_access_token():
-
url = ""
-
grant_type = "client_credentials"
-
client_id = "xxxxxxxxxxxxxxxxxx"
-
client_secret = "xxxxxxxxxxxxxxxxxxxxxx"
-
-
url = url + "?" + "grant_type=" + grant_type + "&" + "client_id=" + client_id + "&" + "client_secret=" + client_secret
-
-
resp = urllib.request.urlopen(url).read()
-
data = json.loads(resp.decode("utf-8"))
-
return data["access_token"]
-
-
-
def baidu_asr(data, id, token):
-
speech_data = base64.b64encode(data).decode("utf-8")
-
speech_length = len(data)
-
-
post_data = {
-
"format" : "wav",
-
"rate" : 16000,
-
"channel" : 1,
-
"cuid" : id,
-
"token" : token,
-
"speech" : speech_data,
-
"len" : speech_length
-
}
-
-
url = ""
-
json_data = json.dumps(post_data).encode("utf-8")
-
json_length = len(json_data)
-
#print(json_data)
-
-
req = urllib.request.Request(url, data = json_data)
-
req.add_header("Content-Type", "application/json")
-
req.add_header("Content-Length", json_length)
-
-
print("asr start request\n")
-
resp = urllib.request.urlopen(req)
-
print("asr finish request\n")
-
resp = resp.read()
-
resp_data = json.loads(resp.decode("utf-8"))
-
if resp_data["err_no"] == 0:
-
return resp_data["result"]
-
else:
-
print(resp_data)
-
return None
-
-
def asr_main(filename):
-
f = open(filename, "rb")
-
audio_data = f.read()
-
f.close()
-
-
#token = get_access_token()
-
token = "xxxxxxxxxxxxxxxxxx"
-
uuid = "xxxx"
-
resp = baidu_asr(audio_data, uuid, token)
-
print(resp[0])
-
return resp[0]
“思考”
这里我使用了百度api store的图灵机器人。其文档见:
它的使用非常简单,这里不再赘述,代码如下:
-
import urllib.request
-
import sys
-
import json
-
-
def robot_main(words):
-
url = ""
-
-
key = "879a6cb3afb84dbf4fc84a1df2ab7319"
-
userid = "1000"
-
-
words = urllib.parse.quote(words)
-
url = url + "key=" + key + "&info=" + words + "&userid=" + userid
-
-
req = urllib.request.Request(url)
-
req.add_header("apikey", "xxxxxxxxxxxxxxxxxxxxxxxxxx")
-
-
print("robot start request")
-
resp = urllib.request.urlopen(req)
-
print("robot stop request")
-
content = resp.read()
-
if content:
-
data = json.loads(content.decode("utf-8"))
-
print(data["text"])
-
return data["text"]
-
else:
-
return None
“说”
先需要把文字转换成语音,即语音合成(tts)。然后把声音播放出来。
百度的语音开放平台提供了tts的接口,并可配置男女声、语调、语速、音量。服务器返回mp3格式的音频数据。我们把数据以二进制方式写入文件中。
详见
代码如下:
-
# coding: utf-8
-
-
import urllib.request
-
import json
-
import sys
-
-
def baidu_tts_by_post(data, id, token):
-
post_data = {
-
"tex" : data,
-
"lan" : "zh",
-
"ctp" : 1,
-
"cuid" : id,
-
"tok" : token,
-
}
-
-
url = ""
-
post_data = urllib.parse.urlencode(post_data).encode('utf-8')
-
#print(post_data)
-
req = urllib.request.Request(url, data = post_data)
-
-
print("tts start request")
-
resp = urllib.request.urlopen(req)
-
print("tts finish request")
-
resp = resp.read()
-
return resp
-
-
def tts_main(filename, words):
-
token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-
text = urllib.parse.quote(words)
-
uuid = "xxxx"
-
resp = baidu_tts_by_post(text, uuid, token)
-
-
f = open("test.mp3", "wb")
-
f.write(resp)
-
f.close()
得到音频文件后,可以使用mpg123播放器播放。
整合
最后,把这三个部分组合起来。
可以先把python相关的代码整合成main.py,如下:
-
import asr
-
import tts
-
import robot
-
-
words = asr.asr_main("test.wav")
-
new_words = robot.robot_main(words)
-
tts.tts_main("test.mp3", new_words)
再使用脚本,调用相关工具:
-
#! /bin/bash
-
arecord -D "plughw:1" -f S16_LE -r 16000 test.wav
-
python3 main.py
-
mpg123 test.mp3
好了,现在你可以和机器人对话了。运行脚本,对着麦克风说句话,然后按ctrl-c,机器人就会回你话了。
阅读(21302) | 评论(3) | 转发(1) |