双边滤波

 双边滤波是一种可以保边去噪的滤波器。之所以可以达到这样的效果,是因为该滤波器是由两个函数构成,一个函数是由几何空间距离决定滤波器系数,另外一个由像素差决定滤波器系数。 

      在前面几种讲述的滤波方法中,像素点的灰度值均是由该点邻域内其他点的灰度值决定的,比如高斯滤波和均值滤波都可看作是加权平均,中值滤波取的是邻域灰度中值。双边滤波则不但考虑邻域范围内点的灰度值,同样考虑这些点距离中心点的几何距离,这样可以得到滤波后的点的灰度值表达公式为:


      其中k为归一化系数,其表达式为:


       h和x分别为滤波后和滤波前对应点的灰度值;

      c表示中心点与其邻域内点的空间相似度;

      s表示中心点与其邻域内点的灰度相似度。

      在实现过程中,c和s函数均可用高斯函数实现,即其定义如下:


      可根据以上原理实现双边滤波如下。

Void BilateralFilter(CvMat *pGrayMat, CvMat *pFilterMat, int nWidth, int nHeight, double dSigma1, double dSigma2, int nWindows)  

{  

    参数说明///   

    //pGrayMat:待处理图像数组   

    //pFilterMat:保存高斯滤波结果   

    //nWidth:图像宽度   

    //nHeight:图像高度   

    //dSigma1、dSigma2:分别为几何与灰度相关高斯函数的方差   

    double* dDistance = new double[nWindows*nWindows]; //计算距离中间点的几何距离   

    double* dGrayDiff = new double[nWindows*nWindows]; //定义中心点到当前点的灰度差   

    for(int i=0; i<nWindows*nWindows; i++)  

    {  

        int nNumX = i/nWindows;  

        int nNumY = i%nWindows;  

        dDistance[i] = ((nWindows-1)/2-nNumX)*((nWindows-1)/2-nNumX)+((nWindows-1)/2-nNumY)*((nWindows-1)/2-nNumY);  

        dDistance[i] = exp(-0.5*dDistance[i]/dSigma1/dSigma1);   //C参数   

    }  

    //以下求解灰度值的差   

    for(i=0; i<nHeight; i++)  

    {  

        for(int j=0; j<nWidth; j++)  

        {  

            double dGray = cvmGet(pGrayMat, i, j);    //当前点的灰度值   

            double dData = 0.0;  

            double dTotal = 0.0;                      //用于进行归一化    

            for(int m=0; m<nWindows*nWindows; m++)  

            {  

                int nNumX = m/nWindows;               //行索引   

                int nNumY = m%nWindows;               //列索引   

                int nX = i-(nWindows-1)/2+nNumX;  

                int nY = j-(nWindows-1)/2+nNumY;  

                if( (nY>=0) && (nY<nWidth) && (nX>=0) && (nX<nHeight))  

                {  

                    double dGray1 = cvmGet(pGrayMat, nX, nY);  

                    dGrayDiff[m] = fabs(dGray-dGray1);  

                    dGrayDiff[m] = exp(-0.5*dGrayDiff[m]*dGrayDiff[m]/dSigma2/dSigma2); //S参数   

                    if(m!=4)  

                    {  

                        dData += dGray1 * dGrayDiff[m] * dDistance[m]; //C和S参数综合   

                        dTotal += dGrayDiff[m]*dDistance[m];    //加权系数求和,进行归一化   

                    }  

                }  

            }  

            dData /=dTotal;  

            cvmSet(pFilterMat, i, j, dData);  

        }  

    }  

    delete[]dDistance;  

    delete[]dGrayDiff;  

}  


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值