双边滤波Matlab实现<The Bilateral Filter>

原文:http://blog.csdn.net/lifeitengup/article/details/8902326#comments

双边滤波与一般的高斯滤波的不同就是:双边滤波既利用了位置信息<or 几何信息——高斯滤波只用了位置信息>又利用了像素信息来定义滤波窗口的权重。


像素值越接近,权重越大。双边滤波会去除图像的细节信息,又能保持边界。


对于彩色图像,像素值的接近与否不能使用RGB空间值,双边滤波的原始文献建议使用CIE颜色空间。

代码如下:

[plain]  view plain  copy
  1. function resultI = BilateralFilt2(I,d,sigma)  
  2. %%%  
  3. %Author:LiFeiteng  
  4. %Version:1.0——灰色图像  Time:2013/05/01  
  5. %Version:1.1——灰色/彩色图像  Time:2013/05/02  2013/05/05  
  6. %d 半窗口宽度  
  7. I = double(I);  
  8. if size(I,3)==1  
  9.     resultI = BilateralFiltGray(I,d,sigma);  
  10. elseif size(I,3)==3  
  11.     resultI = BilateralFiltColor(I,d,sigma);  
  12. else   
  13.     error('Incorrect image size')      
  14. end  
  15. end  
  16.   
  17. function resultI = BilateralFiltGray(I,d,sigma)  
  18.   
  19. [m n] = size(I);  
  20. newI = ReflectEdge(I,d);  
  21. resultI = zeros(m,n);  
  22. width = 2*d+1;  
  23. %Distance  
  24. D = fspecial('gaussian',[width,width],sigma(1));  
  25. S = zeros(width,width);%pix Similarity  
  26. h = waitbar(0,'Applying bilateral filter...');  
  27. set(h,'Name','Bilateral Filter Progress');  
  28. for i=1+d:m+d  
  29.     for j=1+d:n+d  
  30.         pixValue = newI(i-d:i+d,j-d:j+d);  
  31.         subValue = pixValue-newI(i,j);  
  32.         S = exp(-subValue.^2/(2*sigma(2)^2));  
  33.         H = S.*D;  
  34.         resultI(i-d,j-d) = sum(pixValue(:).*H(:))/sum(H(:));   
  35.     end  
  36.     waitbar(i/m);  
  37. end  
  38. close(h);  
  39. end  
  40.   
  41. function resultI = BilateralFiltColor(I,d,sigma)  
  42. I = applycform(I,makecform('srgb2lab'));  
  43. [m n ~] = size(I);  
  44. newI = ReflectEdge(I,d);  
  45. resultI = zeros(m,n,3);  
  46. width = 2*d+1;  
  47. %Distance  
  48. D = fspecial('gaussian',[width,width],sigma(1));  
  49. % [X,Y] = meshgrid(-d:d,-d:d);  
  50. % D = exp(-(X.^2+Y.^2)/(2*sigma(1)^2));  
  51. S = zeros(width,width);%pix Similarity  
  52. h = waitbar(0,'Applying bilateral filter...');  
  53. set(h,'Name','Bilateral Filter Progress');  
  54. sigma_r = 100*sigma(2);  
  55. for i=1+d:m+d  
  56.     for j=1+d:n+d  
  57.         pixValue = newI(i-d:i+d,j-d:j+d,1:3);  
  58.         %subValue = pixValue-repmat(newI(i,j,1:3),width,width);  
  59.         dL = pixValue(:,:,1)-newI(i,j,1);  
  60.         da = pixValue(:,:,2)-newI(i,j,2);  
  61.         db = pixValue(:,:,3)-newI(i,j,3);  
  62.         S = exp(-(dL.^2+da.^2+db.^2)/(2*sigma_r^2));  
  63.         H = S.*D;  
  64.         H = H./sum(H(:));  
  65.         resultI(i-d,j-d,1) = sum(sum(pixValue(:,:,1).*H));   
  66.         resultI(i-d,j-d,2) = sum(sum(pixValue(:,:,2).*H));      
  67.         resultI(i-d,j-d,3) = sum(sum(pixValue(:,:,3).*H));      
  68.     end  
  69.     waitbar(i/m);  
  70. end  
  71. close(h);  
  72. resultI = applycform(resultI,makecform('lab2srgb'));  
  73. end  

