图像降噪算法——维纳滤波
圖像降噪算法——維納濾波
- 圖像降噪算法——維納濾波
- 1. 基本原理
- 2. C++代碼實現
- 3. 結論
圖像降噪算法——維納濾波
維納濾波是在頻域中處理圖像的一種算法,是一種非常經典的圖像增強算法,不僅可以進行圖像降噪,還可以消除由于運動等原因帶來的圖像模糊。
1. 基本原理
在圖像拍攝過程中由于各種原因會造成圖像退化,圖像退化模型如下:g(x,y)=h(x,y)?f(x,y)+η(x,y)g(x, y)=h(x, y) \star f(x, y)+\eta(x, y)g(x,y)=h(x,y)?f(x,y)+η(x,y)其中,?\star?為卷積符號,f(x,y)f(x,y)f(x,y)為輸入圖像,g(x,y)g(x,y)g(x,y)為退化圖像,h(x,y)h(x,y)h(x,y)為退化函數,η(x,y)\eta(x,y)η(x,y)為加性噪聲,將上式進行傅里葉變換有:G(u,v)=H(u,v)F(u,v)+N(u,v)G(u, v)=H(u, v) F(u, v)+N(u, v)G(u,v)=H(u,v)F(u,v)+N(u,v)根據傅里葉變換的特性,空間域中的卷積相當于頻率域中的乘積。
(1) 如果不考慮退化函數,圖像退化模型就簡化為圖像噪聲模型:g(x,y)=f(x,y)+η(x,y)g(x, y)=f(x, y)+\eta(x, y)g(x,y)=f(x,y)+η(x,y)圖像增強問題成為單純的圖像去噪問題,可以通過空間域濾波等眾多方法解決。
(2) 如果不考慮加性噪聲,圖像退化模型就簡化為:g(x,y)=h(x,y)?f(x,y)g(x, y)=h(x, y) \star f(x, y)g(x,y)=h(x,y)?f(x,y)這種問題可以通過逆濾波解決,即通過傅里葉變化以及陣列除法即可獲得恢復后的圖像頻譜F^(u,v)\hat{F}(u, v)F^(u,v):F^(u,v)=G(u,v)H(u,v)\hat{F}(u, v)=\frac{G(u, v)}{H(u, v)}F^(u,v)=H(u,v)G(u,v)?那么H(u,v)H(u,v)H(u,v)怎么獲得呢?《數字圖像處理》中的方法有觀察估計、實驗估計和建模估計,例如建模估計中可以通過運動數學模型將退化函數構造為:H(u,v)=Tπ(ua+vb)sin?[π(ua+vb)]e?jπ(ua+vb)H(u, v)=\frac{T}{\pi(u a+v b)} \sin [\pi(u a+v b)] \mathrm{e}^{-\mathrm{j} \pi(u a+v b)}H(u,v)=π(ua+vb)T?sin[π(ua+vb)]e?jπ(ua+vb)
(3) 如果退化函數和加性噪聲都考慮,空域濾波器無法解決圖像退化問題,逆濾波效果因為噪聲的存在會變得非常差,這個時候就需要用到維納濾波,(維納濾波的推導寫在結論中)維納濾波公式如下:F^(u,v)=[1H(u,v)∣H(u,v)∣2∣H(u,v)∣2+Sη(u,v)/Sf(u,v)]G(u,v)\hat{F}(u, v)=\left[\frac{1}{H(u, v)} \frac{|H(u, v)|^{2}}{|H(u, v)|^{2}+S_{\eta}(u, v) / S_{f}(u, v)}\right] G(u, v)F^(u,v)=[H(u,v)1?∣H(u,v)∣2+Sη?(u,v)/Sf?(u,v)∣H(u,v)∣2?]G(u,v)其中,
Sη(u,v)=∣N(u,v)∣2S_{\eta}(u, v)=|N(u, v)|^{2}Sη?(u,v)=∣N(u,v)∣2為噪聲的功率譜,這個我們可以通過用戶輸入的方差構造一個噪聲圖像N(u,v)N(u, v)N(u,v)并計算功率譜;
Sf(u,v)=∣F(u,v)∣2S_{f}(u, v)=|F(u, v)|^{2}Sf?(u,v)=∣F(u,v)∣2為輸入圖像的功率譜,這里乍一看會覺得有點問題,我們如果知道輸入圖像還需要濾波干嘛?我們當然不知道輸入圖像,因為真實圖像的功率譜都是類似的,因此我們使用一個參考圖像計算功率譜即可,在下面的例子中就是使用的lena的灰度圖作為參考圖像;
下面的例子中我們還對退化函數進行了簡化,將退化函數置為1,因此維納濾波公式簡化為:F^(u,v)=[Sf(u,v)Sf(u,v)+Sη(u,v)]G(u,v)\hat{F}(u, v)=\left[\frac{S_{f}(u, v)}{S_{f}(u, v)+S_{\eta}(u, v)}\right] G(u, v)F^(u,v)=[Sf?(u,v)+Sη?(u,v)Sf?(u,v)?]G(u,v)
2. C++代碼實現
下面基于OpenCV實現維納濾波
Mat Denoise::WienerFilter(const Mat &src, const Mat &ref, int stddev) {//這些圖片是過程中會用到的,pad是原圖像0填充后的圖像,cpx是雙通道頻域圖,mag是頻域幅值圖,dst是濾波后的圖像Mat pad, cpx, dst;//獲取傅里葉變化最佳圖片尺寸,為2的指數int m = getOptimalDFTSize(src.rows);int n = getOptimalDFTSize(src.cols);//對原始圖片用0進行填充獲得最佳尺寸圖片copyMakeBorder(src, pad, 0, m-src.rows, 0, n-src.cols, BORDER_CONSTANT, Scalar::all(0));//獲得參考圖片頻譜Mat tmpR(pad.rows, pad.cols, CV_8U);resize(ref, tmpR, tmpR.size());Mat refSpectrum = GetSpectrum(tmpR);//獲得噪聲頻譜Mat tmpN(pad.rows, pad.cols, CV_32F);randn(tmpN, Scalar::all(0), Scalar::all(stddev));Mat noiseSpectrum = GetSpectrum(tmpN);//對src進行傅里葉變換Mat planes[] = {Mat_<float>(pad), Mat::zeros(pad.size(), CV_32F)};merge(planes, 2, cpx);dft(cpx, cpx);split(cpx, planes);//維納濾波因子Mat factor = refSpectrum / (refSpectrum + noiseSpectrum);multiply(planes[0], factor, planes[0]);multiply(planes[1], factor, planes[1]);//重新合并實部planes[0]和虛部planes[1]merge(planes, 2, cpx);//進行反傅里葉變換idft(cpx, dst, DFT_SCALE | DFT_REAL_OUTPUT);dst.convertTo(dst, CV_8UC1);return dst; }Mat Denoise::GetSpectrum(const Mat &src) {Mat dst, cpx;Mat planes[] = {Mat_<float>(src), Mat::zeros(src.size(), CV_32F)};merge(planes, 2, cpx);dft(cpx, cpx);split(cpx, planes);magnitude(planes[0], planes[1], dst);//頻譜就是頻域幅度圖的平方multiply(dst, dst, dst);return dst; }下面是運行結果:
首先是原圖:
添加上高斯噪聲后:
維納濾波的效果:
這個效果看上去有點神奇…
3. 結論
從濾波結果看,和頻域的高斯低通濾波是不同的,從頻域圖上看其實就是篩掉了不同的高頻信號
咱學知識就要學明白,這里我們把維納濾波的推導再過一遍:
維納濾波是采用優化的方法推導的的,優化的目標是是的估計圖像F^(u,v)\hat{F}(u,v)F^(u,v)和參考圖像F(u,v)F(u,v)F(u,v)(或者說是輸入圖像)頻譜的均方差最小,即:e=E{∣F(u,v)?F^(u,v)∣2}e=E\{|F(u,v)-\hat{F}(u,v)|^{2}\}e=E{∣F(u,v)?F^(u,v)∣2}將估計圖像頻譜進行替換:e=E{∣F(u,v)?X(u,v)G(u,v)∣2}=E{∣F(u,v)?X(u,v)[H(u,v)F(u,v)+N(u,v)]∣2}=E{∣[1?X(u,v)H(u,v)]F(u,v)?X(u,v)N(u,v)∣2}\begin{aligned} e &=E\{|F(u,v)-X(u,v) G(u,v)|^{2}\} \\ &=E\{|F(u,v)-X(u,v) [H(u, v) F(u, v)+N(u, v)]|^{2}\} \\ &=E\{|[1-X(u,v)H(u, v) ] F(u, v)-X(u,v)N(u, v)|^{2}\} \end{aligned}e?=E{∣F(u,v)?X(u,v)G(u,v)∣2}=E{∣F(u,v)?X(u,v)[H(u,v)F(u,v)+N(u,v)]∣2}=E{∣[1?X(u,v)H(u,v)]F(u,v)?X(u,v)N(u,v)∣2}?其中,X(u,v)X(u,v)X(u,v)就是我們需要估計的維納濾波系數,然后對平方進行展開e=[1?X(u,v)H(u,v)][1?X(u,v)H(u,v)]?×E{∣F(u,v)∣2}?[1?X(u,v)H(u,v)]X?(u,v)×E{F(u,v)N?(u,v)}?X(u,v)[1?X(u,v)H(u,v)]?×E{F(u,v)?N(u,v)}+X(u,v)X?(u,v)×E{∣N(u,v)∣2}\begin{aligned} e &=[1-X(u,v)H(u, v) ][1-X(u,v)H(u, v) ]^*×E\{|F(u,v)|^{2}\} \\ &-[1-X(u,v)H(u, v) ]X^*(u,v)× E\left\{F(u,v)N^*(u, v)\right\} \\ &-X(u,v)[1-X(u,v)H(u, v)]^*×E\left\{F(u,v)^*N(u, v)\right\} \\ &+X(u,v)X^*(u,v)×E\{|N(u, v)|^{2}\} \end{aligned}e?=[1?X(u,v)H(u,v)][1?X(u,v)H(u,v)]?×E{∣F(u,v)∣2}?[1?X(u,v)H(u,v)]X?(u,v)×E{F(u,v)N?(u,v)}?X(u,v)[1?X(u,v)H(u,v)]?×E{F(u,v)?N(u,v)}+X(u,v)X?(u,v)×E{∣N(u,v)∣2}?其中,由于噪聲和信號是獨立無關的,因此E{F(u,v)N(u,v)}=E{F(u,v)N(u,v)}=0E\left\{F(u,v)N(u, v)\right\}=E\left\{F(u,v) N(u, v)\right\}=0E{F(u,v)N(u,v)}=E{F(u,v)N(u,v)}=0定義如下功率譜有:Sf(u,v)=E{∣F(u,v)∣2}Sη(u,v)=E{∣N(u,v)∣2}\begin{array}{l} S_f(u,v)=E\{|F(u,v)|^{2}\} \\ S_\eta(u,v)=E\{|N(u, v)|^{2}\} \end{array}Sf?(u,v)=E{∣F(u,v)∣2}Sη?(u,v)=E{∣N(u,v)∣2}?于是有:e=[1?X(u,v)H(u,v)][1?X(u,v)H(u,v)]?Sf(u,v)+X(u,v)X?(u,v)(f)Sη(u,v)e=[1-X(u,v)H(u, v) ][1-X(u,v)H(u, v) ]^*S_f(u,v)+X(u,v)X^*(u,v)(f) S_\eta(u,v)e=[1?X(u,v)H(u,v)][1?X(u,v)H(u,v)]?Sf?(u,v)+X(u,v)X?(u,v)(f)Sη?(u,v)然后對X(u,v)X(u,v)X(u,v)求導d(e)dX(u,v)=X?(u,v)Sη(u,v)?X(u,v)[1?X(u,v)H(u,v))]?Sf(u,v)=0\frac{\mathrmze8trgl8bvbq(e)}{\mathrmze8trgl8bvbq X(u,v)}=X^{*}(u,v)S_\eta(u,v)-X(u,v)[1-X(u,v)H(u, v))]^{*}S_f(u,v)=0dX(u,v)d(e)?=X?(u,v)Sη?(u,v)?X(u,v)[1?X(u,v)H(u,v))]?Sf?(u,v)=0求解可獲得維納濾波公式。
有問題歡迎交流~
此外,這里我寫一個各種算法的總結目錄圖像降噪算法——圖像降噪算法總結,對圖像降噪算法感興趣的同學歡迎參考
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的图像降噪算法——维纳滤波的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图像降噪算法——高斯低通滤波
- 下一篇: 图像降噪算法——小波硬阈值滤波(上)