最近用樹(shù)莓派實(shí)現(xiàn)了一個(gè)能和人對(duì)話(huà)的機(jī)器人,,簡(jiǎn)要介紹一下。
樹(shù)莓派(Raspberry Pi)是世界上最流行的微型電腦主板,,是開(kāi)源硬件的領(lǐng)導(dǎo)產(chǎn)品,,它為學(xué)生計(jì)算機(jī)編程教育而設(shè)計(jì),只有信用卡大小,,且價(jià)格低廉,。支持linux(debian)等操作系統(tǒng)。最重要的是資料完善,,社區(qū)活躍,。
我用的是樹(shù)莓派B+版本,基本配置是博通BCM2836處理器,,4核900M主頻,,1G RAM。
我的目標(biāo)是做成一個(gè)和人對(duì)話(huà)的機(jī)器人,,這就需要機(jī)器人有輸入設(shè)備和輸出設(shè)備,。輸入設(shè)備是麥克風(fēng),輸出可以是HDMI,、耳機(jī)或音響,,我這里用了音響。下面是我的樹(shù)莓派照片,。4個(gè)USB接口分別連了無(wú)線(xiàn)網(wǎng)卡,、無(wú)線(xiàn)鍵盤(pán),、麥克風(fēng)、音響供電,。
![](http://image109.360doc.com/DownloadImg/2018/02/2615/125605948_1_20180226031512222.jpg)
我們可以把機(jī)器人的對(duì)話(huà)分成三個(gè)部分:聽(tīng),、思考、說(shuō),。
“聽(tīng)”,,是把人說(shuō)的話(huà)記錄下來(lái),并轉(zhuǎn)換成文字,。
“思考”,,就是根據(jù)不同的輸入給出不同的輸出。比如,,對(duì)方說(shuō)“現(xiàn)在時(shí)間”,,你就可以回答“現(xiàn)在是北京時(shí)間xx點(diǎn)xx分”。
“說(shuō)”,,是把文字轉(zhuǎn)換成語(yǔ)音,,并播放出來(lái)。
這三個(gè)部分涉及到大量語(yǔ)音識(shí)別,、語(yǔ)音合成,、人工智能等技術(shù),這些都是要花大量時(shí)間精力研究的,,好在有些公司已經(jīng)開(kāi)放了接口給客戶(hù)使用,。這里,我選擇了百度的API,。下面分別說(shuō)明這三個(gè)部分的實(shí)現(xiàn),。
“聽(tīng)”
首先是把人說(shuō)的話(huà)錄制下來(lái),我使用了arecord工具,。命令如下:
-
arecord -D "plughw:1" -f S16_LE -r 16000 test.wav
其中,,-D參數(shù)后接錄制設(shè)備,連接麥克風(fēng)后,,樹(shù)莓派上有2個(gè)設(shè)備:內(nèi)部設(shè)備和外部usb設(shè)備,,plughw:1代表使用外部設(shè)備。-f表示錄制的格式,,-r表示聲音采樣頻率,。由于后面提到的百度語(yǔ)音識(shí)別對(duì)音頻文件格式是有要求的,我們需要錄制成符合要求的格式,。另外,,在這里我沒(méi)有指定錄制的時(shí)間,它會(huì)一直錄制下去,,直到用戶(hù)按下ctrl-c,。錄制后的音頻文件保存為test.wav,。
接下來(lái),我們要把音頻轉(zhuǎn)換成文字,,即語(yǔ)音識(shí)別(asr),,百度的語(yǔ)音開(kāi)放平臺(tái)提供了免費(fèi)的服務(wù),并支持REST API
文檔見(jiàn): http://yuyin.baidu.com/docs/asr/57
流程基本就是獲取token,,把需要識(shí)別的語(yǔ)音信息,、語(yǔ)音數(shù)據(jù)、token等發(fā)送給百度的語(yǔ)音識(shí)別服務(wù)器,,就能獲取到對(duì)應(yīng)的文字。因?yàn)榉?wù)器支持REST API,,我們可以用任何語(yǔ)言來(lái)實(shí)現(xiàn)客戶(hù)端的代碼,,這里使用的是python
- # coding: utf-8
- import urllib.request
- import json
- import base64
- import sys
- def get_access_token():
- url = "https://openapi.baidu.com/oauth/2.0/token"
- grant_type = "client_credentials"
- client_id = "填寫(xiě)API Key?"
- client_secret = "填寫(xiě)Secret Key"
- 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 = "http://vop.baidu.com/server_api"
- 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 = "以上獲取token令牌可以保持下來(lái),不用一直獲取,,一個(gè)月有效"
- uuid = "填寫(xiě)AppID"
- resp = baidu_asr(audio_data, uuid, token)
- print(resp[0])
- return resp[0]
“思考”
這里我使用了圖靈機(jī)器人,。其文檔見(jiàn): http://www./help/h_cent_webapi.jhtml?nav=doc
它的使用非常簡(jiǎn)單,這里不再贅述,,代碼如下:
“說(shuō)”
先需要把文字轉(zhuǎn)換成語(yǔ)音,,即語(yǔ)音合成(tts)。然后把聲音播放出來(lái),。
百度的語(yǔ)音開(kāi)放平臺(tái)提供了tts的接口,,并可配置男女聲、語(yǔ)調(diào),、語(yǔ)速,、音量。服務(wù)器返回mp3格式的音頻數(shù)據(jù),。我們把數(shù)據(jù)以二進(jìn)制方式寫(xiě)入文件中,。
詳見(jiàn) http://yuyin.baidu.com/docs/tts/136
代碼如下: - # 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 = "http://tsn.baidu.com/text2audio"
- 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 = "填寫(xiě)AppID"
- resp = baidu_tts_by_post(text, uuid, token)
- f = open("test.mp3", "wb")
- f.write(resp)
- f.close()
得到音頻文件后,安裝mpg123: sudo apt-get install mpg123 ,,可以使用mpg123播放器播放,。
整合
最后,把這三個(gè)部分組合起來(lái),。
可以先把python相關(guān)的代碼整合成main.py,,如下:
- import asr
- import tts
- import robot
- words = asr.asr_main("test.wav")
- new_words = robot.Tuling(words)
- tts.tts_main("test.mp3", new_words)
再使用腳本,調(diào)用相關(guān)工具:
- #! /bin/bash
- arecord -D "plughw:1" -f S16_LE -r 16000 test.wav
- python3 main.py
- mpg123 test.mp3
好了,,現(xiàn)在你可以和機(jī)器人對(duì)話(huà)了,。運(yùn)行腳本,對(duì)著麥克風(fēng)說(shuō)句話(huà),,然后按ctrl-c,,機(jī)器人就會(huì)回你話(huà)了,。
|