樹莓派的基本概念和安裝系統在系列文章一中介紹了.這篇準備介紹一下語音識別.
一直想研究一下語音識別,用來做家庭物聯網的控制入口,未來也許就是這樣,訊飛的叮咚音響可以連接京東的物聯平臺,蘋果的homekit平臺,華爲的平臺暫時落後的有點多...
國內語音識別領域,我個人比較欣賞訊飛.識別效果業界領先,這幾年百度語音識別也在追趕,這次的研究讓我對百度的語音識別效果刮目相看,Google的在國內不用想了...
言歸正傳
1訊飛語音識別接口.
這次在樹莓派上實現語音識別控制家裏的設備(插座,燈 等等)的研究,第一反應是找訊飛的解決方案,結果訊飛收回的arm平臺開放的sdk,需要申請,有網友放出之前開放出來的sdk庫,但是仍然收每天識別次數的限制.反感搞這些事情(申請需要在論壇裏貼上研究過程,一個有效評論+1,申請後,三個星期發一次...),轉而研究一下百度的語音識別接口.這裏貼上網友的鏈接,裏面有早期訊飛開放的sdk下載鏈接,有興趣的可以去下載.
http://blog.csdn.net/yanghuan313/article/details/50992909
2百度語音識別接口.
百度語音開放平臺號稱永久免費,開發需要去註冊賬號,在平臺上創建應用,這裏不詳細敘述了,平臺操作比較簡單,可以參考下面的鏈接(不用下載sdk什麼的,這裏使用語音識別 REST API ,只需要拿到API KEY、Secret KEY.)
http://www.tuicool.com/articles/z2m6V3v
平臺支持android, ios.我們這裏使用的是語音識別 REST API接口,也就是http傳輸識別.
使用python開發,在ubuntu上先嚐試一下效果
需要安裝pycurl
sudo apt-get install libcurl4-gnutls-dev
pip install pycurl安裝好後,下面是python的代碼:
#encoding=utf-8
import wave
import urllib, urllib2, pycurl
import base64
import json
## get access token by api key & secret key
def get_token():
apiKey = "*******"
secretKey = "***************"
auth_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + apiKey + "&client_secret=" + secretKey
res = urllib2.urlopen(auth_url)
json_data = res.read()
return json.loads(json_data)['access_token']
def dump_res(buf):
print buf
## post audio to server
def use_cloud(token):
# fp = wave.open('test.pcm', 'rb')
fp = wave.open('cn_word.wav', 'rb')
# fp = wave.open('vad_1.wav', 'rb')
nf = fp.getnframes()
f_len = nf * 2
audio_data = fp.readframes(nf)
#mac addr
cuid = "123456"
srv_url = 'http://vop.baidu.com/server_api' + '?cuid=' + cuid + '&token=' + token
http_header = [
'Content-Type: audio/pcm; rate=16000',
# 'Content-Type: audio/pcm; rate=8000',
'Content-Length: %d' % f_len
]
c = pycurl.Curl()
c.setopt(pycurl.URL, str(srv_url)) #curl doesn't support unicode
#c.setopt(c.RETURNTRANSFER, 1)
c.setopt(c.HTTPHEADER, http_header) #must be list, not dict
c.setopt(c.POST, 1)
c.setopt(c.CONNECTTIMEOUT, 30)
c.setopt(c.TIMEOUT, 30)
c.setopt(c.WRITEFUNCTION, dump_res)
c.setopt(c.POSTFIELDS, audio_data)
c.setopt(c.POSTFIELDSIZE, f_len)
c.perform() #pycurl.perform() has no return val
if __name__ == "__main__":
token = get_token()
use_cloud(token)
識別結果如下:
這裏使用的是訊飛sdk中的wav文件,所以代碼中rate=16000.大家根據自己的音頻數據去修改.識別結果完全正確,可見音頻文件效果可以的話,百度語音識別接口完全可以用,不需要訊飛sdk.
這裏插一下題外的話,因爲考慮語音文件效果的問題,自然考慮到了麥克風硬件的優劣,這裏又再次提到訊飛,訊飛出了六麥環形陣列的麥克風陣列,鏈接:http://www.xfyun.cn/services/mic#list_wrap
不得不說,雖然沒有使用,但是我相信效果,只是好貴.......不考慮成本的可以試試.
說一下我最後選擇的方案,語音識別效果可以的情況下,要考慮喚醒的問題,喚醒方案有很多,上訊飛麥克風陣列的可以用喚醒詞,可以增加聲音傳感器,某寶上也就幾塊錢,但是聲音傳感器的閥值是我比較擔心的,我並不想語音識別被莫名的聲音喚醒,因爲這種傳感器只能檢測聲音的有無.大家根據自己的需求去增加特定的傳感器去喚醒語音識別就好.對於我來說,考慮到家裏有小米網關,插座等大量的小米設備,使用了樹莓派nodejs homebridge插件(虛擬出一個HomeKit網關),這樣就可以對接到蘋果手機的家庭應用,用蘋果的siri控制了.當然以後還是想上自己的語音識別的.
先把關係整理一下:
- nodejs是一個命令行下的javascript運行環境。
- npm是nodejs的插件社區,裏面有無數的好東西和不好的東西,因爲是不需要審覈的。
- homebridge是npm社區上的插件之一,可以虛擬出一個HomeKit網關出來,但並不負責任何設備的適配。
- 其它設備要想使用homebridge和HomeKit互通,就要寫一個homebridge的插件,現在這種插件也有上百個了
- 做homebridge-aquara,Aquara是做小米多功能網關的深圳綠米聯創的自有品牌,最近出的牆壁開關和空調伴侶都是這個品牌的
最後具體的步驟參見小米bbs
http://bbs.xiaomi.cn/t-13198850