图像降噪算法——高斯低通滤波
圖像降噪算法——高斯低通濾波
- 圖像降噪算法——高斯低通濾波
- 1. 基本原理
- 2. C++代碼實現
- 3. 結論
圖像降噪算法——高斯低通濾波
1. 基本原理
通過離散傅里葉變換對圖像進行濾波流程作非常簡單,就如下圖所示:
(1) 二維離散傅里葉變換的公式為:F(u,v)=∑x=0M?1∑y=0N?1f(x,y)e?j2π(ux/M+vy/N)F(u, v)=\sum_{x=0}^{M-1} \sum_{y=0}^{N-1} f(x, y) \mathrm{e}^{-\mathrm{j} 2 \pi(u x / M+v y / N)}F(u,v)=x=0∑M?1?y=0∑N?1?f(x,y)e?j2π(ux/M+vy/N)其中,xxx和yyy分別為原始圖像上的橫縱坐標,MMM和NNN為為原始圖像的高和寬,f(x,y)f(x,y)f(x,y)為原始圖像上坐標(x,y)(x,y)(x,y)處的灰度值,其中,根據歐拉公式:e?j2π(ux/M+vy/N)=cos(2π(uxM+vyN))?jsin(2π(uxM+vyN))\mathrm{e}^{-\mathrm{j} 2 \pi(u x / M+v y / N)}=cos(2 \pi(\frac{u x} {M}+\frac{v y}{N}))-jsin(2 \pi(\frac{u x} {M}+\frac{v y}{N}))e?j2π(ux/M+vy/N)=cos(2π(Mux?+Nvy?))?jsin(2π(Mux?+Nvy?))因此原始圖像通過二維離散傅里葉變換獲得的二維頻譜上每一個像素都是復數,在OpenCV中用Mat數據格式處理時,每個像素值都有兩個通道。
(2) 二維離散傅里葉反變換的公式為:f(x,y)=1MN∑u=0M?1∑v=0N?1F(u,v)ej2π(ux/M+vy/N)f(x, y)=\frac{1}{M N} \sum_{u=0}^{M-1} \sum_{v=0}^{N-1} F(u, v) \mathrm{e}^{\mathrm{j} 2 \pi(u x / M+v y / N)}f(x,y)=MN1?u=0∑M?1?v=0∑N?1?F(u,v)ej2π(ux/M+vy/N)其中,符號表示和上述二維離散傅里葉變換相同。
(3) 對二維頻譜的各種操作的具體方式:將二維頻譜與設計好的濾波模板進行乘積,為什么是乘積呢?
因為根據傅里葉變換的性質,頻率域中的乘積相當于空間域中的卷積,即f(x,y)?h(x,y)?F(u,v)H(u,v)f(x, y) \star h(x, y) \Leftrightarrow F(u, v) H(u, v)f(x,y)?h(x,y)?F(u,v)H(u,v),其中二維循環卷積公式如下f(x,y)?h(x,y)=∑m=0M?1∑n=0N?1f(m,n)h(x?m,y?n)f(x, y) \star h(x, y)=\sum_{m=0}^{M-1} \sum_{n=0}^{N-1} f(m, n) h(x-m, y-n)f(x,y)?h(x,y)=m=0∑M?1?n=0∑N?1?f(m,n)h(x?m,y?n)以高斯低通濾波為例,即H(u,v)=e?D2(u,v)/2σ2H(u, v)=\mathrm{e}^{-D^{2}(u, v) / 2 \sigma^{2}}H(u,v)=e?D2(u,v)/2σ2其中D(u,v)D(u,v)D(u,v)為二維頻譜上像素(u,v)(u,v)(u,v)距離中心的距離,其通過傅里葉反變換得到:h(x,y)=2πσe?2π2σ2D2(x,y)h(x,y)=\sqrt{2 \pi} \sigma \mathrm{e}^{-2 \pi^{2} \sigma^{2} D^{2}(x,y)}h(x,y)=2π?σe?2π2σ2D2(x,y)其中D(x,y)D(x,y)D(x,y)為空間域圖像上像素(x,y)(x,y)(x,y)距離中心的距離。可以發現空間域中同樣是一個高斯濾波器,兩者之間的關系是頻率中高斯低通濾波器越窄,說明其衰減的低頻越多,引起的模糊就越大,在空間域中就相當于使用了更大的模板來增加模糊。
2. C++代碼實現
下面是基于OpenCV實現的頻域的高斯低通濾波器
//高斯低通濾波器(頻域) Mat Denoise::GaussianLowPassFilter(const Mat &src, double sigma) {//這些圖片是過程中會用到的,pad是原圖像0填充后的圖像,cpx是雙通道頻域圖,mag是頻域幅值圖,dst是濾波后的圖像Mat pad, cpx, mag, 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 gaussian(pad.size(),CV_32FC2);for(int i = 0; i<m; i++){float* p = gaussian.ptr<float>(i);for(int j = 0; j<n; j++){double d = pow(i-m/2, 2) + pow(j-n/2, 2);p[2*j] = expf(-d/sigma/sigma/2.0);p[2*j+1] = expf(-d/sigma/sigma/2.0);}}//建立雙通道圖片,其中planes[0]填充原始圖片Mat planes[] = {Mat_<float>(pad), Mat::zeros(pad.size(), CV_32F)};merge(planes, 2, cpx);//進行傅里葉變換dft(cpx, cpx);//分離通道并進行象限變幻split(cpx, planes);planes[0] = ShiftQuadrant(planes[0]);planes[1] = ShiftQuadrant(planes[1]); // magnitude(planes[0], planes[1], mag); // mag += Scalar::all(1); // log(mag, mag); // normalize(mag, mag, 0, 1, CV_MINMAX); // imshow("mag1", mag);//進行濾波merge(planes, 2, cpx);multiply(cpx, gaussian, cpx);//分離通道并進行象限變幻split(cpx, planes);//計算幅值,并講幅值存儲再planes[0]中magnitude(planes[0], planes[1], mag); // mag += Scalar::all(1); // log(mag, mag); // normalize(mag, mag, 0, 1, CV_MINMAX); // imshow("mag2", mag);planes[0] = ShiftQuadrant(planes[0]);planes[1] = ShiftQuadrant(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::ShiftQuadrant(const Mat &src) {// 交換前// ×××××××××××××××××××××××// × q1 × q2 ×// × × ×// ×××××××××××××××××××××××// × q3 × q4 ×// × × ×// ×××××××××××××××××××××××// 交換后// ×××××××××××××××××××××××// × q4 × q3 ×// × × ×// ×××××××××××××××××××××××// × q2 × q1 ×// × × ×// ×××××××××××××××××××××××Mat dst = src.clone();int m = src.rows, n = src.cols;Mat q1(dst, Rect(0,0,n/2,m/2));Mat q2(dst, Rect(n/2,0,n/2,m/2));Mat q3(dst, Rect(0,m/2,n/2,m/2));Mat q4(dst, Rect(n/2,m/2,n/2,m/2));//交換象限Mat temp;q1.copyTo(temp);q4.copyTo(q1);temp.copyTo(q4);q2.copyTo(temp);q3.copyTo(q2);temp.copyTo(q3);return dst; }下面是運行結果:
首先,下面這是原圖:
添加上高斯噪聲后:
進行二維離散傅里葉變換獲得二維頻譜(下面顯示的幅值圖mag,僅僅是為了演示頻域濾波的過程,實際上用來操作的是兩通道的頻譜圖cpx):
對二維頻譜進行操作,乘以高斯低通濾波器:
最后通過二維離散傅里葉反變換獲得降噪圖像:
3. 結論
本文是直接上手二維離散傅里葉變換進行濾波,啥是離散傅里葉變換?怎么就變換了?不太熟悉的同學建議復習下《數字信號處理》或者到網上看一些大佬的博客,這里推薦幾篇:
1. 從菜鳥到完全學會二維傅立葉在圖像處理算法中的應用【老司機教你學傅立葉】
2. 為什么用圖像二維傅里葉變換的相位譜進行反變換,能夠大致得到原圖的形狀,而幅度譜則不行呢?
3. 十分簡明易懂的FFT(快速傅里葉變換)
4. 如果看了這篇文章你還不懂傅里葉變換,那就過來掐死我吧
本文介紹的二維離散傅里葉變換是最基本的形式,而實際應用中采用的肯定是快速傅里葉變換。
采用離散傅里葉進行濾波會有更直觀,但是由于空間域可以進行并行計算,因此實際濾波是還是更加傾向于空間域濾波。
暫時分享這么多,有問題歡迎交流~
此外,這里我寫一個各種算法的總結目錄圖像降噪算法——圖像降噪算法總結,對圖像降噪算法感興趣的同學歡迎參考
總結
以上是生活随笔為你收集整理的图像降噪算法——高斯低通滤波的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图像降噪算法——非局部均值降噪算法
- 下一篇: 图像降噪算法——维纳滤波