其中newI = ReflectEdge(I,d); %对称地扩展边界,在原始图像I的边界处镜像映射像素值 

[plain]  view plain  copy
  1. function newI = ReflectEdge(I,d)  
  2. %Version:1.0——灰色图像  Time:2013/05/01  
  3. %Version:1.1——灰色/彩色图像  Time:2013/05/02  
  4. %考虑到实用性,决定不添加更多的边界处理选择,统一使用:reflect across edge  
  5.   
  6. if size(I,3)==1  
  7.     newI = ReflectEdgeGray(I,d);  
  8. elseif size(I,3)==3  
  9.     newI = ReflectEdgeColor(I,d);  
  10. else   
  11.     error('Incorrect image size')      
  12. end  
  13. end  
  14.   
  15. function newI = ReflectEdgeGray(I,d)  
  16. [m n] = size(I);  
  17. newI = zeros(m+2*d,n+2*d);  
  18. %中间部分  
  19. newI(d+1:d+m,d+1:d+n) = I;  
  20. %上  
  21. newI(1:d,d+1:d+n) = I(d:-1:1,:);  
  22. %下  
  23. newI(end-d:end,d+1:d+n) = I(end:-1:end-d,:);  
  24. %左  
  25. newI(:,1:d) = newI(:,2*d:-1:d+1);  
  26. %右  
  27. newI(:,n+d+1:n+2*d) = newI(:,n+d:-1:n+1);  
  28. end  
  29.   
  30. function newI = ReflectEdgeColor(I,d)  
  31. %扩展图像边界  
  32. [m n ~] = size(I);  
  33. newI = zeros(m+2*d,n+2*d,3);  
  34. %中间部分  
  35. newI(d+1:d+m,d+1:d+n,1:3) = I;  
  36. %上  
  37. newI(1:d,d+1:d+n,1:3) = I(d:-1:1,:,1:3);  
  38. %下  
  39. newI(end-d:end,d+1:d+n,1:3) = I(end:-1:end-d,:,1:3);  
  40. %左  
  41. newI(:,1:d,1:3) = newI(:,2*d:-1:d+1,1:3);  
  42. %右  
  43. newI(:,n+d+1:n+2*d,1:3) = newI(:,n+d:-1:n+1,1:3);  
  44. end  

测试用例:

[plain]  view plain  copy
  1. img = imread('.\lena.tif');  
  2. %%img = imread('.\images\lena_gray.tif');  
  3. img = double(img)/255;  
  4. img = img+0.05*randn(size(img));  
  5. img(img<0) = 0; img(img>1) = 1;  
  6. %img = imnoise(img,'gaussian');  
  7. figure, imshow(img,[])  
  8. title('原始图像')  
  9. d = 6;  
  10. sigma = [3 0.1];  
  11. resultI = BilateralFilt2(double(img), d, sigma);  
  12.   
  13. figure, imshow(resultI,[])  
  14. title('双边滤波后的图像')  

结果:



Reference:

1.C Tomasi, R Manduchi.Bilateral Filtering for Gray and Color Images, - Computer Vision, 1998.

双边滤波与一般的高斯滤波的不同就是:双边滤波既利用了位置信息<or 几何信息——高斯滤波只用了位置信息>又利用了像素信息来定义滤波窗口的权重。


像素值越接近,权重越大。双边滤波会去除图像的细节信息,又能保持边界。


对于彩色图像,像素值的接近与否不能使用RGB空间值,双边滤波的原始文献建议使用CIE颜色空间。

代码如下:

