OpenCV(cv::GaussianBlur())



cv::GaussianBlur() 是 OpenCV 中常用的图像模糊函数之一。它使用高斯滤波器对图像进行平滑处理。高斯模糊通过给不同的像素赋予不同的权重来平滑图像,常用于减少图像中的噪声和细节,同时比均值模糊更好地保留图像的边缘。



1. 函数定义

void cv::GaussianBlur(
    InputArray src,    // 输入图像
    OutputArray dst,   // 输出图像
    Size ksize,        // 滤波器的核大小 (宽度和高度)
    double sigmaX,     // X方向的高斯核标准差
    double sigmaY = 0, // Y方向的高斯核标准差,默认为0
    int borderType = BORDER_DEFAULT  // 边界类型
);

参数:

  1. src (输入图像):

    • 输入的图像可以是 1 通道(灰度图)或 3 通道(彩色图),类型可以是 8 位、16 位或 32 位浮点数类型。
  2. dst (输出图像):

    • 与输入图像具有相同的大小和类型,存储高斯模糊后的图像。
  3. ksize (核大小):

    • 高斯核的大小 Size(kwidth, kheight) 决定滤波器的尺寸。核的宽度和高度必须是正数并且是奇数(如 3, 5, 7 等)。
    • 核的大小越大,模糊效果越强。通常在模糊较大图像时使用较大的核。
  4. sigmaX (X 方向的标准差):

    • 用于高斯函数在 X 方向的标准差值,决定了 X 方向上的模糊程度。
    • 如果 sigmaX 设置为 0,OpenCV 会根据核大小自动计算合适的 sigma 值。
  5. sigmaY (Y 方向的标准差,默认为 0):

    • 用于高斯函数在 Y 方向的标准差值。若设置为 0,函数会将 sigmaY 设置为与 sigmaX 相同的值。
    • 可以单独指定 X 和 Y 方向的模糊程度。如果你想要各向同性模糊(即 X 和 Y 方向模糊程度相同),可以仅设置 sigmaXsigmaY 保持为 0。
  6. borderType (边界类型):

    • 用来指定当滤波器核接触到图像边缘时如何处理边界。常见的值包括:
      • BORDER_CONSTANT: 用常数填充边界像素。
      • BORDER_REPLICATE: 重复边界像素。
      • BORDER_REFLECT: 反射边界。
      • BORDER_WRAP: 用对面图像的像素填充边界。
      • BORDER_DEFAULT 默认使用 BORDER_REFLECT_101


2. 高斯模糊原理

2.1 高斯核\((3 \times 3)\)

假设我们有一个大小为 \((5 \times 5)\) 的图像,并且使用 \((3 \times 3)\) 的高斯核进行高斯模糊。


2.1.1 高斯核的创建

首先,我们需要生成一个 \((3 \times 3)\) 的高斯核。假设标准差 \(\sigma\) 为 1。高斯核的计算公式为:

\[G(x, y) = \frac{1}{2\pi\sigma^2} e^{-\frac{x^2 + y^2}{2\sigma^2}} \]

假设高斯核的值如下:

\[\text{Kernel} = \begin{bmatrix} 0.0751 & 0.1238 & 0.0751 \\ 0.1238 & 0.2042 & 0.1238 \\ 0.0751 & 0.1238 & 0.0751 \\ \end{bmatrix} \ \]

这些值是通过上述公式计算得到的,用来加权周围的像素。


2.1.2 卷积操作

对图像进行高斯模糊时,我们使用高斯核对图像的每个像素进行卷积操作。假设原图像 (I) 的像素值如下:

\[I = \begin{bmatrix} 10 & 20 & 30 & 40 & 50 \\ 60 & 70 & 80 & 90 & 100 \\ 110 & 120 & 130 & 140 & 150 \\ 160 & 170 & 180 & 190 & 200 \\ 210 & 220 & 230 & 240 & 250 \\ \end{bmatrix} \ \]

我们将高斯核在图像上滑动,计算每个位置的加权平均值。以下是计算步骤:

  1. 选择一个位置

    • 比如我们选择图像中心位置 \((3, 3)\)(即像素值 \(130\)),将高斯核的中心对准该位置。
  2. 提取 \(3 \times 3\) 区域

    • 在位置 \((3, 3)\) 上提取图像的 \(3 \times 3\) 区域:

    \[\text{Region} = \begin{bmatrix} 70 & 80 & 90 \\ 120 & 130 & 140 \\ 170 & 180 & 190 \\ \end{bmatrix} \]

    其中:

    \[\text{Sum} = 0.0751 + 0.1238 + 0.0751 + 0.1238 + 0.2042 + 0.1238 + 0.0751 + 0.1238 + 0.0751 = 0.9998 \]

  3. 计算加权和

    • 将高斯核的每个值与对应的像素值相乘,然后求和:

    \[\text{Blurred Value} = (0.0751 \times 70) + (0.1238 \times 80) + (0.0751 \times 90) \\ + (0.1238 \times 120) + (0.2042 \times 130) + (0.1238 \times 140) \\ + (0.0751 \times 170) + (0.1238 \times 180) + (0.0751 \times 190) \]

    计算得到:

    \[\text{Blurred Value} \approx 70 \times 0.0751 + 80 \times 0.1238 + 90 \times 0.0751 \\ + 120 \times 0.1238 + 130 \times 0.2042 + 140 \times 0.1238 \\ + 170 \times 0.0751 + 180 \times 0.1238 + 190 \times 0.0751 \]

    \[\text{Blurred Value} \approx 5.257 + 9.904 + 6.759 + 14.856 + 26.546 + 17.332 + 12.768 + 22.284 + 14.272 \approx 129.29 \]

    所以,模糊后图像在该位置的值为大约 129。


