2015-09-26 30 views
0

我在Android上運行PocketSphinx(版本5prealpha)。我使用一個文件定義的關鍵字識別,通過下面的代碼片段規定(kwfile是關鍵字定義文件,並mRecognizer是SpeechRecognizer的一個實例):我可以修改PocketSphinx的關鍵字識別器「刷新率」嗎?

mRecognizer.addKeywordSearch(DESCRIPTOR, kwfile); 

總體而言,識別性能是相當不錯的,後已經優化了關鍵字閾值。然而,如果我在一個關鍵字話語和下一個關鍵詞話語之間等待任意時間量(5秒到幾分鐘),則識別性能會受到第二話語的影響。例如,我會說「關鍵字」,它會被識別。如果我等待不到5秒並再次說出「關鍵字」,則第二個話語可能會被識別(識別率超過95%)。但是,如果我等待15秒,識別率會急劇下降,不到50%。

我的假設是,當我第二次說關鍵字時,識別器處於刷新的中間 - 就是在Stop Recognition事件和Start Recognition事件之間,並且我的講話超出了該事件。這是我的logcat的典型視圖。注意,5秒後,識別器「刷新」。這大概每5秒發生一次。有時在「刷新」之間可能長達30秒,但通常是5秒左右。

09-26 07:11:06.800 20397-20397/...﹕ Start recognition "kwfile" 
09-26 07:11:06.815 20397-23642/...﹕ Starting decoding 
09-26 07:11:11.310 20397-20397/...﹕ Stop recognition 
09-26 07:11:11.315 20397-20397/...﹕ Start recognition "kwfile" 
09-26 07:11:11.360 20397-23645/...﹕ Starting decoding 
09-26 07:11:17.405 20397-20397/...﹕ Stop recognition 

所以,我的問題是:我能做些什麼來控制這個「刷新率」?這是否是由於我在執行RecognitionListener時出現了錯誤(請參閱下文,但請注意 - 我通常不會在話語之間獲得任何部分結果)。或者是否有PocketSphinx API調用,我不知道要設置此刷新率?或者,有什麼我可以改變在PocketSphinx源來改善這種行爲?

class VoiceListener implements RecognitionListener{ 

     private boolean isCommand = false; 

     @Override 
     public void onBeginningOfSpeech() { 
      Log.d(TAG,"Beginning of Speech"); 
      // do nothing 
     } 

     @Override 
     public void onEndOfSpeech() { 
      Log.d(TAG,"End of Speech"); 
      // do nothing 
     } 

     @Override 
     public void onPartialResult(Hypothesis arg0) { 
      if(arg0 != null){ 
       Log.d(TAG, "Partial results list: " + arg0.getHypstr()); 

       isCommand = false; 

       // handle recognition results for keywords 
       for(String command : this.getCurrentCommands()) { 
        if (arg0.getHypstr().contains(command)) { 
         this.onRecognition(arg0.getHypStr()); 
         isCommand = true; 
         mRecognizer.stop(); 
        } 
       } 

       // call stop, and let onResults() handle grammar results 
       if(arg0.getHypstr().contains(Command.STOP_WORD)) 
        mRecognizer.stop(); 

      } 
     } 

     @Override 
     public void onResult(Hypothesis results) { 

      String data; 
      if(results == null){ 
       data = null; 
      }else{ 
       data = results.getHypstr(); 
      } 

      Log.d(TAG,"Final results: " + data); 

      // handle grammar recognition results 
      if(!isCommand){ 
       this.onRecognition(data); 
      } 
      return; 

     } 

回答

0

沒有「刷新率」這樣的東西。識別準確性下降可能是因爲您在背景上有一些噪音,並且未正確濾除。您可以研究原始轉儲以調查沉默是否被視爲語音。您可以分享原始音頻轉儲以獲得有關此問題的幫助。

在你的代碼中有些東西不是很合理。如果您僅使用關鍵字定位,則無需像現在這樣停止並重新啓動onEndOfSpeech中的識別器,您可以跳過它。在發現模式中,您無需等待語音結束即可獲得結果,只需使用部分結果即可調用操作並重新啓動識別器。

+0

謝謝,尼古拉。實際上,我使用相同的RecognitionListener進行關鍵字和語法識別。所以,我可以取出stop()並查看是否改善了事情,或者我可以將它分解爲兩個SpeechRecognizer實例,一個用於關鍵字,另一個用於語法,然後有兩個單獨的監聽器,一個監聽器和停止另一個沒有它。無論如何,我會擺弄這些選項,並讓你知道它是如何運作的。如果我仍然遇到麻煩,我會添加一些音頻日誌。 –

+0

使用兩個實例並不是一個好主意。您需要使用單個實例然後切換搜索,但是如果當前搜索是關鍵字,您還應該跟蹤當前搜索並避免識別器停止。 Android演示以正確的方式執行,您可以按照它進行。 –

+0

好的。我知道了。我會用你的答案修改我的代碼塊。我將onEndOfSpeech()中的所有內容全部取出,並在onResult()中處理關鍵字onPartialResult()和語法。另外一個好處是,現在關鍵字識別的速度顯着提高,因爲它不必等待識別器調用onResult()。謝謝! –