双边滤波 MATLAB代码实现

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


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


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

代码如下:


    
    
  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. function resultI = BilateralFiltGray(I,d,sigma)
  17. [ m n ] = size (I) ;
  18. newI = ReflectEdge(I,d);
  19. resultI = zeros(m,n);
  20. width = 2*d+ 1;
  21. %Distance
  22. D = fspecial( ’gaussian’,[width,width],sigma( 1));
  23. S = zeros(width,width);%pix Similarity
  24. h = waitbar( 0, ’Applying bilateral filter…’);
  25. set(h, ’Name’, ’Bilateral Filter Progress’);
  26. for i= 1+d:m+d
  27. for j= 1+d:n+d
  28. pixValue = newI(i-d:i+d,j-d:j+d);
  29. subValue = pixValue-newI(i,j);
  30. S = exp(-subValue.^ 2/( 2*sigma( 2)^ 2));
  31. H = S.*D;
  32. resultI(i-d,j-d) = sum(pixValue(:).*H(:))/sum(H(:));
  33. end
  34. waitbar(i/m);
  35. end
  36. close(h);
  37. end
  38. function resultI = BilateralFiltColor(I,d,sigma)
  39. I = applycform (I,makecform(’srgb2lab’) );
  40. [m n ~] = size(I);
  41. newI = ReflectEdge(I,d);
  42. resultI = zeros(m,n, 3);
  43. width = 2*d+ 1;
  44. %Distance
  45. D = fspecial( ’gaussian’,[width,width],sigma( 1));
  46. % [X,Y] = meshgrid(-d:d,-d:d);
  47. % D = exp(-(X.^ 2+Y.^ 2)/( 2*sigma( 1)^ 2));
  48. S = zeros(width,width);%pix Similarity
  49. h = waitbar( 0, ’Applying bilateral filter…’);
  50. set(h, ’Name’, ’Bilateral Filter Progress’);
  51. sigma_r = 100*sigma( 2);
  52. for i= 1+d:m+d
  53. for j= 1+d:n+d
  54. pixValue = newI(i-d:i+d,j-d:j+d, 1: 3);
  55. %subValue = pixValue-repmat(newI(i,j, 1: 3),width,width);
  56. dL = pixValue(:,:, 1)-newI(i,j, 1);
  57. da = pixValue(:,:, 2)-newI(i,j, 2);
  58. db = pixValue(:,:, 3)-newI(i,j, 3);
  59. S = exp(-(dL.^ 2+da.^ 2+db.^ 2)/( 2*sigma_r^ 2));
  60. H = S.*D;
  61. H = H./sum(H(:));
  62. resultI(i-d,j-d, 1) = sum(sum(pixValue(:,:, 1).*H));
  63. resultI(i-d,j-d, 2) = sum(sum(pixValue(:,:, 2).*H));
  64. resultI(i-d,j-d, 3) = sum(sum(pixValue(:,:, 3).*H));
  65. end
  66. waitbar(i/m);
  67. end
  68. close(h);
  69. resultI = applycform(resultI,makecform( ’lab2srgb’));
  70. end

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


    
    
  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. if size(I, 3)== 1
  6. newI = ReflectEdgeGray(I,d);
  7. elseif size(I, 3)== 3
  8. newI = ReflectEdgeColor(I,d);
  9. else
  10. error( 'Incorrect image size')
  11. end
  12. end
  13. function newI = ReflectEdgeGray(I,d)
  14. [m n] = size(I);
  15. newI = zeros(m+ 2*d,n+ 2*d);
  16. %中间部分
  17. newI(d+ 1 :d+m,d+ 1 :d+n) = I;
  18. %上
  19. newI( 1 :d,d+ 1 :d+n) = I( d:- 1 : 1, :);
  20. %下
  21. newI( end- d: end,d+ 1 :d+n) = I( end:- 1 :end-d, :);
  22. %左
  23. newI( :, 1 :d) = newI( :, 2* d:- 1 :d+ 1);
  24. %右
  25. newI( :,m+d+ 1 :m+ 2*d) = newI( :,m+ d:- 1 :m+ 1);
  26. end
  27. function newI = ReflectEdgeColor(I,d)
  28. %扩展图像边界
  29. [m n ~] = size(I);
  30. newI = zeros(m+ 2*d,n+ 2*d, 3);
  31. %中间部分
  32. newI(d+ 1 :d+m,d+ 1 :d+n, 1 : 3) = I;
  33. %上
  34. newI( 1 :d,d+ 1 :d+n, 1 : 3) = I( d:- 1 : 1, :, 1 : 3);
  35. %下
  36. newI( end- d: end,d+ 1 :d+n, 1 : 3) = I( end:- 1 :end-d, :, 1 : 3);
  37. %左
  38. newI( :, 1 :d, 1 : 3) = newI( :, 2* d:- 1 :d+ 1, 1 : 3);
  39. %右
  40. newI( :,m+d+ 1 :m+ 2*d, 1 : 3) = newI( :,m+ d:- 1 :m+ 1, 1 : 3);
  41. end

测试用例:


    
    
  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. figure, imshow(resultI,[])
  13. title( '双边滤波后的图像')

结果:



Reference:

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



            </div>

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


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


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

