痞子衡嵌入式:語音處理工具pzh-speech誕生記(5)- 語音識別實現(SpeechRecognition, PocketSphinx0.1.15)



  大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是語音處理工具pzh-py-speech誕生之語音識別實現

  語音識別是pzh-py-speech的核心功能,pzh-py-speech借助的是SpeechRecognition系統以及CMU Sphinx引擎來實現的語音識別功能,今天痞子衡為大家介紹語音識別在pzh-py-speech中是如何實現的。

一、SpeechRecognition系統簡介

  SpeechRecognition是一套基於python實現語音識別的系統,該系統的設計者為 Anthony Zhang (Uberi),該庫從2014年開始推出,一直持續更新至今,pzh-py-speech使用的是SpeechRecognition 3.8.1。
  SpeechRecognition系統的官方主頁如下:

  SpeechRecognition系統自身並沒有語音識別功能,其主要是調用第三方語音識別引擎來實現語音識別,SpeechRecognition支持的語音識別引擎非常多,有如下8種:

  • CMU Sphinx (works offline)
  • Google Speech Recognition
  • Google Cloud Speech API
  • Wit.ai
  • Microsoft Bing Voice Recognition
  • Houndify API
  • IBM Speech to Text
  • Snowboy Hotword Detection (works offline)

  不管是選用哪一種語音識別引擎,在SpeechRecognition里調用接口都是一致的,我們以實現音頻文件轉文字的示例代碼 audio_transcribe.py 為例了解SpeechRecognition的用法,截取audio_transcribe.py部分內容如下:

import speech_recognition as sr

# 指定要轉換的音頻源文件(english.wav)
from os import path
AUDIO_FILE = path.join(path.dirname(path.realpath(__file__)), "english.wav")

# 定義SpeechRecognition對象並獲取音頻源文件(english.wav)中的數據
r = sr.Recognizer()
with sr.AudioFile(AUDIO_FILE) as source:
    audio = r.record(source)  # read the entire audio file

# 使用CMU Sphinx引擎去識別音頻
try:
    print("Sphinx thinks you said " + r.recognize_sphinx(audio))
except sr.UnknownValueError:
    print("Sphinx could not understand audio")
except sr.RequestError as e:
    print("Sphinx error; {0}".format(e))

# 使用Microsoft Bing Voice Recognition引擎去識別音頻
BING_KEY = "INSERT BING API KEY HERE"  # Microsoft Bing Voice Recognition API keys 32-character lowercase hexadecimal strings
try:
    print("Microsoft Bing Voice Recognition thinks you said " + r.recognize_bing(audio, key=BING_KEY))
except sr.UnknownValueError:
    print("Microsoft Bing Voice Recognition could not understand audio")
except sr.RequestError as e:
print("Could not request results from Microsoft Bing Voice Recognition service; {0}".format(e))

# 使用其他引擎去識別音頻
# ... ...

  有木有覺得SpeechRecognition使用起來特別簡單?是的,這正是SpeechRecognition系統強大之處,更多示例可見 https://github.com/Uberi/speech_recognition/tree/master/examples

1.1 選用CMU Sphinx引擎

  前面痞子衡講了SpeechRecognition系統自身並沒有語音識別功能,因此我們需要為SpeechRecognition安裝一款語音識別引擎,痞子衡為JaysPySPEECH選用的是可離線工作的CMU Sphinx。
  CMU Sphinx是卡內基梅隆大學開發的一款開源語音識別引擎,該引擎可以離線工作,並且支持多語種(英語、中文、法語等)。CMU Sphinx引擎的官方主頁如下:

  由於JaysPySPEECH是基於Python環境開發的,因此我們不能直接用CMU Sphinx,那該怎么辦?別着急,Dmitry Prazdnichnov大牛為CMU Sphinx寫了Python封裝接口,即PocketSphinx,其官方主頁如下:

  我們在JaysPySPEECH誕生系列文章第一篇 環境搭建 里已經安裝了SpeechRecognition和PocketSphinx,痞子衡的安裝路徑為C:\tools_mcu\Python27\Lib\site-packages下的\speech_recognition與\pocketsphinx,安裝好這兩個包,引擎便選好了。

