【问题标题】:Does cv2.Canny() perform a Gaussian blur?cv2.Canny() 是否执行高斯模糊?
【发布时间】:2020-12-12 00:44:36
【问题描述】:

我知道在使用 Canny 检测边缘之前对图像应用高斯模糊非常重要。我的问题是:cv2.Canny() 自己做高斯模糊还是有必要在cv2.Canny() 之前应用cv2.GaussianBlur()?文档在这一点上并不清楚。

【问题讨论】:

    标签: python opencv image-processing edge-detection canny-operator


    【解决方案1】:

    回想一下,在 Python 中使用 OpenCV 实际上是 OpenCV 的 C++ 接口的包装器。 Canny 边缘检测算法在 C++ 中的实现文件可以在这里找到:https://github.com/opencv/opencv/blob/master/modules/imgproc/src/canny.cpp

    如果您检查此来源,您会发现图像上没有进行任何模糊处理。然而,由于 Yves Daoust 的修正(见下文),Sobel 边缘检测算法被用于寻找梯度。有一个aperture 输入参数指定Sobel 内核的大小。使用默认值意味着您使用的是 3 x 3 内核并且没有应用模糊。但是,任何高于 3 x 3 的东西都将使用高斯核。因此,如果您想使用默认的 Sobel 内核,您需要自己应用模糊。如果您改变 Sobel 内核的大小,您不必自己执行模糊操作。

    事实上,在他们演示使用 Canny 的官方 OpenCV 教程中,图像在检测之前被手动模糊:https://docs.opencv.org/3.4/da/d5c/tutorial_canny_detector.html。但是,由于您使用的是 3 x 3 Sobel 内核,因此他们在算法之前使用了 3 x 3 框过滤器。

    tl;dr - 如果您决定使用默认孔径/Sobel 内核大小,则需要在使用 Canny 边缘检测算法之前自行模糊图像。如果大于 3,则不必模糊图像。

    【讨论】:

    • ...这有点可悲,因为 Canny 在他的开创性论文中表明,高斯梯度是计算导数的最佳选择,但大多数实现要么使用高斯模糊和 Sobel 滤波器,要么跳过高斯完全模糊。 OpenCV 总是优先考虑速度而不是精度,甚至是正确性。
    • 该教程非常具有误导性。它提倡使用 5x5 高斯内核,尽管代码使用 3x3 框过滤器并使用 3x3 孔径调用 Canny!
    • @YvesDaoust 感谢有关文档的提示 - 如果您在 Canny 中选择 3 x 3 Sobel 内核,它会进行高斯平滑,所以现在对我来说很有意义关于为什么他们会提前进行预平滑......但是,他们绝对应该使用高斯内核。这些文档需要更新。
    • @rayryeng:高斯模糊和Sobel中的模糊差别很小。
    • @Yves 高斯和 Sobel 中的模糊有很多区别。 Sobel 核在与导数垂直的方向上使用 3-tab 三角形核,并且在导数方向上没有模糊。我不知道是谁提出了更大的 Sobel 内核扩展,或者它们是如何设计的。但是它们不是 Sobel 内核,Sobel 描述了一个 3x3 内核,不要去给这个人分配其他随机的东西!
    【解决方案2】:

    Cannyaperture 参数控制 Sobel 滤波器的大小(从 1 到 7 ?),它实际上在求导之前应用了低通滤波器。不幸的是,尽管引用了高斯滤波器,但文档并未明确说明该低通滤波器。

    我敢打赌,实际上使用了二项式滤波器(它非常近似于高斯)。

    【讨论】:

      猜你喜欢
      • 2020-10-09
      • 2018-05-01
      • 1970-01-01
      • 2017-08-27
      • 2015-11-05
      • 1970-01-01
      • 1970-01-01
      • 2016-04-30
      • 2011-12-07
      相关资源
      最近更新 更多