【轉】--雙邊濾波及其matlab代碼


雙邊濾波及其matlab代碼

參考:
https://blog.csdn.net/MoFMan/article/details/77482794
https://www.jianshu.com/p/8d11e26c9665
代碼:https://blog.csdn.net/l_eop/article/details/81812277
高斯濾波:https://blog.csdn.net/nima1994/article/details/79776802

濾波

在介紹雙邊濾波以前,簡要介紹一下濾波的過程.就像下面的動圖所展示的,我們使用一個3×3的卷積核以步長為1對圖像進行遍歷,然后得到一幅新的經過濾波的圖像.
在這里插入圖片描述
其中每次濾波的時候只是在計算中心點的新的像素值.也就是說每次遍歷移動一步其實只是在利用鄰域(n×n)計算一個像素點的值,直到將圖像中所有的點都卷積一次.
在這里插入圖片描述
那么卷積的結果就是,在3×3的鄰域內,權重矩陣和圖像塊之間各對應位置相乘然后將這些乘積相加得到紅色中心點的新的像素值.
在這里插入圖片描述

雙邊濾波

雙邊濾波是一種非線性的方法,同時考慮到了圖像的空域信息和灰度相似性,以達到保邊去噪的目的.雙邊濾波通過空域矩陣和值域矩陣形成一個新的權重矩陣,其中空域矩陣用來模糊去噪;值域矩陣用來保護邊緣.
在介紹相關公式之前,我們定義(i,j)為中心點坐標,(k,l)為以(i,j)點為中心的鄰域S內的任意一點.
空域矩陣中點(k,l)到點(i,j)的空間距離定義為:d(i,j,k,l)=exp(ik)2+(jl)22σ2d(1)d(i,j,k,l)=exp-\frac{(i-k)^2+(j-l)^2}{2σ_{d}^2} (1)d(i,j,k,l)=exp2σd2(ik)2+(jl)2(1)
值得注意的一旦σdσ_{d}σd確定了,那么空域矩陣中各點的值是始終不變的.
而值域矩陣定義為:r(i,j,k,l)=expf(k,l)f(i,j)22σ2r(2)r(i,j,k,l)=exp-\frac{||f(k,l)-f(i,j)||^2}{2σ_{r}^2} (2)r(i,j,k,l)=exp2σr2f(k,l)f(i,j)2(2)
兩者相乘后,就會產生依賴於數據的雙邊濾波權重矩陣w(i,j,k,l):
w(i,j,k,l)=exp(ik)2+(jl)22σ2df(k,l)f(i,j)22σ2r(3)w(i,j,k,l)=exp-\frac{(i-k)^2+(j-l)^2}{2σ_{d}^2} -\frac {||f(k,l)-f(i,j)||^2}{2σ_{r}^2} (3)w(i,j,k,l)=exp2σd2(ik)2+(jl)22σr2f(k,l)f(i,j)2(3)
最后計算得到點(i,j)新的像素值g(i,j).
在這里插入圖片描述
d函數根據像素距離選擇權重,距離越近權重越大,這一點和方框濾波,高斯濾波方式相同.而r函數則是根據像素值的差異來分配權值.
在平坦區域,像素差異較小,對應值域權重r(i,j,k,l)接近於1,此時空域權重d(i,j,k,l)起主要作用,相當於直接對此平坦區域進行高斯模糊.需要注意的是空域核是始終不變的,而值域核卻因為區域的不同而不同.
邊緣的特點就是相距近的點像素值差異大.那么濾波的同時是希望保留邊緣的這種特性的.所以在邊緣區域,因為像素之間差異較大,即f(k,l)-f(i,j)之間差值大,此時值域核權重變小,導致此處總權重值w(i,j,k,l)下降(w=r*d),當前像素(i,j)受到大差異點的影響就越小,從而保持了邊緣的細節信息.

matlab代碼
雙邊濾波的實現代碼如下.

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% % 雙邊濾波的程序
% %
% %
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

clear;close all;
% 讀取圖像
filename = './rgb.png';
% filename = './gray.png';
img = imread(filename);

% 設置參數
r = 3; % 濾波半徑
a = 3; % 全局方差
b = 0.1; % 局部方差

[~,~,ch] = size(img);
% 判斷是灰度圖還是彩色圖像
if ch == 1
g = bfilt_gray(img,r,a,b);
else
g = bfilt_rgb(img,r,a,b);
end

% 顯示
figure;subplot(121);imshow(img);
subplot(122);imshow(g);

%% 灰度圖雙邊濾波
function res = bfilt_gray(img,r,a,b)
% f灰度圖;r濾波半徑 ;a全局方差;b局部方差
[x,y] = meshgrid(-r:r);

% 空域核 把中心點當做原點那么各點與中心點的距離就為(i-k)^2 +(j-l)^2 =k^2+l^2.
% 其中(i,j)是中心點坐標,(k,l)是鄰域各點坐標
w_spatial = exp(-( x.^2+y.^2 )/(2*a^2)); % 二維高斯函數為 G(x,y) = 1/(2πσ) * exp(-(x^2 + y^2)/2*σ^2)
img = im2double(img);

[m,n] = size(img);
f_temp = padarray(img,[r r],'symmetric'); % 邊緣填充之后的圖像
res = zeros(m,n);
count = 0; % 記錄有多少個點計算了

for i = r+1:m+r
for j = r+1:n+r

count = count +1;
temp = f_temp(i-r:i+r,j-r:j+r); % 一個局部塊的像素值

w_pixel = exp( -( temp- img(i-r,j-r) ).^2/(2*b^2)); % 值域核
w = w_spatial .* w_pixel;
s = temp.*w;

res(i-r,j-r) = sum(s(:)) / sum(w(:)); % 計算該點新的像素值
end

end
fprintf('count = %d \n', count);

end

%% 彩色圖雙邊濾波
% 彩色圖像每個通道單獨處理即可
function res = bfilt_rgb(img,r,a,b)
% f灰度圖;r濾波半徑;a全局方差;b局部方差

res = zeros(size(img)) ;
for ch = 1:3
res(:,:,ch) = bfilt_gray(img(:,:,ch),r,a,b);
end

end

 

 

% 有關兩個sigma參數如何確定的問題
% sigma_d 變大,圖像每個區域的權重基本都源於值域濾波的權重,
% 因此對於空間鄰域信息不是很敏感;sigma_r 變大,則不太考慮值域,權重多來自於空間距離,
% 因此近似於普通的高斯濾波,圖像的保邊性能下降。
% 因此如果像更多的去除平滑區域的噪聲,應該提高 sigma_d ,如果像保持邊緣,則應該減小 sigma_r 。
% 極端情況,如果 sigma_d 無窮大,相當於值域濾波;sigma_r 無窮大,相當於空域高斯濾波。

% 濾波半徑於sigma_d的關系 r =3*

% 對於彩色圖片,由於兩種顏色中可能有其他完全不同的顏色,
% 因此不像灰度圖那樣,僅僅是 blurred ,而是會產生 auras like 的奇怪的暈圈,
% 所以在雙邊濾波的過程中,將RGB轉換到 CIE-Lab 色彩空間,
% 這個空間與人的主管色彩辨識能力相關,因此可以改善這一缺陷。


免責聲明!

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



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