2.1.3 边界处理

对于边界像素(例如,图像的边缘),由于高斯核会超出图像边界,通常需要进行填充(如零填充)来处理这些边界情况。


2.1.4 完成模糊处理

将上述步骤应用于图像的每个位置,计算所有像素的新值。最终得到的图像将是原图像的高斯模糊版本。


2.1.5 总结

高斯模糊通过加权平均图像中每个像素的值来实现。使用高斯函数计算的权重值确保了每个像素周围的像素在模糊处理中起到了不同的作用,中心像素的权重最大,远离中心的像素权重逐渐减小。这种方法有效地减少了图像的细节和噪声,使图像变得更平滑。


2.2 高斯核\((5 \times 5)\)

一个 \(5 \times 5\)的高斯核可以用来进行图像平滑处理。下面是一个示例高斯核,假设标准差 \(\sigma\)\(1\)

$G(x, y) = \frac{1}{2\pi\sigma^2} e{-\frac{x2 + y2}{2\sigma2}} $

标准差 \(\sigma = 1\) 时的高斯核如下:

\[\text{Kernel} = \begin{bmatrix} 0.0039 & 0.0156 & 0.0235 & 0.0156 & 0.0039 \\ 0.0156 & 0.0625 & 0.0938 & 0.0625 & 0.0156 \\ 0.0235 & 0.0938 & 0.1406 & 0.0938 & 0.0235 \\ 0.0156 & 0.0625 & 0.0938 & 0.0625 & 0.0156 \\ 0.0039 & 0.0156 & 0.0235 & 0.0156 & 0.0039 \\ \end{bmatrix} \]



3. 示例

#include <opencv2/opencv.hpp>

int main() {
    // 读取输入图像
    cv::Mat src = cv::imread("input.jpg");
    cv::Mat dst;

    // 使用5x5的高斯滤波器模糊处理,sigmaX=1.0
    cv::GaussianBlur(src, dst, cv::Size(5, 5), 1.0);

    // 显示结果
    cv::imshow("Original Image", src);
    cv::imshow("Gaussian Blurred Image", dst);

    cv::waitKey(0);
    return 0;
}


4. 高斯核的生成

高斯核由 ksizesigma 参数决定。ksize 控制滤波器核的大小,sigma 控制模糊的程度。较大的 sigma 值意味着更强的模糊,而较小的 sigma 值会更精确地保留图像细节。

sigmaXsigmaY 设置为 0 时,OpenCV 会自动根据核大小计算合理的标准差。计算方式为:

  • 对于 3x3 的核,默认的 sigma0.8
  • 对于 5x5 的核,默认的 sigma1.0

如果想让模糊程度仅沿着一个方向增加(如 X 方向比 Y 方向更模糊),可以单独设置 sigmaXsigmaY



5. 高斯模糊的应用场景

  1. 噪声去除:

    • 高斯模糊可以有效地去除图像中的随机噪声,而不会像均值滤波器那样过度模糊边缘。它常用于预处理图像,减少噪声对后续图像处理任务的影响。
  2. 图像平滑:

    • 高斯模糊可用于图像平滑,使得图像显得更加柔和。相比于 cv::blur(),高斯模糊可以更好地保留图像细节,尤其是边缘。
  3. 边缘检测前的预处理:

    • 高斯模糊常用于边缘检测前的预处理,以减少检测到伪边缘的可能性。经典的 Canny 边缘检测算法中,首先要对图像应用高斯模糊以去除噪声。
  4. 多尺度图像处理:

    • 在图像金字塔、图像缩放以及尺度空间处理(如 SIFT 特征检测算法)中,高斯模糊用于生成不同尺度的图像版本,提取图像中的不同层次的特征。


6. 高斯模糊与其他模糊方式的对比

  1. cv::blur() 的比较:

    • cv::blur() 是均值滤波器,给每个像素赋予相等的权重,所以会模糊掉图像的边缘。均值滤波器简单,但在去除噪声的同时也会过度平滑图像。
    • cv::GaussianBlur() 根据高斯分布给像素赋予不同权重,距离中心越远,权重越小。这种方式可以有效去除噪声,同时保留更多的边缘细节。
  2. cv::medianBlur() 的比较:

    • cv::medianBlur() 是非线性滤波器,它通过替换窗口内像素的中值来去除噪声,尤其在去除椒盐噪声时效果显著。而高斯模糊对于高斯噪声更加有效,但在椒盐噪声的处理上效果不如中值滤波。
    • cv::GaussianBlur() 更适合处理高斯噪声和一般的图像平滑任务,而 cv::medianBlur() 更适合处理图像中出现的极端噪声。


7. 总结

  • cv::GaussianBlur() 使用高斯滤波器进行平滑处理,是一种有效的去噪和图像平滑技术。它通过对中心像素赋予较高权重,对周围像素赋予较低权重,能够在平滑图像的同时保留边缘信息。
  • 它适用于边缘检测前的预处理、图像去噪、多尺度图像处理等场景,相较于均值模糊,能够更加自然地模糊图像而不丢失太多细节。
  • 参数 ksizesigmaX/sigmaY 的选择对高斯模糊效果至关重要,通常较大的 sigma 和核会使图像模糊更严重,而较小的 sigma 值则会更好地保留细节。


posted @ 2024-09-14 09:16  做梦当财神  阅读(473)  评论(0编辑  收藏  举报