zoukankan      html  css  js  c++  java
  • opencv源码学习: getGaussianKernel( 高斯核);

    参考: https://blog.csdn.net/u012633319/article/details/80921023

    二维高斯核, 可以根据下面的公式推到为两个一维高斯核的乘积:

    原型:

    /** @brief Returns Gaussian filter coefficients.
    
    The function computes and returns the f$	exttt{ksize} 	imes 1f$ matrix of Gaussian filter
    coefficients:
    
    f[G_i= alpha *e^{-(i-( 	exttt{ksize} -1)/2)^2/(2* 	exttt{sigma}^2)},f]
    
    where f$i=0..	exttt{ksize}-1f$ and f$alphaf$ is the scale factor chosen so that f$sum_i G_i=1f$.
    
    Two of such generated kernels can be passed to sepFilter2D. Those functions automatically recognize
    smoothing kernels (a symmetrical kernel with sum of weights equal to 1) and handle them accordingly.
    You may also use the higher-level GaussianBlur.
    @param ksize Aperture size. It should be odd ( f$	exttt{ksize} mod 2 = 1f$ ) and positive.
    @param sigma Gaussian standard deviation. If it is non-positive, it is computed from ksize as
    `sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8`.
    @param ktype Type of filter coefficients. It can be CV_32F or CV_64F .
    @sa  sepFilter2D, getDerivKernels, getStructuringElement, GaussianBlur
     */
    CV_EXPORTS_W Mat getGaussianKernel( int ksize, double sigma, int ktype = CV_64F );

    源码分析:

    cv::Mat cv::getGaussianKernel( int n, double sigma, int ktype )
    {
        const int SMALL_GAUSSIAN_SIZE = 7;
        static const float small_gaussian_tab[][SMALL_GAUSSIAN_SIZE] =
        {
            {1.f},
            {0.25f, 0.5f, 0.25f},
            {0.0625f, 0.25f, 0.375f, 0.25f, 0.0625f},
            {0.03125f, 0.109375f, 0.21875f, 0.28125f, 0.21875f, 0.109375f, 0.03125f}
        };
    
        //判断是否满足预置的高斯模板;
        const float* fixed_kernel = n % 2 == 1 && n <= SMALL_GAUSSIAN_SIZE && sigma <= 0 ?
            small_gaussian_tab[n>>1] : 0;
    
        CV_Assert( ktype == CV_32F || ktype == CV_64F );          //仅支持两种格式,  32, 64位;
        Mat kernel(n, 1, ktype);                  //创建核模板, ktype为指定的类型;
        float* cf = kernel.ptr<float>();
        double* cd = kernel.ptr<double>();
        //如果sigma < 0, 那么更具模板尺寸计算sigma;
        double sigmaX = sigma > 0 ? sigma : ((n-1)*0.5 - 1)*0.3 + 0.8;
        double scale2X = -0.5/(sigmaX*sigmaX);
        double sum = 0;
    
        int i;
        for( i = 0; i < n; i++ )
        {
            double x = i - (n-1)*0.5;
            double t = fixed_kernel ? (double)fixed_kernel[i] : std::exp(scale2X*x*x);                //使用预置模板或者根据高斯函数计算高斯模板;
            if( ktype == CV_32F )          //把计算得到的核填到模板中;
            {
                cf[i] = (float)t;
                sum += cf[i];
            }
            else
            {
                cd[i] = t;
                sum += cd[i];
            }
        }
    
        sum = 1./sum;
        for( i = 0; i < n; i++ )            //归一化;
        {
            if( ktype == CV_32F )
                cf[i] = (float)(cf[i]*sum);
            else
                cd[i] *= sum;
        }
    
        return kernel;
    }
  • 相关阅读:
    sql学习笔记
    正则表达式30分钟入门教程(转) 收藏
    学习Javascript闭包(Closure)
    Bug等级规范
    下载1G的东西用1M网速理论上要用多长时间?
    C#多线程学习(四) 多线程的自动管理(线程池)
    JS调用WebServers
    北京软件公司排名
    Js调用WebServices
    C#多线程学习(三) 生产者和消费者
  • 原文地址:https://www.cnblogs.com/yinwei-space/p/9833440.html
Copyright © 2011-2022 走看看