1. 程式人生 > >樹莓派系列二(語音識別)

樹莓派系列二(語音識別)

樹莓派的基本概念和安裝系統在系列文章一中介紹了.這篇準備介紹一下語音識別.

一直想研究一下語音識別,用來做家庭物聯網的控制入口,未來也許就是這樣,訊飛的叮咚音響可以連線京東的物聯平臺,蘋果的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控制了.當然以後還是想上自己的語音識別的.

先把關係整理一下:

  1. nodejs是一個命令列下的javascript執行環境。
  2. npm是nodejs的外掛社群,裡面有無數的好東西和不好的東西,因為是不需要稽核的。
  3. homebridge是npm社群上的外掛之一,可以虛擬出一個HomeKit網關出來,但並不負責任何裝置的適配。
  4. 其它裝置要想使用homebridge和HomeKit互通,就要寫一個homebridge的外掛,現在這種外掛也有上百個了
  5. 做homebridge-aquara,Aquara是做小米多功能閘道器的深圳綠米聯創的自有品牌,最近出的牆壁開關和空調伴侶都是這個品牌的

最後具體的步驟參見小米bbs

http://bbs.xiaomi.cn/t-13198850