【问题标题】:How do you implement a calculated Gaussian kernel?你如何实现计算的高斯核?
【发布时间】:2013-09-15 19:33:54
【问题描述】:

我正在努力实现计算高斯核以返回模糊图像的能力。 我当前计算内核的代码如下:

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 循环来替换原始图像的像素,但我无法正确实现这个想法。 感谢您的宝贵时间。

【问题讨论】:

标签: c++ opencv blur gaussian


【解决方案1】:

听起来您想计算原始图像与高斯核的卷积,如下所示:

blurred[x][y] = 积分 (kernel[s][t] * original[x-s][y-t]) ds dt

有很多技术可以做到这一点:

  1. 直接卷积:通过网格并计算每个点的上述积分。这适用于支持非常小的内核,在每个方向上大约 5 个网格点,但对于支持较大的内核变得太慢了。对于高斯核,截断支持的经验法则约为 3*sigma,因此在 2 个网格点下使用 sigma 进行直接卷积并非不合理。

  2. 快速傅里叶变换 (FFT)。这对任何内核都可以合理地快速运行。因此,FFT 成为计算几乎任何东西与几乎任何东西的卷积的标准方法。直接卷积仅在支持非常小的内核上优于 FFT。

  3. 解析:某些内核的积分具有解析表达式。特别是,高斯积分是 Erf 函数,至少在 Unix 系统上,它可以作为函数调用使用。此外,在某些硬件(例如 GPU)上,Erf 是在硬件中实现的。在一些罕见(但重要)的粗略双层图像的情况下,可以使用循环 Erf 函数调用用高斯替换卷积。

对于大多数计算系统,最好的选择是使用 FFT:它速度快,而且足够灵活,可以正确处理任何内核和图像。

【讨论】:

    猜你喜欢
    • 2012-01-02
    • 2015-08-28
    • 1970-01-01
    • 2015-11-13
    • 2021-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多