zoukankan      html  css  js  c++  java
  • 高斯滤波

    高斯滤波核函数满足如下分布:

    一维核函数:

    二维核函数:

    通过核函数可以计算K*K的高斯平滑模板:(貌似opencv 和matlab 中都有封装好的函数)

    sigma需要自己设定,根据生成的模板大小,x和y表示当前元素距模板中心的距离。可以由opencv直接调用求模板,也可以分别通过一维/二维自己代码求模板。【注意,一维滤波的时候需要对x和y方向分别滤波】

    //通用变量定义
    double nSigma = 0.4;                            //定义高斯函数的标准差  
    int nWidowSize = 1+2*ceil(3*nSigma);            //定义滤波窗口的大小  
    int nCenter = (nWidowSize)/2;                   //定义滤波窗口中心的索引  
    double nSigma = 0.4;                            //定义高斯函数的标准差  
    int nWidowSize = 1+2*ceil(3*nSigma);            //定义滤波窗口的大小  
    int nCenter = (nWidowSize)/2;                   //定义滤波窗口中心的索引  
    //////////////////////生成一维高斯滤波系数,高斯模板也可以是非对称的/////////////////////////////  
    double* pdKernal_1 = new double[nWidowSize];    //定义一维高斯核数组  
    double  dSum_1 = 0.0;                           //求和,用于进行归一化          
    ////////////////////////一维高斯函数公式//////////////////////////////       
    ////                   x*x                           /////////////////  
    ////          -1*----------------                    /////////////////  
    ////         1     2*Sigma*Sigma                     /////////////////  
    ////   ------------ e                                /////////////////  
    ////                                                 /////////////////  
    ////   /2*pi*Sigma                                  /////////////////  
    //////////////////////////////////////////////////////////////////////  
    for(int i=0; i<nWidowSize; i++)  
    {  
            double nDis = (double)(i-nCenter);  
        pdKernal_1[i] = exp(-(0.5)*nDis*nDis/(nSigma*nSigma))/(sqrt(2*3.14159)*nSigma);  
        dSum_1 += pdKernal_1[i];  
    }  
    for(i=0; i<nWidowSize; i++)  
    {  
        pdKernal_1[i] /= dSum_1;                 //进行归一化  
    }  
    //////////////////////生成二维高斯滤波系数//////////////////////////////////    
    double* pdKernal_2 = new double[nWidowSize*nWidowSize]; //定义一维高斯核数组  
    double  dSum_2 = 0.0;                                   //求和,进行归一化        
    ///////////////////////二维高斯函数公式////////////////////////////////////      
    ////                         x*x+y*y                        ///////////////  
    ////                   -1*--------------                ///////////////  
    ////         1             2*Sigma*Sigma                ///////////////  
    ////   ---------------- e                                   ///////////////  
    ////   2*pi*Sigma*Sigma                                     ///////////////  
    ///////////////////////////////////////////////////////////////////////////  
    for(i=0; i<nWidowSize; i++)  
    {  
        for(int j=0; j<nWidowSize; j++)  
        {  
            int nDis_x = i-nCenter;  
            int nDis_y = j-nCenter;  
            pdKernal_2[i+j*nWidowSize]=exp(-(1/2)*(nDis_x*nDis_x+nDis_y*nDis_y)  
                /(nSigma*nSigma))/(2*3.1415926*nSigma*nSigma);  
            dSum_2 += pdKernal_2[i+j*nWidowSize];  
        }  
    }  
    for(i=0; i<nWidowSize; i++)  
    {  
        for(int j=0; j<nWidowSize; j++)                 //进行归一化  
            {  
            pdKernal_2[i+j*nWidowSize] /= dSum_2;  
        }  
    }  

    ========================================================

    高斯平滑:

    //一维核函数生成的模板平滑
    for(i=0; i<nHeight; i++)                               //进行x向的高斯滤波(加权平均)  
    {  
        for(j=0; j<nWidth; j++)  
        {  
            double dSum = 0;  
            double dFilter=0;                                       //滤波中间值  
            for(int nLimit=(-nCenter); nLimit<=nCenter; nLimit++)  
            {  
                if((j+nLimit)>=0 && (j+nLimit) < nWidth )       //图像不能超出边界  
                {  
                    dFilter += (double)nImageData[i*nWidth+j+nLimit] * pdKernal_1[nCenter+nLimit];  
                    dSum += pdKernal_1[nCenter+nLimit];  
                }  
            }  
            nData[i*nWidth+j] = dFilter/dSum;  
        }  
    }  
      
    for(i=0; i<nWidth; i++)                                //进行y向的高斯滤波(加权平均)  
    {  
        for(j=0; j<nHeight; j++)  
        {  
            double dSum = 0.0;  
            double dFilter=0;  
            for(int nLimit=(-nCenter); nLimit<=nCenter; nLimit++)  
            {  
                if((j+nLimit)>=0 && (j+nLimit) < nHeight)       //图像不能超出边界  
                {  
                    dFilter += (double)nData[(j+nLimit)*nWidth+i] * pdKernal_1[nCenter+nLimit];  
                    dSum += pdKernal_1[nCenter+nLimit];  
                }  
            }  
            pCanny[j*nWidth+i] = (unsigned char)(int)dFilter/dSum;  
        }  
    }  
    //二维核函数平滑
    int x;  
    int y;  
    for(i=0; i<nHeight; i++)  
    {  
        for(j=0; j<nWidth; j++)  
        {  
            double dFilter=0.0;  
            double dSum = 0.0;  
            for(x=(-nCenter); x<=nCenter; x++)                     //
            {  
                            for(y=(-nCenter); y<=nCenter; y++)             //
                {  
                    if( (j+x)>=0 && (j+x)<nWidth && (i+y)>=0 && (i+y)<nHeight) //判断边缘  
                    {  
                        dFilter += (double)nImageData [(i+y)*nWidth + (j+x)]  
                            * pdKernal_2[(y+nCenter)*nWidowSize+(x+nCenter)];  
                        dSum += pdKernal_2[(y+nCenter)*nWidowSize+(x+nCenter)];  
                    }  
                }  
            }  
            pCanny[i*nWidth+j] = (unsigned char)dFilter/dSum;  
        }  
    }  

    在选择Sigma时要注意,如果选的过大,那么会加深滤波程度,这样会导致图像边缘模糊,不利于下一步的边缘检测,如果过小,则滤波效果不佳,

    参考:

    http://blog.csdn.net/likezhaobin/article/details/6892176(整个canny总览)

    http://blog.csdn.net/likezhaobin/article/details/6892629(整个canny算法步骤的细致讲解+代码)

    http://blog.csdn.net/xiaojiegege123456/article/details/7714897

    http://blog.csdn.net/likezhaobin/article/details/6835049(对opencv参数和sigma的讲解)

  • 相关阅读:
    忙碌进度条
    WPF异步调用WCF
    Oracle 数据类型及存储方式(二)
    C# 与Oracle Data Type Mappings
    【CEO来信】任正非寄语2010:开放、妥协与灰度
    数据库数据类型
    asccii 表
    SQlServer2008 表结构查询
    Oracle 数据类型及存储方式(六)
    应用特征备份
  • 原文地址:https://www.cnblogs.com/Daringoo/p/4519846.html
Copyright © 2011-2022 走看看