1.2 為PocketSphinx引擎增加中文語言包

  默認情況下,PocketSphinx僅支持US English語言的識別,在C:\tools_mcu\Python27\Lib\site-packages\speech_recognition\pocketsphinx-data目錄下僅能看到en-US文件夾,先來看一下這個文件夾里有什么:

\pocketsphinx-data\en-US
                        \acoustic-model                     --聲學模型
                                       \feat.params           --HMM模型的特征參數
                                       \mdef                  --模型定義文件
                                       \means                 --混合高斯模型的均值
                                       \mixture_weights       --混合權重
                                       \noisedict             --噪聲也就是非語音字典
                                       \sendump               --從聲學模型中獲取混合權重
                                       \transition_matrices   --HMM模型的狀態轉移矩陣
                                       \variances             --混合高斯模型的方差
						\language-model.lm.bin              --語言模型
						\pronounciation-dictionary.dict     --拼音字典

  看到這一堆文件是不是覺得有點難懂?這其實跟CMU Sphinx引擎的語音識別原理有關,此處我們暫且不深入了解,對我們調用API的應用來說只需要關於如何為CMU Sphinx增加其他語言包(比如中文包)。
  要想增加其他語言,首先得要有語言包數據,CMU Sphinx主頁提供了12種主流語言包的下載 https://sourceforge.net/projects/cmusphinx/files/Acoustic_and_Language_Models/,因為JaysPySPEECH需要支持中文識別,因此我們需要下載\Mandarin下面的三個文件:

\Mandarin
		 \zh_broadcastnews_16k_ptm256_8000.tar.bz2  --聲學模型
         \zh_broadcastnews_64000_utf8.DMP           --語言模型
		 \zh_broadcastnews_utf8.dic                 --拼音字典

  有了中文語言包數據,然后我們需要根據 Notes on using PocketSphinx 里指示的步驟操作,痞子衡整理如下:

  1. \speech_recognition\pocketsphinx-data目錄下創建zh-CN文件夾
  2. 將zh_broadcastnews_16k_ptm256_8000.tar.bz2解壓縮並里面所有文件放入\zh-CN\acoustic-model文件夾下
  3. 將zh_broadcastnews_utf8.dic重命名為pronounciation-dictionary.dict並放入\zh-CN文件夾下
  4. 借助SphinxBase工具將zh_broadcastnews_64000_utf8.DMP轉換成language-model.lm.bin並放入\zh-CN文件夾下

  關於第4步里提到的SphinxBase工具,我們需要從 https://github.com/cmusphinx/sphinxbase 里下載源碼,然后使用Visual Studio 2010(或以上)打開\sphinxbase\sphinxbase.sln工程Rebuild All后會在\sphinxbase\bin\Release\x64下看到生成了如下6個工具:

\\sphinxbase\bin\Release\x64
		                    \sphinx_cepview.exe
                            \sphinx_fe.exe
		                    \sphinx_jsgf2fsg.exe
		                    \sphinx_lm_convert.exe
		                    \sphinx_pitch.exe
		                    \sphinx_seg.exe

  我們主要使用sphinx_lm_convert.exe工具完成轉換工作生成language-model.lm.bin,具體命令如下:

PS C:\tools_mcu\sphinxbase\bin\Release\x64> .\sphinx_lm_convert.exe -i .\zh_broadcastnews_64000_utf8.DMP -o language-model.lm - ofmt arpa

Current configuration:
[NAME]          [DEFLT] [VALUE]
-case
-help           no      no
-i                      .\zh_broadcastnews_64000_utf8.DMP
-ifmt
-logbase        1.0001  1.000100e+00
-mmap           no      no
-o                      language-model.lm
-ofmt                   arpa

INFO: ngram_model_trie.c(354): Trying to read LM in trie binary format
INFO: ngram_model_trie.c(365): Header doesn't match
INFO: ngram_model_trie.c(177): Trying to read LM in arpa format
INFO: ngram_model_trie.c(70): No \data\ mark in LM file
INFO: ngram_model_trie.c(445): Trying to read LM in dmp format
INFO: ngram_model_trie.c(527): ngrams 1=63944, 2=16600781, 3=20708460
INFO: lm_trie.c(474): Training quantizer
INFO: lm_trie.c(482): Building LM trie

