欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

双边滤波Matlab实现The Bilateral Filter

发布时间:2025/3/15 编程问答 29 豆豆
生活随笔 收集整理的这篇文章主要介绍了 双边滤波Matlab实现The Bilateral Filter 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

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

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


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


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

代码如下:

[plain] view plain copy
  • function resultI = BilateralFilt2(I,d,sigma)  
  • %%%  
  • %Author:LiFeiteng  
  • %Version:1.0——灰色图像  Time:2013/05/01  
  • %Version:1.1——灰色/彩色图像  Time:2013/05/02  2013/05/05  
  • %d 半窗口宽度  
  • I = double(I);  
  • if size(I,3)==1  
  •     resultI = BilateralFiltGray(I,d,sigma);  
  • elseif size(I,3)==3  
  •     resultI = BilateralFiltColor(I,d,sigma);  
  • else   
  •     error('Incorrect image size')      
  • end  
  • end  
  •   
  • function resultI = BilateralFiltGray(I,d,sigma)  
  •   
  • [m n] = size(I);  
  • newI = ReflectEdge(I,d);  
  • resultI = zeros(m,n);  
  • width = 2*d+1;  
  • %Distance  
  • D = fspecial('gaussian',[width,width],sigma(1));  
  • S = zeros(width,width);%pix Similarity  
  • h = waitbar(0,'Applying bilateral filter...');  
  • set(h,'Name','Bilateral Filter Progress');  
  • for i=1+d:m+d  
  •     for j=1+d:n+d  
  •         pixValue = newI(i-d:i+d,j-d:j+d);  
  •         subValue = pixValue-newI(i,j);  
  •         S = exp(-subValue.^2/(2*sigma(2)^2));  
  •         H = S.*D;  
  •         resultI(i-d,j-d) = sum(pixValue(:).*H(:))/sum(H(:));   
  •     end  
  •     waitbar(i/m);  
  • end  
  • close(h);  
  • end  
  •   
  • function resultI = BilateralFiltColor(I,d,sigma)  
  • I = applycform(I,makecform('srgb2lab'));  
  • [m n ~] = size(I);  
  • newI = ReflectEdge(I,d);  
  • resultI = zeros(m,n,3);  
  • width = 2*d+1;  
  • %Distance  
  • D = fspecial('gaussian',[width,width],sigma(1));  
  • % [X,Y] = meshgrid(-d:d,-d:d);  
  • % D = exp(-(X.^2+Y.^2)/(2*sigma(1)^2));  
  • S = zeros(width,width);%pix Similarity  
  • h = waitbar(0,'Applying bilateral filter...');  
  • set(h,'Name','Bilateral Filter Progress');  
  • sigma_r = 100*sigma(2);  
  • for i=1+d:m+d  
  •     for j=1+d:n+d  
  •         pixValue = newI(i-d:i+d,j-d:j+d,1:3);  
  •         %subValue = pixValue-repmat(newI(i,j,1:3),width,width);  
  •         dL = pixValue(:,:,1)-newI(i,j,1);  
  •         da = pixValue(:,:,2)-newI(i,j,2);  
  •         db = pixValue(:,:,3)-newI(i,j,3);  
  •         S = exp(-(dL.^2+da.^2+db.^2)/(2*sigma_r^2));  
  •         H = S.*D;  
  •         H = H./sum(H(:));  
  •         resultI(i-d,j-d,1) = sum(sum(pixValue(:,:,1).*H));   
  •         resultI(i-d,j-d,2) = sum(sum(pixValue(:,:,2).*H));      
  •         resultI(i-d,j-d,3) = sum(sum(pixValue(:,:,3).*H));      
  •     end  
  •     waitbar(i/m);  
  • end  
  • close(h);  
  • resultI = applycform(resultI,makecform('lab2srgb'));  
  • end  

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

    [plain] view plain copy
  • function newI = ReflectEdge(I,d)  
  • %Version:1.0——灰色图像  Time:2013/05/01  
  • %Version:1.1——灰色/彩色图像  Time:2013/05/02  
  • %考虑到实用性,决定不添加更多的边界处理选择,统一使用:reflect across edge  
  •   
  • if size(I,3)==1  
  •     newI = ReflectEdgeGray(I,d);  
  • elseif size(I,3)==3  
  •     newI = ReflectEdgeColor(I,d);  
  • else   
  •     error('Incorrect image size')      
  • end  
  • end  
  •   
  • function newI = ReflectEdgeGray(I,d)  
  • [m n] = size(I);  
  • newI = zeros(m+2*d,n+2*d);  
  • %中间部分  
  • newI(d+1:d+m,d+1:d+n) = I;  
  • %上  
  • newI(1:d,d+1:d+n) = I(d:-1:1,:);  
  • %下  
  • newI(end-d:end,d+1:d+n) = I(end:-1:end-d,:);  
  • %左  
  • newI(:,1:d) = newI(:,2*d:-1:d+1);  
  • %右  
  • newI(:,n+d+1:n+2*d) = newI(:,n+d:-1:n+1);  
  • end  
  •   
  • function newI = ReflectEdgeColor(I,d)  
  • %扩展图像边界  
  • [m n ~] = size(I);  
  • newI = zeros(m+2*d,n+2*d,3);  
  • %中间部分  
  • newI(d+1:d+m,d+1:d+n,1:3) = I;  
  • %上  
  • newI(1:d,d+1:d+n,1:3) = I(d:-1:1,:,1:3);  
  • %下  
  • newI(end-d:end,d+1:d+n,1:3) = I(end:-1:end-d,:,1:3);  
  • %左  
  • newI(:,1:d,1:3) = newI(:,2*d:-1:d+1,1:3);  
  • %右  
  • newI(:,n+d+1:n+2*d,1:3) = newI(:,n+d:-1:n+1,1:3);  
  • end  

  • 测试用例:

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

  • 结果:



    Reference:

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

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


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


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

    代码如下:

    [plain] view plain copy
  • function resultI = BilateralFilt2(I,d,sigma)  
  • %%%  
  • %Author:LiFeiteng  
  • %Version:1.0——灰色图像  Time:2013/05/01  
  • %Version:1.1——灰色/彩色图像  Time:2013/05/02  2013/05/05  
  • %d 半窗口宽度  
  • I = double(I);  
  • if size(I,3)==1  
  •     resultI = BilateralFiltGray(I,d,sigma);  
  • elseif size(I,3)==3  
  •     resultI = BilateralFiltColor(I,d,sigma);  
  • else   
  •     error('Incorrect image size')      
  • end  
  • end  
  •   
  • function resultI = BilateralFiltGray(I,d,sigma)  
  •   
  • [m n] = size(I);  
  • newI = ReflectEdge(I,d);  
  • resultI = zeros(m,n);  
  • width = 2*d+1;  
  • %Distance  
  • D = fspecial('gaussian',[width,width],sigma(1));  
  • S = zeros(width,width);%pix Similarity  
  • h = waitbar(0,'Applying bilateral filter...');  
  • set(h,'Name','Bilateral Filter Progress');  
  • for i=1+d:m+d  
  •     for j=1+d:n+d  
  •         pixValue = newI(i-d:i+d,j-d:j+d);  
  •         subValue = pixValue-newI(i,j);  
  •         S = exp(-subValue.^2/(2*sigma(2)^2));  
  •         H = S.*D;  
  •         resultI(i-d,j-d) = sum(pixValue(:).*H(:))/sum(H(:));   
  •     end  
  •     waitbar(i/m);  
  • end  
  • close(h);  
  • end  
  •   
  • function resultI = BilateralFiltColor(I,d,sigma)  
  • I = applycform(I,makecform('srgb2lab'));  
  • [m n ~] = size(I);  
  • newI = ReflectEdge(I,d);  
  • resultI = zeros(m,n,3);  
  • width = 2*d+1;  
  • %Distance  
  • D = fspecial('gaussian',[width,width],sigma(1));  
  • % [X,Y] = meshgrid(-d:d,-d:d);  
  • % D = exp(-(X.^2+Y.^2)/(2*sigma(1)^2));  
  • S = zeros(width,width);%pix Similarity  
  • h = waitbar(0,'Applying bilateral filter...');  
  • set(h,'Name','Bilateral Filter Progress');  
  • sigma_r = 100*sigma(2);  
  • for i=1+d:m+d  
  •     for j=1+d:n+d  
  •         pixValue = newI(i-d:i+d,j-d:j+d,1:3);  
  •         %subValue = pixValue-repmat(newI(i,j,1:3),width,width);  
  •         dL = pixValue(:,:,1)-newI(i,j,1);  
  •         da = pixValue(:,:,2)-newI(i,j,2);  
  •         db = pixValue(:,:,3)-newI(i,j,3);  
  •         S = exp(-(dL.^2+da.^2+db.^2)/(2*sigma_r^2));  
  •         H = S.*D;  
  •         H = H./sum(H(:));  
  •         resultI(i-d,j-d,1) = sum(sum(pixValue(:,:,1).*H));   
  •         resultI(i-d,j-d,2) = sum(sum(pixValue(:,:,2).*H));      
  •         resultI(i-d,j-d,3) = sum(sum(pixValue(:,:,3).*H));      
  •     end  
  •     waitbar(i/m);  
  • end  
  • close(h);  
  • resultI = applycform(resultI,makecform('lab2srgb'));  
  • end  

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

    [plain] view plain copy
  • function newI = ReflectEdge(I,d)  
  • %Version:1.0——灰色图像  Time:2013/05/01  
  • %Version:1.1——灰色/彩色图像  Time:2013/05/02  
  • %考虑到实用性,决定不添加更多的边界处理选择,统一使用:reflect across edge  
  •   
  • if size(I,3)==1  
  •     newI = ReflectEdgeGray(I,d);  
  • elseif size(I,3)==3  
  •     newI = ReflectEdgeColor(I,d);  
  • else   
  •     error('Incorrect image size')      
  • end  
  • end  
  •   
  • function newI = ReflectEdgeGray(I,d)  
  • [m n] = size(I);  
  • newI = zeros(m+2*d,n+2*d);  
  • %中间部分  
  • newI(d+1:d+m,d+1:d+n) = I;  
  • %上  
  • newI(1:d,d+1:d+n) = I(d:-1:1,:);  
  • %下  
  • newI(end-d:end,d+1:d+n) = I(end:-1:end-d,:);  
  • %左  
  • newI(:,1:d) = newI(:,2*d:-1:d+1);  
  • %右  
  • newI(:,m+d+1:m+2*d) = newI(:,m+d:-1:m+1);  
  • end  
  •   
  • function newI = ReflectEdgeColor(I,d)  
  • %扩展图像边界  
  • [m n ~] = size(I);  
  • newI = zeros(m+2*d,n+2*d,3);  
  • %中间部分  
  • newI(d+1:d+m,d+1:d+n,1:3) = I;  
  • %上  
  • newI(1:d,d+1:d+n,1:3) = I(d:-1:1,:,1:3);  
  • %下  
  • newI(end-d:end,d+1:d+n,1:3) = I(end:-1:end-d,:,1:3);  
  • %左  
  • newI(:,1:d,1:3) = newI(:,2*d:-1:d+1,1:3);  
  • %右  
  • newI(:,m+d+1:m+2*d,1:3) = newI(:,m+d:-1:m+1,1:3);  
  • end  

  • 测试用例:

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

  • 结果:



    Reference:

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

    总结

    以上是生活随笔为你收集整理的双边滤波Matlab实现The Bilateral Filter的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。