樹莓派系列二(語音識別)
樹莓派的基本概念和安裝系統在系列文章一中介紹了.這篇準備介紹一下語音識別.
一直想研究一下語音識別,用來做家庭物聯網的控制入口,未來也許就是這樣,訊飛的叮咚音響可以連線京東的物聯平臺,蘋果的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