PS C:\tools_mcu\sphinxbase\bin\Release\x64> .\sphinx_lm_convert.exe -i .\language-model.lm -o language-model.lm.bin

Current configuration:
[NAME]          [DEFLT] [VALUE]
-case
-help           no      no
-i                      .\language-model.lm
-ifmt
-logbase        1.0001  1.000100e+00
-mmap           no      no
-o                      language-model.lm.bin
-ofmt

INFO: ngram_model_trie.c(354): Trying to read LM in trie binary format
INFO: ngram_model_trie.c(365): Header doesn't match
INFO: ngram_model_trie.c(177): Trying to read LM in arpa format
INFO: ngram_model_trie.c(193): LM of order 3
INFO: ngram_model_trie.c(195): #1-grams: 63944
INFO: ngram_model_trie.c(195): #2-grams: 16600781
INFO: ngram_model_trie.c(195): #3-grams: 20708460
INFO: lm_trie.c(474): Training quantizer
INFO: lm_trie.c(482): Building LM trie

二、pzh-py-speech語音識別實現

  語音識別代碼實現其實很簡單,直接調用speech_recognition里的API即可,目前僅實現了CMU Sphinx引擎,並且僅支持中英雙語識別。具體到pzh-py-speech上主要是實現GUI界面上"ASR"按鈕的回調函數,即audioSpeechRecognition(),如果用戶選定了配置參數(語言類型、ASR引擎類型),並點擊了"ASR"按鈕,此時便會觸發audioSpeechRecognition()的執行。代碼如下:

import speech_recognition

class mainWin(win.speech_win):

    def getLanguageSelection(self):
        languageType = self.m_choice_lang.GetString(self.m_choice_lang.GetSelection())
        if languageType == 'Mandarin Chinese':
            languageType = 'zh-CN'
            languageName = 'Chinese'
        else: # languageType == 'US English':
            languageType = 'en-US'
            languageName = 'English'
        return languageType, languageName

    def audioSpeechRecognition( self, event ):
        if os.path.isfile(self.wavPath):
		    # 創建speech_recognition語音識別對象asrObj
            asrObj = speech_recognition.Recognizer()
			# 獲取wav文件里的語音內容
            with speech_recognition.AudioFile(self.wavPath) as source:
                speechAudio = asrObj.record(source)
            self.m_textCtrl_asrttsText.Clear()
            # 獲取語音語言類型(English/Chinese)
            languageType, languageName = self.getLanguageSelection()
            engineType = self.m_choice_asrEngine.GetString(self.m_choice_asrEngine.GetSelection())
            if engineType == 'CMU Sphinx':
                try:
				    # 調用recognize_sphinx完成語音識別
                    speechText = asrObj.recognize_sphinx(speechAudio, language=languageType)
					# 語音識別結果顯示在asrttsText文本框內
                    self.m_textCtrl_asrttsText.write(speechText)
                    self.statusBar.SetStatusText("ASR Conversation Info: Successfully")
					# 語音識別結果寫入指定文件
                    fileName = self.m_textCtrl_asrFileName.GetLineText(0)
                    if fileName == '':
                        fileName = 'asr_untitled1.txt'
                    asrFilePath = os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))), 'conv', 'asr', fileName)
                    asrFileObj = open(asrFilePath, 'wb')
                    asrFileObj.write(speechText)
                    asrFileObj.close()
                except speech_recognition.UnknownValueError:
                    self.statusBar.SetStatusText("ASR Conversation Info: Sphinx could not understand audio")
                except speech_recognition.RequestError as e:
                    self.statusBar.SetStatusText("ASR Conversation Info: Sphinx error; {0}".format(e))
            else:
                self.statusBar.SetStatusText("ASR Conversation Info: Unavailable ASR Engine")

  至此,語音處理工具pzh-py-speech誕生之語音識別實現痞子衡便介紹完畢了,掌聲在哪里~~~

歡迎訂閱

文章會同時發布到我的 博客園主頁CSDN主頁微信公眾號 平台上。

微信搜索"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM