• 在Shader中实现双边滤波的时候,总感觉理解的不太...高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。 为了实现线性的平滑,高斯滤波器和高斯分布(正态分布)是有关系的。 一个...

    在Shader中实现双边滤波的时候,总感觉理解的不太透彻,这里写博客记录一下。

    参考资料:
    算法原理
    GPUImage中Bilateral Filtering的实现

    高斯滤波 空间域

    在理解双边滤波之前,先来理解上面是高斯滤波
    高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。
    为了实现线性的平滑,高斯滤波器和高斯分布(正态分布)是有关系的。
    一个二维的高斯函数如下:

    其高斯核的图像为:
    这里写图片描述

    有了高斯函数之后就可以得到高斯模板,常用的高斯模板(也就是高斯核)是这样的:

    双边滤波 空间域+值域

    高斯滤波可以看成是基于像素点的欧式距离
    双边滤波是结合像素点之间的欧式距离与像素点之间的颜色差异

    上图中,最右边是归一化的公式,其目的是为了完全平滑的图像结果不变。双边滤波之所以可以保留边缘是因为其滤波模板不仅仅依赖于像素的位置关系,更依赖于其颜色,所以边缘可以被保留。

    高斯滤波对比双边滤波

    不管是什么样的图片,其高斯滤波模板可视化的图都差不多,见下图:

    因为不同的像素会影响到双边滤波模板,当像素为为下图中蓝色方框(中心像素点落在右边,偏白色)的时候:

    其双边滤波模板可视化的图见下图:

    展开全文
  • 利用双边滤波方法进行图像处理,所用的软件为MATLAB,其中一个.m文件为函数文件,另一个.m为测试文件,具体处理所需时间大约十多秒,也可能二三十秒,看情况,运行时耐心等下
  • 双边滤波    由于高斯噪声在信号采集系统中往往是无法避免的,所以在信号处理中高斯滤波器是最常用的滤波器之一;数字图像也是一种信号,高斯滤波也是最常用的图像去噪方法。但是在之前的博客中提到过,高斯滤波是...

    【fishing-pan:https://blog.csdn.net/u013921430 转载请注明出处】

    双边滤波

       高斯滤波是最常用的图像去噪方法之一,它能很好地滤除掉图像中随机出现的高斯噪声,但是在之前的博客中提到过,高斯滤波是一种低通滤波(有兴趣的点击这里,查看之前的博客),它在滤除图像中噪声信号的同时,也会对图像中的边缘信息进行平滑,表现出来的结果就是图像变得模糊,如下图所示;
    在这里插入图片描述
       高斯滤波之所以会导致图像变得模糊,是因为它在滤波过程中只关注了位置信息;例如,以 qq 为中心的窗口中,某一点 pp 在高斯滤波过程中的权重的计算方法如下式;
    G(p)=12πσ2epq22σ2G(p)=\frac{1}{2\pi \sigma ^{2}} e^{-\frac{\left \| p-q \right \|^{2}}{2\sigma ^{2}}}
      即在滤波窗口内,距离中心点越近的点的权重越大;这种只关注距离的思想在某些情况下是可行的,例如在平坦的区域,距离越近的区域其像素分布也越相近,自然地,这些点的像素值对滤波中心点的像素值更有参考价值。但是在像素值出现跃变的边缘区域,这种方法会适得其反,损失掉有用的边缘信息。此时就出现了一类算法——边缘保护滤波方法双边滤波就是最常用的边缘保护滤波方法(另一种常用来与双边滤波对比的边缘保护滤波方法——引导滤波)。

      双边滤波的思想很简单,在高斯滤波的基础上加入了像素值权重项,也就是说既要考虑距离因素,也要考虑像素值差异的影响,像素值越相近,权重越大。将像素值权重表示为 GrG_{r} ,空间距离权重表示为 GsG_{s}

    Gs=exp(pq22σs2)G_{s}=exp(-\frac{\left \| p-q \right \|^{2}}{2\sigma _{s}^{2}})
    Gr=exp(IpIq22σr2)G_{r}=exp(-\frac{\left \| I_{p}-I_{q} \right \|^{2}}{2\sigma _{r}^{2}})

      那么整个滤波器可以表示为BFBF,那么滤波结果为;
    BF=1WqpSGs(p)Gr(p)Ip=1WqpSexp(pq22σs2)exp(IpIq22σr2)Ip \begin{aligned} BF&=\frac{1}{W_{q}}\sum_{p\in S}G_{s}(p)G_{r}(p)*I_{p}\\ &=\frac{1}{W_{q}}\sum_{p\in S}exp(-\frac{\left \| p-q \right \|^{2}}{2\sigma _{s}^{2}})exp(-\frac{\left \| I_{p}-I_{q} \right \|^{2}}{2\sigma _{r}^{2}})*I_{p} \end{aligned}
      其中Wq{W_{q}} 为滤波窗口内每个像素值的权重和,用于权重的归一化;
    Wq=pSGs(p)Gr(p)=pSexp(pq22σs2)exp(IpIq22σr2){W_{q}}=\sum_{p\in S}G_{s}(p)G_{r}(p)=\sum_{p\in S}exp(-\frac{\left \| p-q \right \|^{2}}{2\sigma _{s}^{2}})exp(-\frac{\left \| I_{p}-I_{q} \right \|^{2}}{2\sigma _{r}^{2}})
      在平坦区域,滤波器中每个像素点的GrG_{r} 值相近,空间距离权重GsG_{s}主导滤波效果。在边缘区域,边缘同侧的GrG_{r} 值相近,且远大于边缘另一侧的GrG_{r} 值,此时另一侧的像素点的权重对滤波结果几乎不影响,边缘信息得到保护。表现出了一定的自适应性。

      在平坦区域出现噪声点时,噪声点周围的信号的权值都很小,在进行归一化后,这些权值得到了提升,因此对噪声点也有滤除效果。
    双边滤波示意图

    双边滤波OpenCV实现

      在OpenCV中已经有编辑好的双边滤波的函数;

    void bilateralFilter( InputArray src, OutputArray dst, int d,
                                       double sigmaColor, double sigmaSpace,
                                       int borderType = BORDER_DEFAULT );
    

      函数中的参数依次表示src:输入图像,dst: 输出图像,d:滤波窗口的直径(函数注释中使用的是Diameter,那么很可能函数中选取的窗口是圆形窗口),sigmaColor:像素值域方差,sigmaSpace:空间域方差,以及边缘处理方式。

      根据算法原理,我编写了自己的双边滤波函数;其中的核心部分如下;

    //-------------------------------------------------------------
    //作者:不用先生,2018.11.26
    //自实现的图像双边滤波算法
    //bilateral.cpp
    //-------------------------------------------------------------
    for (int i = 0; i < row; i++)    //对每一个点进行处理
    {
    	for (int j = 0; j < col; j++)
    	{
    		double weightSum = 0;
    		double filterValue = 0;
    		for (int row_d = -(d / 2); row_d <= (d / 2); row_d++)   //以图像中的一点为中心,d为边长的方形区域内进行计算
    		{
    			for (int col_d = -(d / 2); col_d <= (d / 2); col_d++)
    			{
    				double distance_Square = row_d*row_d + col_d*col_d;
    				double value_Square = pow((scr.at<uchar>(i, j) - copyBorder_dst.at<uchar>(i + (d / 2) + row_d, j + (d / 2) + col_d)), 2);
    				double weight = exp(-1 * (distance_Square / (2 * sigmaSpace*sigmaSpace) + value_Square / (2 * sigmaColor*sigmaColor)));
    				weightSum += weight;               //求滤波窗口内的权重和,用于归一化;
    				filterValue += (weight*copyBorder_dst.at<uchar>(i + (d / 2) + row_d, j + (d / 2) + col_d));
    
    			}
    		}
    		dst.at<uchar>(i, j) = filterValue / weightSum;
    				
    	}
    }
    

      从代码中可以看出,我选择的是一个方形区域而不是圆形区域进行滤波计算,大家如果觉得欠妥,在自己编写代码时可以修改成圆形区域,也很简单。完整代码,可以到这里下载,或者直接在评论区留下自己的邮箱,我看到留言后会尽快发的您的邮箱。

    测试结果

      用自己编写的代码、OpenCV自带的双边滤波函数以及高斯滤波函数分别对一张彩色图像今进行处理,并对比了结果。
    在这里插入图片描述
      这里出现了很奇怪的现象,所有输入参数相同时(我选取参数的是d=21;sigmaColor=10;sigmaSpace = 10;),我的函数计算的结果比OpenCV自带的 bilateralFilter 函数的处理结果更加平滑。当把 bilateralFilter 函数的sigmaColorsigmaSpace参数调整为两到三倍的时候, bilateralFilter 函数的结果与我的计算结果相近。这种差异性的结果不应该是窗口选取方式不同导致的。具体原因,我觉得可能与 bilateralFilter 函数中方差的应用有关。但是总的来说,两个函数都对图像有一定的平滑效果,并很好地保护了边缘信息。

      本博客中只讲述了双边滤波最基础的原理以及实现过程,这种计算方法比较耗时,后续的人们做了一系列的工作,用于提升双边滤波的计算效率。大家感兴趣的可以去了解一下。

    参考

    1. Tomasi C, Manduchi R. Bilateral filtering for gray and color images[C]//Computer Vision, 1998. Sixth International Conference on. IEEE, 1998: 839-846.
    2. He K, Sun J, Tang X. Guided image filtering[J]. IEEE transactions on pattern analysis & machine intelligence, 2013 (6): 1397-1409.

      已完。。

    展开全文
  • 图像滤波原理之双边滤波图像滤波问题描述1. 空间(即图像定义域)相邻关系的滤波器2. 双边滤波器(bilateral filter)3. 如何快速实现双边滤波 图像滤波问题描述 为了内容的完整性,首先对图像滤波进行简单的回顾。...

    图像滤波问题描述

    为了内容的完整性,首先对图像滤波进行简单的回顾。令IRh×w×cI\in R^{h\times w\times c}表示图像,是一个二维矩阵,h,wh,w分别表示图像的高度和宽度,c=1,3c=1,3分别表示灰度图像和彩色图像,II中的每个元素I(i,j)I(i,j)称作一个像素。不失一般性,我们以c=1c=1即灰度图为例。本质上图像II是一个定义二维网格点上的函数,也即I:(i,j)R2I(i,j)RI:(i,j)\in R^{2} \rightarrow I(i,j)\in R
    f:IRh×wI^Rh×wf:I\in R^{h\times w}\rightarrow \hat{I}\in R^{h\times w}表示滤波器。常见的滤波过程就是:计算每个像素I(i,j)I(i,j)经过滤波后的值I^(i,j)\hat{I}(i,j),都是通过加权像素I(i,j)I(i,j)的邻域像素值,如下公式所示:
    (1)I^(i,j)=fI(i,j)=1w(i,j)(i,j)Nw(i,j)I(i,j)\hat{I}(i,j)=f\circ I(i,j)=\frac{1}{\sum w(i&#x27;,j&#x27;)}\sum_{(i&#x27;,j&#x27;)\in N} w(i&#x27;,j&#x27;)I(i&#x27;,j&#x27;)\tag{1}
    其中NN表示像素I(i,j)I(i,j)的邻域(也称滤波器的窗口),注意这里的邻域关系仅仅是像素点在定义域的相邻关系,如图像上的8邻域等。

    1. 空间(即图像定义域)相邻关系的滤波器

    常见的滤波器,如高斯滤波器,均值滤波器等,都属于这一类滤波器。
    如(1)式所示,当权重
    w(i,j)=1nw(i&#x27;,j&#x27;)=\frac{1}{n}其中n=Nn=|N|表示邻域像素的个数, 这就均值滤波器。
    当权重
    w(i,j)=12πσ2e(ii)2+(jj)22σ2w(i&#x27;,j&#x27;)=\frac{1}{2\pi\sigma^2}e^{-{\frac{(i&#x27;-i)^2+(j&#x27;-j)^2}{2\sigma^2}}}
    就是通常的高斯滤波器。

    注意这类滤波器,在进行图像滤波的时候仅仅考虑图像的定义域上的邻域关系(也即空间上的邻域关系)。这样通常会导致图像模糊,因为仅仅按图像定义域或空间上的相邻关系,会导致空间(或定义域)上相邻但是像素值相差巨大的像素参与滤波过程,如下图所示:按8邻域关系,计算点AA的高斯滤波或均值滤波时,空间相邻的像素点B,C,D,EB,C,D,E(注意它们的像素值(白)与AA点的像素值(黑)相差很大),会参与滤波公式(1)中的加权平均。很显然,滤波后会导致,在AA点附近的图像边缘会出现模糊。

    滤波仅考虑图像定义域上的相邻关系下面就介绍双边滤波,能够在很大程度上避免这一种仅仅依靠图像定义域相邻引起的图像模糊。

    2. 双边滤波器(bilateral filter)

    如何将上图中的点AAB,C,D,EB,C,D,E区分开来,使得(1)式中计算AA点的加权平均时,B,C,D,EB,C,D,E贡献的权重为0(当然这是理想的情况),就成了关键。那么一个很自然的想法是,同时考虑像素点的像素值,这样将像素点投到高维空间,那么有可能B,C,D,EB,C,D,E将不再是AA的相邻点。因为在低维空间中不易区分的点,在高维空间中可能比较容易区分开来。这点类似SVM(支持向量机)中的核函数设置的思想。

    同时统计像素点AA的坐标和像素值,这其实就是图像函数I:(i,j)I(i,j)RI:(i,j)\rightarrow I(i,j)\in R的graph, 记作
    (2)G={(i,j,I(i,j)):(i,j)}G=\{(i,j,I(i,j)):(i,j)是图像像素坐标\}\tag{2}
    它是一个二维流形(嵌入在三位欧式空间R3R^3中),其实就是一个曲面,显然在这个graph GG上,B,C,D,EB,C,D,EAA不再是相邻点。但是在直接二维流形GG上寻找点的相邻点可能非常复杂,因为曲面的形状可能很不规则(曲率不为0),不像二维平面网格点(i,j)(i,j)那样容易寻找相邻点。

    为了计算方便,退而求其次,把二维曲面GG嵌入在三维空间中考虑,利用三维欧式空间R3R^3的曲率为0,在三维网格点中寻找相邻点,这样就和在二维网格中种寻找相邻点一样方便。但是考虑到嵌入的GG实则是函数II的图像graph,本质上是二维的,所以双边滤波仍按定义域寻找相邻点即可,但是要减弱这些相邻点中颜色差异较大的点对滤波贡献的权重。

    可以看到,在把GG嵌入三维空间考虑时,AA点在对应(iA,jA,IA)(i_A,j_A,I_A)。以DD点为例,DD对应(iD,jD,ID)(i_D,j_D,I_D)。不妨以欧式范数为例,在三维空间中A,DA,D之间的距离为
    (3)d(A,D)=(iDiA)2+(jDjA)2+(IDIA)2=1+1+(IDIA)2d(A,D)=\sqrt{(i_D-i_A)^2+(j_D-j_A)^2+(I_D-I_A)^2}=\sqrt{1+1+(I_D-I_A)^2}\tag{3}
    则如上面(3)式所示,那么当A,DA,D的像素值之差IDIA|I_D-I_A|很大时,那么在GGd(A,D)d(A,D)距离就很远。
    而双边滤波正是通过,考虑这种距离来弱化DDAA的影响,这点可以从下面双边滤波的公式中,得到体现
    (4)I^A=1w(q,A)qNw(q,A)Iq\hat{I}_A=\frac{1}{\sum w(q,A)}\sum_{q\in N}w(q,A)I_q\tag{4}
    其中,NN是点AA的邻域,
    w(q,A)=e(iqiA)2+(jqjA)22σs2(IqIA)22σr2w(q,A)=e^{-\frac{(i_q-i_A)^2+(j_q-j_A)^2}{2\sigma_{s}^{2}}-\frac{(I_q-I_A)^2}{2\sigma_{r}^2}}

    显然,当q,Aq,A之间的像素值相差很大时,w(q,A)w(q,A)就会变得很小,从而达到了弱化qq点对AA点的滤波值的影响,易见上图中的B,C,D,EB,C,D,EAA的距离很大(在R3R^3中考虑它们之间的距离时)。所以滤波时,B,C,D,EB,C,D,EAA的影响就大大减弱,从而大大减轻滤波后边界模糊的现象,达到了保边滤波的效果。

    3. 如何快速实现双边滤波

    即使双边滤波有很好的保边效果,但是当图像的尺寸以及滤波器的窗口尺寸很大时,双边滤波的速度就可能很慢。双边滤波这不像通常的高斯滤波和均值率波等,双边滤波(4)式中的权重系数ww是与图像的像素值有关的,因而不能像高斯滤波或者均值滤波那样有固定的模板通过卷积快速实现。后面系列,会介绍快速实现近似双边滤波的相关文章[1]以及在双边滤波在深度学习中的应用。。。。。

    [1]: Fast high-dimensional filtering using the permutohedral lattice.

    展开全文
  • 双边滤波(Bilateral filter)是一种可以去噪保边的滤波器。之所以可以达到此效果,是因为滤波器是由两个函数构成:一个函数是由几何空间距离决定滤波器系数,另一个由像素差值决定滤波器系数。  原理示意图如下...
         双边滤波(Bilateral filter)是一种可以去噪保边的滤波器。之所以可以达到此效果,是因为滤波器是由两个函数构成:一个函数是由几何空间距离决定滤波器系数,另一个由像素差值决定滤波器系数。
     原理示意图如下:


         双边滤波器中,输出像素的值依赖于邻域像素的值的加权组合,
              
         权重系数w(i,j,k,l)取决于定义域核
              
         和值域核
              
         的乘积
              

    二、C++实现
         2.1 OpenCV调用方法:

    cvSmooth(m_iplImg, dstImg, CV_BILATERAL, 2 * r + 1, 0, sigma_r, sigma_d);


         2.3 C++代码
         
    //双边滤波
    void CImgPrcView::BilateralFilter()
    {
        // TODO: 在此添加命令处理程序代码
        if (!m_pBitmap) return;
        FreeInterResultImage();

        int r = 7;//滤波器边长
        int w_filter = 2 * r + 1;
        //修改该参数
        double sigma_d = 5;
        double sigma_r = 25;
        int nx = m_dwWidth, ny = m_dwHeight;
        double gaussian_d_coeff = -1 / (2 * sigma_d * sigma_d);    //定义域核 sigma_d为标准差
        double gaussian_r_coeff = -1 / (2 * sigma_r * sigma_r);    //值域核    sigma_r为标准差
        double *d_metrix = new double[w_filter * w_filter];            // spatial weight 空间距离系数
        double *r_metrix = new double[w_filter * w_filter];            // r_metrix weight 空间距离系数
        double *metrix = new double[w_filter * w_filter];            // metrix weight 空间距离系数

        //double r_metrix[256];  // similarity weight 灰度差值系数

        // copy the original image
        BYTE *img_tmp = new BYTE[nx * ny];
        BYTE *img = new BYTE[nx * ny];
        for (int i = 0; i < ny; i++)
            for (int j = 0; j < nx; j++)
                {
                    img_tmp[i * nx + j] = m_pBitmap[i * nx + j];
                    img[i * nx + j] = 255;
                }

        // compute spatial weight
        for (int i = -r; i <= r; i++)
            for (int j = -r; j <= r; j++)
            {
                 d_metrix[(i + r) * w_filter + (j + r)] = exp((i * i + j * j) * gaussian_d_coeff);
            }

    // bilateral filter
        for (int i = 0; i < ny; i++)
        {
            for (int j = 0; j < nx; j++)
            {
                // compute similarity weight
                double weight_temp = 0;
                for (int k = -r; k <= r; k++)
                {
                    for (int l = -r; l <= r; l++)
                    {
                        if (((i + k) < 0) || ((i + k) > ny) || ((j + l) < 0) || ((j + l) > nx))
                        {
                            weight_temp = abs(img_tmp[i * nx + j] - 0);
                            r_metrix[(k + r)*(2 * r + 1) + (l + r)] = exp(gaussian_r_coeff * pow(weight_temp, 2));
                        }
                        else
                        {
                            weight_temp = abs(img_tmp[i * nx + j] - img_tmp[(i + k) * nx + (j + l)]);
                            r_metrix[(k + r)*(2 * r + 1) + (l + r)] = exp(gaussian_r_coeff * pow(weight_temp , 2));
                        }
                    }
                }

                // compute weight               
                double weight_up = 0, weight_down = 0;
                for (int k = -r; k <= r; k++)
                {
                    for (int l = -r; l <= r; l++)
                    {
                        if (((i + k) < 0) || ((i + k) > ny) || ((j + l) < 0) || ((j + l) > nx))
                        {
                            metrix[(k + r) * (2 * r + 1) + (l + r)] = 0;
                            //计算当前灰度值
                            weight_down += metrix[(k + r) * (2 * r + 1) + (l + r)];
                            weight_up += metrix[(k + r) * (2 * r + 1) + (l + r)] * 0/* * img_tmp[(i) * nx + (j)]*/; //边界处理
                        }
                        else
                        {
                            metrix[(k + r) * (2 * r + 1) + (l + r)] = r_metrix[(k + r) * (2 * r + 1) + (l + r)] * d_metrix[(k + r) * (2 * r + 1) + (l + r)];
                            //计算当前灰度值
                            weight_down += metrix[(k + r) * (2 * r + 1) + (l + r)];
                            weight_up += metrix[(k + r) * (2 * r + 1) + (l + r)] * img_tmp[(i + k) * nx + (j + l)];
                        }
                    }
                }
                img[i * nx + j] = weight_up / weight_down;
            }
        }
        AddInterResultImage(img, m_dwHeight, m_dwWidth, 8, "双边滤波");
        Invalidate(FALSE);
        UpdateWindow();
        delete [] img;
        delete [] img_tmp;
        delete [] d_metrix;
        delete [] r_metrix;
        delete [] metrix;
    }
    性能方面,跟OpenCV处理速度有差距,有兴趣的,可以自己研究OpenCV版本的源代码

    三、效果图




    四、参考资料
         资料[4]是MIT的学习资料,最全面,包括课件、论文、代码等,涵盖原理、改进、应用、与PDE的联系等等,最值得一看。

    展开全文
  • 实现图像的联合双边滤波 Function im = jbf(D,C,w, sigma_f, sigma_g) D为输入图像 C为引导图像 W为滤波窗口大小 sigma_f 为spatial kernel标准差 sigma_g为range kernel 标准差 输入图像I 下采样(1/2)得到LR...

    本文属于原创,转载请注明出处。

    实验4: 联合双边滤波

    • 实现图像的联合双边滤波
    • Function im = jbf(D,C,w, sigma_f, sigma_g)
    • D为输入图像
    • C为引导图像
    • W为滤波窗口大小
    • sigma_f 为spatial kernel标准差
    • sigma_g为range kernel 标准差
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    输入图像I 下采样(1/2)得到LR低分辨率图像,再由LR图像上采样2倍得到引导图像
    注:图像缩放采用实验二的双线性插值

    这学期的最后一个数字图像处理,老师上课的时候并没有讲到这块内容,所以只能自学上网查资料:

    双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。

    双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。

    然后双边滤波器的权值不够稳定,而联合双边滤波器就是在双边滤波器的基础上引入了引导图像,使得权值更稳定。
    其中引导图像是先将图像按1/2进行缩小,然后再*2进行放大,这里应用到了之前写到的双线性差值:

    function output_img =  resize( input_img,x,y )
    %RESIZE 此处显示有关此函数的摘要
    %   input_img为输入图像,output_img为输出图像,x,y为缩放倍数
    %获取原图像的长宽
    [width,height,dimension] = size(input_img);
    %计算新图像的长宽
    new_width = round(width*x);
    new_height = round(height*y);
    
    %双线性差值法
    for i = 1:new_width
        for j = 1:new_height
            %原来图像的坐标,向下取整
            tempx = floor((i-1)/x);
            tempy = floor((j-1)/y);
            %对四条边和四个顶点进行处理
            if tempx == 0 || tempy == 0 || tempx == width-1 || tempy == height-1
                output_img(1,j,:) = input_img(1,tempy+1,:);
                output_img(i,1,:) = input_img(tempx+1,1,:);
            %对其余像素进行处理
            else
                %计算原图像坐标减去新图像坐标的小数部分
                a = (i-1) / x - tempx;
                b = (j-1) / y - tempy;
                %最小值为1
                tempx = tempx+1;
                tempy = tempy+1;
                output_img(i,j,:) = input_img(tempx,tempy,:)*(1-a)*(1-b)+input_img(tempx,tempy+1,:)*(1-a)*b...
                    +input_img(tempx+1,tempy,:)*a*(1-b)+input_img(tempx+1,tempy+1,:)*a*b;
            end
        end
    end
    
    
    

    这个函数的具体讲解可以看我之前的博客:实验二

    然后就是使用JBF算法:

    function output_img = jbf(D,C,w, sigma_f, sigma_g)
    %   联合双边滤波
    %   D为输入图像
    %   C为引导图像
    %   W为滤波窗口大小
    %   sigma_f 为spatial kernel标准差
    %   sigma_g为range kernel 标准差
    %统计运行时间
    tic;
    %保证数据的精度
    D = double(D);
    C = double(C);
    
    %创建核距离矩阵
    [X,Y] = meshgrid(-w:w,-w:w);
    %计算定义域核
    F = exp(-(X.^2+Y.^2)/(2*sigma_f^2));
    %初始化输出矩阵 
    [rows,cols,dimension] = size(D);
    output_img = zeros([rows,cols,dimension]);
    %多通道处理
    for d = 1:dimension
        for i = 1:rows
            for j = 1:cols
                %计算当前窗口范围
                iStart = max(i-w,1);
                iEnd = min(i+w,rows);
                jStart = max(j-w,1);
                jEnd = min(j+w,cols);
                %原图的当前窗口
                window_D = D(iStart:iEnd,jStart:jEnd,d);
                %引导图的当前窗口
                window_C = C(iStart:iEnd,jStart:jEnd,d);
                %由引导图像的灰度值差计算值域核
                G = exp(-(window_C-C(i,j)).^2/(2*sigma_g^2));
                %由值域核G与定义域核F的乘积得到联合双边权重函数W
                W = G.*F((iStart:iEnd)-i+w+1,(jStart:jEnd)-j+w+1);
                output_img(i,j,d) = sum(W(:).*window_D(:))/sum(W(:));
            end
        end
    end
    output_img = uint8(output_img);
    toc;
    end
    

    现在看看结果:

    input = imread('a.png');
    %获取引导图像C,先缩小再放大进行采样
    img = resize(input,0.5,0.5);
    C = resize(img,2,2);
    output = jbf(input,C,2,2,15);
    %图像显示
    subplot(1,3,1);
    imshow(input),title('原图');
    subplot(1,3,2);
    imshow(C),title('引导图');
    imwrite(C,'C.png');
    subplot(1,3,3);
    imshow(output),title('联合双边滤波处理后');
    imwrite(output,'output.png');
    
    

    原图
    在这里插入图片描述
    引导图像
    在这里插入图片描述
    结果图像
    在这里插入图片描述

    展开全文
  • 两者的区别在于,高斯滤波在滤波时会将图像中各个颜色区域的边缘同区域本身一起模糊掉,而高斯双边滤波则是对各个区域的交界边缘有所保留。 对于高斯滤波来说有两个参数 window_size,即滤波窗口越大,图像越模糊 ...
  • 图像处理双边滤波效果(Bilateral Filtering for Gray and Color Image) 基本介绍: 普通的时空域的低通滤波器,在像素空间完成滤波以后,导致图像的边缘部分也变得不那么明显, 整张图像都变得同样的模糊,图像...
  • 双边滤波是基于高斯滤波的思想,在高斯滤波的基础上,加上图像像素值对中心像素的影响,两者共同影响中心像素的值。 高斯滤波: 权重大小取决于中心像素的灰度值和邻域像素的灰度值得差,当边缘有较大的灰度...
  • 20180307站位。
  • 1 近期在学习双边滤波相关知识,其原理如下(以后补上):2 灰度图双边滤波实现C++代码如下,网上大多数是基于8位灰度图和彩色图像的。(此次代码未经优化,可去除opencv依赖)://灰度图双边滤波 void m_bilateral...
  • 假设sigma=1.5(这里为什么假设一个sigma,而不是直接使用实际的sigma,因为计算出来的方差也包含了图像的细节,如果 直接用图像的方差来计算高斯模糊,强度过大) 高斯距离矩阵 按照最上面的公式计算出来的权...
  • 图像双边滤波

    2020-07-03 23:30:50
    图像进行双边滤波,在平滑图像的基础上有效地保持边缘
  • 递归双边滤波双边滤波的一种加速算法,加速比非常大,就像高斯模糊快速算法一样,加速起来,速度跟原算法相比,提高了十几倍。双边滤波的加速算法很多,文献都比较老旧,我这边主要讲一下比较新的算法:递归双边...
  • 采用openCV和vs2010实现通过双边滤波的方法实现图像的优化。
  • 双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。双边滤波的基本...
  • 但是双边滤波保边性会因为平滑滤波作用而减弱,造成图像模糊不清晰。为了克服这一缺点,提出了基于双边滤波图像增强算法。该算法是将原图像高低频分量进行分离,在重新分配权重合成一张新图像。新算法解决了边缘保...
  • 双边滤波算法原理

    2016-03-10 22:15:40
     双边滤波图像处理领域中有着广泛的应用,比如去噪、去马赛克、光流估计等等,最近,比较流行的Non-Local算法也可以看成是双边滤波的一种扩展。自从Tomasi et al等人提出该算法那一天起,如何快速的实现他,一直...
  • 双边滤波(Bilateral Filter)是非线性滤波中的一种。这是一种结合图像的空间邻近度与像素值相似度的处理办法。在滤波时,该滤波方法同时考虑空间临近信息与颜色相似信息,在滤除噪声、平滑图像的同时,又做到边缘...
  • 基于双边滤波图像处理方法,在图像处理方面可以有效地保留图像信息的基础上达到较好的去噪效果,突出目标点
1 2 3 4 5 ... 20
收藏数 3,468
精华内容 1,387
关键字:

双边滤波图像处理