[plain]  view plain  copy
  1. function resultI = BilateralFilt2(I,d,sigma)  
  2. %%%  
  3. %Author:LiFeiteng  
  4. %Version:1.0——灰色图像  Time:2013/05/01  
  5. %Version:1.1——灰色/彩色图像  Time:2013/05/02  2013/05/05  
  6. %d 半窗口宽度  
  7. I = double(I);  
  8. if size(I,3)==1  
  9.     resultI = BilateralFiltGray(I,d,sigma);  
  10. elseif size(I,3)==3  
  11.     resultI = BilateralFiltColor(I,d,sigma);  
  12. else   
  13.     error('Incorrect image size')      
  14. end  
  15. end  
  16.   
  17. function resultI = BilateralFiltGray(I,d,sigma)  
  18.   
  19. [m n] = size(I);  
  20. newI = ReflectEdge(I,d);  
  21. resultI = zeros(m,n);  
  22. width = 2*d+1;  
  23. %Distance  
  24. D = fspecial('gaussian',[width,width],sigma(1));  
  25. S = zeros(width,width);%pix Similarity  
  26. h = waitbar(0,'Applying bilateral filter...');  
  27. set(h,'Name','Bilateral Filter Progress');  
  28. for i=1+d:m+d  
  29.     for j=1+d:n+d  
  30.         pixValue = newI(i-d:i+d,j-d:j+d);  
  31.         subValue = pixValue-newI(i,j);  
  32.         S = exp(-subValue.^2/(2*sigma(2)^2));  
  33.         H = S.*D;  
  34.         resultI(i-d,j-d) = sum(pixValue(:).*H(:))/sum(H(:));   
  35.     end  
  36.     waitbar(i/m);  
  37. end  
  38. close(h);  
  39. end  
  40.   
  41. function resultI = BilateralFiltColor(I,d,sigma)  
  42. I = applycform(I,makecform('srgb2lab'));  
  43. [m n ~] = size(I);  
  44. newI = ReflectEdge(I,d);  
  45. resultI = zeros(m,n,3);  
  46. width = 2*d+1;  
  47. %Distance  
  48. D = fspecial('gaussian',[width,width],sigma(1));  
  49. % [X,Y] = meshgrid(-d:d,-d:d);  
  50. % D = exp(-(X.^2+Y.^2)/(2*sigma(1)^2));  
  51. S = zeros(width,width);%pix Similarity  
  52. h = waitbar(0,'Applying bilateral filter...');  
  53. set(h,'Name','Bilateral Filter Progress');  
  54. sigma_r = 100*sigma(2);  
  55. for i=1+d:m+d  
  56.     for j=1+d:n+d  
  57.         pixValue = newI(i-d:i+d,j-d:j+d,1:3);  
  58.         %subValue = pixValue-repmat(newI(i,j,1:3),width,width);  
  59.         dL = pixValue(:,:,1)-newI(i,j,1);  
  60.         da = pixValue(:,:,2)-newI(i,j,2);  
  61.         db = pixValue(:,:,3)-newI(i,j,3);  
  62.         S = exp(-(dL.^2+da.^2+db.^2)/(2*sigma_r^2));  
  63.         H = S.*D;  
  64.         H = H./sum(H(:));  
  65.         resultI(i-d,j-d,1) = sum(sum(pixValue(:,:,1).*H));   
  66.         resultI(i-d,j-d,2) = sum(sum(pixValue(:,:,2).*H));      
  67.         resultI(i-d,j-d,3) = sum(sum(pixValue(:,:,3).*H));      
  68.     end  
  69.     waitbar(i/m);  
  70. end  
  71. close(h);  
  72. resultI = applycform(resultI,makecform('lab2srgb'));  
  73. end  

其中newI = ReflectEdge(I,d); %对称地扩展边界,在原始图像I的边界处镜像映射像素值 

