一個頻域語音降噪算法實現及改進方法
來自: http://www.cnblogs.com/icoolmedia/p/weiner_audio_ns.html
發現很多朋友想進入語音降噪處理的大門,卻很容易被鋪天蓋地的理論弄的很迷惑,不知道從哪里開始比較好。網上給出的參考文章大多干說理論,沒有代碼實現。很不利于學習。于是打算寫這篇語音降噪的文章,并給出相應的實現代碼方便交流和進一步的學習。
一. 算法核心思想與流程概要
本文給出的降噪算法的核心流程很簡單,主要是兩個步驟:
- 環境噪聲的假設與估計
- 頻域維納濾波降噪
這里簡單說一下語音相位問題,通常在語音的降噪算法中,是不考慮純凈語音的相位問題的,這是因為理論上可以證明:帶噪語音相位就是純凈語音相位的最優估計!
二. 環境噪聲估計
首先我們假設環境噪聲為隨機平穩加性噪聲、且與語音信號不相關。要注意這個假設對我們很重要,要記住這個算法的前提條件。這里介紹的噪聲估計算法叫做連續譜最小值跟蹤,資料出處為“語音增強-理論與實踐”一書中第九章中的一部分內容。此算法利用了帶噪語音信號在單個頻帶的功率通常會衰減到噪聲的功率水平。即使在語音活動期間也是如此。
算法主要分為兩個步驟:
- 對各頻點帶噪語音功率譜進行平滑處理。短時平滑方式為:
這里, 為平滑后的第k幀、
頻點的語音信號功率譜,
為平滑因子(通常取值為:
)。
2.對各頻點帶噪語音功率最小值進行非線性跟蹤。
If
else
end
這里,算法中的非線性跟蹤會連續對噪聲功率進行估計,這主要是由于上式中的第二項實現了一個一階差分運算,是在離散情況下對求導的一種近似。當帶噪語音功率 增加時,導數值也會增加,因此差分值
為正,當帶噪語音功率下降的時候,導數為負,噪聲估計減小。算法唯一要注意的是:當語音譜上出現很窄的峰值時,可能會導致在語音活動期音對噪聲的過估計,進而可能抑制語音。
三. 頻域維納濾波
使用維納濾波進行語音降噪的過程,其實是把降噪過程視為一個線性時不變系統,當帶噪語音通過這個系統時,在均方誤差最小化準則下,使得系統的輸出與期望的純凈語音信號最接近的過程。系統我們用下面的卷積過程來表示:
其中y(n)為輸入信號, 為輸出信號,如果我們轉換到頻域,表示為:
,則頻率
處的估計誤差為:
在頻域使其均方誤差 最小化:
這里 為輸入信號的功率譜,
是輸入信號y(n)與期望信號d(n)的互功率譜,為了得到最優的濾波器
,我們對均方誤差
求關于
的復導數,并令其等于0,可得:
由于 ,求解
,得到維納濾波的通用形式:
再由于我們假設噪聲為加性噪聲,且與語音信號不相關,可得:
將上面兩個式子代入維納濾波器的通用形式,得到頻域維納濾波器:
其中 為頻率
處的先驗SNR。下面的算法實現中將會用到這個結論。當然,如果想使用平方根維納濾波器,也可以對
再進行一次開方,這個就不再多說了。
四. 可能的改進方法
總的說來,這是一個降噪算法的小實現,可以改進的地方真的是太多了:
l 結合對先驗信噪比與后驗信噪比的調整算法(如:判決引導法)
l 結合語音存在的概率進行調整
l 使用超幾何增益,而不是維納增益
l 結合盲信號處理與陣列方向信息
這里不再一一列舉,實現代碼請到音視頻算法討論QQ群(374737122)中自行下載(TestNs),歡迎就其它改進方法一起討論!
</div>