我正在努力实现计算的高斯内核以返回模糊图像。 我当前计算内核的代码如下:
const int m = 5;
const int n = 5;
double sigma = std;
Mat Gauss;
double kernel[m][n];
for ( int x = 0; x < m; ++x )
for ( int y = 0; y < n; ++y )
{
kernel[x][y] = (1 / (sigma * (sqrt(2 * M_PI))))
* exp(-0.5 * (std::pow((x - avg) / sigma, 2.0)
+ pow((y - avg) / sigma, 2.0) ) / (2 * M_PI * sigma * sigma));
}
然而,我无法弄清楚如何将这个应用于图像,使我返回模糊的图像。 如果有人能以一种我可以将其应用于图像的方式给我一些指示,我将不胜感激。
我正在考虑使用for循环来替换原始图像的像素,但我无法正确实现这个想法。 谢谢你的时间。
答案 0 :(得分:0)
听起来你想要用高斯内核计算原始图像的卷积,如下所示:
模糊[x] [y] =积分(内核[s] [t] *原始[x-s] [y-t])ds dt
有很多技巧:
直接卷积:遍历网格并在每个点计算上述积分。这适用于支持非常小的内核,每个方向上有5个网格点,但对于支持较大的内核来说,速度太慢。对于高斯核,截断支持的经验法则约为3 * sigma,因此在2格点下使用sigma进行直接卷积并非不合理。
快速傅里叶变换(FFT)。这适用于任何内核都很合理。因此,FFT成为几乎任何东西计算几乎任何东西卷积的标准方法。直接卷积仅针对内核支持FFT,支持非常小。
分析:某些内核的积分具有解析表达式。特别是,Gaussian的积分是Erf函数,至少在Unix系统上,它可以作为函数调用使用。此外,在某些硬件(如GPU)上,Erf以硬件实现。在一些罕见(但很重要)粗糙双层图像的情况下,可以用高斯函数调用循环代替卷积。
对于大多数计算系统而言,最好的选择是使用FFT:它速度快,而且足够灵活,能够正确处理任何内核和图像。