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;
    }
  • 相关阅读:
    ES6走一波 Generator异步应用
    扁平数据结构化
    Django笔记&教程 6-2 表单(Form)基础操作
    Django笔记&教程 6-3 使用模型(models)创建表单(form)
    Django笔记&教程 6-4 forms进阶操作,重写forms方法
    Django笔记&教程 7-1 基于类的视图(Class-based views)介绍
    Django笔记&教程 7-3 拓展CBVs(Class-based views)
    Django笔记&教程 5-1 基础增删查改
    Django笔记&教程 1-1 一 新建项目
    Django笔记&教程 0-2 框架版本与相关工具
  • 原文地址:https://www.cnblogs.com/yinwei-space/p/9833440.html
Copyright © 2011-2022 走看看