高斯滤波

来源:互联网 发布:mac如何投屏到电视 编辑:程序博客网 时间:2024/05/01 18:49

高斯滤波是一种线性平滑滤波,适用于滤除高斯白噪声,已广泛应用于图像处理的预处理阶段。按照本人的理解,对图像进行高斯滤波就是对图像中的每个点的像素值计算,计算的准则是,由该点本身灰度值以及其邻域内的其他像素灰度值加权平均所得,而加权平均的权系数由二维离散高斯函数采样并归一化后所得。

void GuassFilter(CvMat *pGrayMat, CvMat* pFilterMat, int nWidth, int nHeight, double dSigma)  

{  

    ////////////////////////参数说明///////////////////////////////////  

    //pGrayMat:待处理图像数组  

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

    //nWidth:图像宽度  

    //nHeight:图像高度  

    //dSigma:高斯滤波参数,方差  

    int nWidowSize = (int)(1+2*ceil(3*dSigma));  //定义滤波窗口的大小  

    int nCenter = (nWidowSize)/2;                //定义滤波窗口中心的索引  

    //生成二维的高斯滤波系数  

    double* pdKernal = new double[nWidowSize*nWidowSize]; //定义一维高斯核数组  

    double  dSum = 0.0;                                   //求和,进行归一化          

    /////////////二维高斯函数公式//////////////////////       

    //                           x*x+y*y        ///////  

    //                     -1*--------------    ///////  

    //          1               2*Sigma*Sigma   ///////  

    //   ---------------- e                     ///////  

    //   2*pi*Sigma*Sigma                       ///////  

    ///////////////////////////////////////////////////  

    for(int i=0; i<nWidowSize; i++)  

    {  

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

        {  

            int nDis_x = i-nCenter;  

            int nDis_y = j-nCenter;  

            pdKernal[i+j*nWidowSize]=exp(-(1/2)*(nDis_x*nDis_x+nDis_y*nDis_y)  

                /(dSigma*dSigma))/(2*3.1415926*dSigma*dSigma);  

            dSum += pdKernal[i+j*nWidowSize];  

        }  

    }  

    //进行归一化  

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

    {  

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

        {  

            pdKernal[i+j*nWidowSize] /= dSum;  

        }  

    }  

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

    {  

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

        {  

            double dFilter=0.0;  

            double dSum = 0.0;  

            for(int x=(-nCenter); x<=nCenter; x++)           //  

            {  

                for(int y=(-nCenter); y<=nCenter; y++)       //  

                {  

                    if( (j+x)>=0 && (j+x)<nWidth && (i+y)>=0 && (i+y)<nHeight)  //判断边缘  

                    {  

                        double ImageData = cvmGet(pGrayMat ,i+y, j+x);  

                        dFilter += ImageData * pdKernal[(y+nCenter)*nWidowSize+(x+nCenter)];  

                        dSum += pdKernal[(y+nCenter)*nWidowSize+(x+nCenter)];  

                    }  

                }  

            }  

            cvmSet(pFilterMat, i, j, dFilter/dSum);  

        }  

    }  

    delete[]pdKernal;  

}  


0 0