代码如下:


  
  
  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. function resultI = BilateralFiltGray(I,d,sigma)
  17. [ m n ] = size (I) ;
  18. newI = ReflectEdge(I,d);
  19. resultI = zeros(m,n);
  20. width = 2*d+ 1;
  21. %Distance
  22. D = fspecial( ’gaussian’,[width,width],sigma( 1));
  23. S = zeros(width,width);%pix Similarity
  24. h = waitbar( 0, ’Applying bilateral filter…’);
  25. set(h, ’Name’, ’Bilateral Filter Progress’);
  26. for i= 1+d:m+d
  27. for j= 1+d:n+d
  28. pixValue = newI(i-d:i+d,j-d:j+d);
  29. subValue = pixValue-newI(i,j);
  30. S = exp(-subValue.^ 2/( 2*sigma( 2)^ 2));
  31. H = S.*D;
  32. resultI(i-d,j-d) = sum(pixValue(:).*H(:))/sum(H(:));
  33. end
  34. waitbar(i/m);
  35. end
  36. close(h);
  37. end
  38. function resultI = BilateralFiltColor(I,d,sigma)
  39. I = applycform (I,makecform(’srgb2lab’) );
  40. [m n ~] = size(I);
  41. newI = ReflectEdge(I,d);
  42. resultI = zeros(m,n, 3);
  43. width = 2*d+ 1;
  44. %Distance
  45. D = fspecial( ’gaussian’,[width,width],sigma( 1));
  46. % [X,Y] = meshgrid(-d:d,-d:d);
  47. % D = exp(-(X.^ 2+Y.^ 2)/( 2*sigma( 1)^ 2));
  48. S = zeros(width,width);%pix Similarity
  49. h = waitbar( 0, ’Applying bilateral filter…’);
  50. set(h, ’Name’, ’Bilateral Filter Progress’);
  51. sigma_r = 100*sigma( 2);
  52. for i= 1+d:m+d
  53. for j= 1+d:n+d
  54. pixValue = newI(i-d:i+d,j-d:j+d, 1: 3);
  55. %subValue = pixValue-repmat(newI(i,j, 1: 3),width,width);
  56. dL = pixValue(:,:, 1)-newI(i,j, 1);
  57. da = pixValue(:,:, 2)-newI(i,j, 2);
  58. db = pixValue(:,:, 3)-newI(i,j, 3);
  59. S = exp(-(dL.^ 2+da.^ 2+db.^ 2)/( 2*sigma_r^ 2));
  60. H = S.*D;
  61. H = H./sum(H(:));
  62. resultI(i-d,j-d, 1) = sum(sum(pixValue(:,:, 1).*H));
  63. resultI(i-d,j-d, 2) = sum(sum(pixValue(:,:, 2).*H));
  64. resultI(i-d,j-d, 3) = sum(sum(pixValue(:,:, 3).*H));
  65. end
  66. waitbar(i/m);
  67. end
  68. close(h);
  69. resultI = applycform(resultI,makecform( ’lab2srgb’));
  70. end

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


  
  
  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. if size(I, 3)== 1
  6. newI = ReflectEdgeGray(I,d);
  7. elseif size(I, 3)== 3
  8. newI = ReflectEdgeColor(I,d);
  9. else
  10. error( 'Incorrect image size')
  11. end
  12. end
  13. function newI = ReflectEdgeGray(I,d)
  14. [m n] = size(I);
  15. newI = zeros(m+ 2*d,n+ 2*d);
  16. %中间部分
  17. newI(d+ 1 :d+m,d+ 1 :d+n) = I;
  18. %上
  19. newI( 1 :d,d+ 1 :d+n) = I( d:- 1 : 1, :);
  20. %下
  21. newI( end- d: end,d+ 1 :d+n) = I( end:- 1 :end-d, :);
  22. %左
  23. newI( :, 1 :d) = newI( :, 2* d:- 1 :d+ 1);
  24. %右
  25. newI( :,m+d+ 1 :m+ 2*d) = newI( :,m+ d:- 1 :m+ 1);
  26. end
  27. function newI = ReflectEdgeColor(I,d)
  28. %扩展图像边界
  29. [m n ~] = size(I);
  30. newI = zeros(m+ 2*d,n+ 2*d, 3);
  31. %中间部分
  32. newI(d+ 1 :d+m,d+ 1 :d+n, 1 : 3) = I;
  33. %上
  34. newI( 1 :d,d+ 1 :d+n, 1 : 3) = I( d:- 1 : 1, :, 1 : 3);
  35. %下
  36. newI( end- d: end,d+ 1 :d+n, 1 : 3) = I( end:- 1 :end-d, :, 1 : 3);
  37. %左
  38. newI( :, 1 :d, 1 : 3) = newI( :, 2* d:- 1 :d+ 1, 1 : 3);
  39. %右
  40. newI( :,m+d+ 1 :m+ 2*d, 1 : 3) = newI( :,m+ d:- 1 :m+ 1, 1 : 3);
  41. end

测试用例:


  
  
  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. figure, imshow(resultI,[])
  13. title( '双边滤波后的图像')

结果:



Reference:

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



            </div>

猜你喜欢

转载自blog.csdn.net/weixin_41907390/article/details/81021848