[plain]  view plain  copy
  1. function newI = ReflectEdge(I,d)  
  2. %Version:1.0——灰色图像  Time:2013/05/01  
  3. %Version:1.1——灰色/彩色图像  Time:2013/05/02  
  4. %考虑到实用性,决定不添加更多的边界处理选择,统一使用:reflect across edge  
  5.   
  6. if size(I,3)==1  
  7.     newI = ReflectEdgeGray(I,d);  
  8. elseif size(I,3)==3  
  9.     newI = ReflectEdgeColor(I,d);  
  10. else   
  11.     error('Incorrect image size')      
  12. end  
  13. end  
  14.   
  15. function newI = ReflectEdgeGray(I,d)  
  16. [m n] = size(I);  
  17. newI = zeros(m+2*d,n+2*d);  
  18. %中间部分  
  19. newI(d+1:d+m,d+1:d+n) = I;  
  20. %上  
  21. newI(1:d,d+1:d+n) = I(d:-1:1,:);  
  22. %下  
  23. newI(end-d:end,d+1:d+n) = I(end:-1:end-d,:);  
  24. %左  
  25. newI(:,1:d) = newI(:,2*d:-1:d+1);  
  26. %右  
  27. newI(:,m+d+1:m+2*d) = newI(:,m+d:-1:m+1);  
  28. end  
  29.   
  30. function newI = ReflectEdgeColor(I,d)  
  31. %扩展图像边界  
  32. [m n ~] = size(I);  
  33. newI = zeros(m+2*d,n+2*d,3);  
  34. %中间部分  
  35. newI(d+1:d+m,d+1:d+n,1:3) = I;  
  36. %上  
  37. newI(1:d,d+1:d+n,1:3) = I(d:-1:1,:,1:3);  
  38. %下  
  39. newI(end-d:end,d+1:d+n,1:3) = I(end:-1:end-d,:,1:3);  
  40. %左  
  41. newI(:,1:d,1:3) = newI(:,2*d:-1:d+1,1:3);  
  42. %右  
  43. newI(:,m+d+1:m+2*d,1:3) = newI(:,m+d:-1:m+1,1:3);  
  44. end  

测试用例:

[plain]  view plain  copy
  1. img = imread('.\lena.tif');  
  2. %%img = imread('.\images\lena_gray.tif');  
  3. img = double(img)/255;  
  4. img = img+0.05*randn(size(img));  
  5. img(img<0) = 0; img(img>1) = 1;  
  6. %img = imnoise(img,'gaussian');  
  7. figure, imshow(img,[])  
  8. title('原始图像')  
  9. d = 6;  
  10. sigma = [3 0.1];  
  11. resultI = BilateralFilt2(double(img), d, sigma);  
  12.   
  13. figure, imshow(resultI,[])  
  14. title('双边滤波后的图像')  

结果:



Reference:

1.C Tomasi, R Manduchi.Bilateral Filtering for Gray and Color Images, - Computer Vision, 1998.

双边滤波是一种可以同时考虑空间距离和像素值差异的滤波方法,可以在去除图像噪声的同时保留图像细节。下面是双边滤波Matlab代码实现: ```matlab function [output_image] = bilateral_filter(input_image, sigma_d, sigma_r) % 双边滤波函数 % input_image: 输入图像 % sigma_d: 空域滤波器的标准差 % sigma_r: 像素值差异滤波器的标准差 % 将输入图像转换为double类型 input_image = im2double(input_image); % 获取输入图像的大小 [M, N, ~] = size(input_image); % 初始化输出图像 output_image = zeros(M, N, 3); % 定义空域滤波器 [X, Y] = meshgrid(-ceil(3*sigma_d):ceil(3*sigma_d)); space_filter = exp(-(X.^2+Y.^2)/(2*sigma_d^2)); % 对于每个像素进行滤波 for i = 1:M for j = 1:N % 计算像素值差异滤波器 pixel_filter = exp(-((input_image(i,j,1)-input_image(:,:,1)).^2+... (input_image(i,j,2)-input_image(:,:,2)).^2+... (input_image(i,j,3)-input_image(:,:,3)).^2)/(2*sigma_r^2)); % 计算双边滤波bilateral_filter = space_filter .* pixel_filter; % 归一化 bilateral_filter = bilateral_filter / sum(bilateral_filter(:)); % 计算输出像素值 output_image(i,j,1) = sum(sum(input_image(:,:,1).*bilateral_filter)); output_image(i,j,2) = sum(sum(input_image(:,:,2).*bilateral_filter)); output_image(i,j,3) = sum(sum(input_image(:,:,3).*bilateral_filter)); end end % 将输出图像转换为uint8类型 output_image = uint8(output_image*255); ``` 使用方法: ```matlab input_image = imread('input_image.png'); sigma_d = 2; sigma_r = 0.1; output_image = bilateral_filter(input_image, sigma_d, sigma_r); imshow(output_image); ``` 其中,`input_image.png`为输入图像的文件名,`sigma_d`为空域滤波器的标准差,`sigma_r`为像素值差异滤波器的标准差。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值