一、概述
该函数返回高斯滤波器系数。
该函数计算并返回 ksize×1 的高斯滤波器系数矩阵:
其中 和
是选择的比例因子,因此
。可以将两个这样的生成内核传递给 sepFilter2D。 这些函数会自动识别平滑内核(权重总和等于 1 的对称内核)并相应地处理它们。 您也可以使用更高级别的 GaussianBlur。

高斯核在 1-D、2D 和 N-D 中分别定义为
二、getGaussianKernel函数
1、函数原型
cv::getGaussianKernel (int ksize, double sigma, int ktype=CV_64F)
2、参数详解
ksize | 孔径大小。 它应该是奇数 (ksizemod2=1) 和正数。 |
sigma | 高斯标准差。 如果它是非正数,则根据 ksize 计算为 sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8。 |
ktype | 滤波器系数的类型。 它可以是 CV_32F 或 CV_64F 。 |
三、OpenCV源码
1、源码路径
opencv\modules\imgproc\src\smooth.dispatch.cpp
2、源码代码
Mat getGaussianKernel(int n, double sigma, int ktype)
{
CV_CheckDepth(ktype, ktype == CV_32F || ktype == CV_64F, "");
Mat kernel(n, 1, ktype);
std::vector<softdouble> kernel_bitexact;
getGaussianKernelBitExact(kernel_bitexact, n, sigma);
if (ktype == CV_32F)
{
for (int i = 0; i < n; i++)
kernel.at<float>(i) = (float)kernel_bitexact[i];
}
else
{
CV_DbgAssert(ktype == CV_64F);
for (int i = 0; i < n; i++)
kernel.at<double>(i) = kernel_bitexact[i];
}
return kernel;
}
static
softdouble getGaussianKernelBitExact(std::vector<softdouble>& result, int n, double sigma)
{
CV_Assert(n > 0);
//TODO: incorrect SURF implementation requests kernel with n = 20 (PATCH_SZ): https://github.com/opencv/opencv/issues/15856
//CV_Assert((n & 1) == 1); // odd
if (sigma <= 0)
{
if (n == 1)
{
result = std::vector<softdouble>(1, softdouble::one());
return softdouble::one();
}
else if (n == 3)
{
softdouble v3[] = {
softdouble::fromRaw(0x3fd0000000000000), // 0.25
softdouble::fromRaw(0x3fe0000000000000), // 0.5
softdouble::fromRaw(0x3fd0000000000000) // 0.25
};
result.assign(v3, v3 + 3);
return softdouble::one();
}
else if (n == 5)
{
softdouble v5[] = {
softdouble::fromRaw(0x3fb0000000000000), // 0.0625
softdouble::fromRaw(0x3fd0000000000000), // 0.25
softdouble::fromRaw(0x3fd8000000000000), // 0.375
softdouble::fromRaw(0x3fd0000000000000), // 0.25
softdouble::fromRaw(0x3fb0000000000000) // 0.0625
};
result.assign(v5, v5 + 5);
return softdouble::one();
}
else if (n == 7)
{
softdouble v7[] = {
softdouble::fromRaw(0x3fa0000000000000), // 0.03125
softdouble::fromRaw(0x3fbc000000000000), // 0.109375
softdouble::fromRaw(0x3fcc000000000000), // 0.21875
softdouble::fromRaw(0x3fd2000000000000), // 0.28125
softdouble::fromRaw(0x3fcc000000000000), // 0.21875
softdouble::fromRaw(0x3fbc000000000000), // 0.109375
softdouble::fromRaw(0x3fa0000000000000) // 0.03125
};
result.assign(v7, v7 + 7);
return softdouble::one();
}
else if (n == 9)
{
softdouble v9[] = {
softdouble::fromRaw(0x3f90000000000000), // 4 / 256
softdouble::fromRaw(0x3faa000000000000), // 13 / 256
softdouble::fromRaw(0x3fbe000000000000), // 30 / 256
softdouble::fromRaw(0x3fc9800000000000), // 51 / 256
softdouble::fromRaw(0x3fce000000000000), // 60 / 256
softdouble::fromRaw(0x3fc9800000000000), // 51 / 256
softdouble::fromRaw(0x3fbe000000000000), // 30 / 256
softdouble::fromRaw(0x3faa000000000000), // 13 / 256
softdouble::fromRaw(0x3f90000000000000) // 4 / 256
};
result.assign(v9, v9 + 9);
return softdouble::one();
}
}
softdouble sd_0_15 = softdouble::fromRaw(0x3fc3333333333333); // 0.15
softdouble sd_0_35 = softdouble::fromRaw(0x3fd6666666666666); // 0.35
softdouble sd_minus_0_125 = softdouble::fromRaw(0xbfc0000000000000); // -0.5*0.25
softdouble sigmaX = sigma > 0 ? softdouble(sigma) : mulAdd(softdouble(n), sd_0_15, sd_0_35);// softdouble(((n-1)*0.5 - 1)*0.3 + 0.8)
softdouble scale2X = sd_minus_0_125/(sigmaX*sigmaX);
int n2_ = (n - 1) / 2;
cv::AutoBuffer<softdouble> values(n2_ + 1);
softdouble sum = softdouble::zero();
for (int i = 0, x = 1 - n; i < n2_; i++, x+=2)
{
// x = i - (n - 1)*0.5
// t = std::exp(scale2X*x*x)
softdouble t = exp(softdouble(x*x)*scale2X);
values[i] = t;
sum += t;
}
sum *= softdouble(2);
//values[n2_] = softdouble::one(); // x=0 in exp(softdouble(x*x)*scale2X);
sum += softdouble::one();
if ((n & 1) == 0)
{
//values[n2_ + 1] = softdouble::one();
sum += softdouble::one();
}
// normalize: sum(k[i]) = 1
softdouble mul1 = softdouble::one()/sum;
result.resize(n);
softdouble sum2 = softdouble::zero();
for (int i = 0; i < n2_; i++ )
{
softdouble t = values[i] * mul1;
result[i] = t;
result[n - 1 - i] = t;
sum2 += t;
}
sum2 *= softdouble(2);
result[n2_] = /*values[n2_]*/ softdouble::one() * mul1;
sum2 += result[n2_];
if ((n & 1) == 0)
{
result[n2_ + 1] = result[n2_];
sum2 += result[n2_];
}
return sum2;
}