gaussBlur

The key is: double t = fixed_kernel ? (double)fixed_kernel[i] : std::exp(scale2X*x*x);

Gaussian formula: std::exp(scale2X*x*x);


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} }; /*如果sigma小于0,且n为不大于7的奇整数,则核的滤波系数固定了,其固定在数组 small_gaussian_tab中,根据其n的长度来选择具体的值 ,如果不满足上面的,则固定核为0 固定核为0表示自己计算其核*/ 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);//建立一个n*1的数组kernel,一个Mat矩阵包括一个矩阵头和一个指向矩阵元素的指针 float* cf = (float*)kernel.data;//定义指针cf指向kernel单精度浮点型数据 double* cd = (double*)kernel.data;//定义指针cd指向kernerl双精度浮点型数据 double sigmaX = sigma > 0 ? sigma : ((n-1)*0.5 - 1)*0.3 + 0.8;//当sigma小于0时,采用公式得到sigma(只与n有关) double scale2X = -0.5/(sigmaX*sigmaX);//高斯表达式后面要用到 double sum = 0; int i; for( i = 0; i < n; i++ ) { double x = i - (n-1)*0.5; //如果自己算其核的话,就常用公式exp(scale2X*x*x)计算,否则就用固定系数的核 double t = fixed_kernel ? (double)fixed_kernel[i] : std::exp(scale2X*x*x); if( ktype == CV_32F ) { cf[i] = (float)t;//单精度要求时存入cf数组中 sum += cf[i];//进行归一化时要用到 } else { cd[i] = t;//双精度时存入cd数组中 sum += cd[i]; } } sum = 1./sum;//归一化时核中各元素之和为1 for( i = 0; i < n; i++ ) { if( ktype == CV_32F ) cf[i] = (float)(cf[i]*sum);//归一化后的单精度核元素 else cd[i] *= sum;//归一化后的双精度核元素 } return kernel;//返回n*1的数组,其元素或是单精度或是双精度,且符合高斯分布 }
原文地址:https://www.cnblogs.com/stevenxiu/p/5591005.html