【问题标题】:How to normalize OpenCV Sobel filter given kernel size如何在给定内核大小的情况下标准化 OpenCV Sobel 滤波器
【发布时间】:2018-06-07 20:01:17
【问题描述】:

在给定内核大小的情况下,如何调用 OpenCV Sobel 函数来计算图像的实际导数? IE。考虑到图像是f(x, y)x, y 的函数,范围从[0, 0][width, height],以像素为单位?

dimg_x = cv2.Sobel(img, ddepth=-1, dx=1, dy=0, ksize=ksize)

可能需要对渐变图像应用一些缩放,但我不知道如何在给定内核大小的情况下计算它。

【问题讨论】:

  • Sobel 梯度是梯度的近似值。所以,这取决于你所说的“实际”衍生品是什么。所有数值方法都是近似值。在某些时候,您可以简单地分别获取行和列的水平或垂直方向的差异。
  • @Cyb3rFly3r 通过“实际”我的意思是定义。我可以,这是一个近似值,但对于某些应用程序,它被缩放 100 倍是不可接受的。
  • 导数的定义需要一个连续函数,这是数字图像中没有的,它是一些不可知函数的离散表示。有很多方法可以尝试近似梯度,可能 Sobel 不是您想要的。最简单的方法之一是沿列和行使用 numpy.diff。
  • @Cyb3rFly3r 沿行和列的差异是导数的一阶近似,考虑到基础函数是线性的。它很粗糙,容易受到噪音等影响。这就是为什么我使用更大的 sobel 内核来获得导数。但是它们在 OpenCV 中没有被规范化,所以我正在寻找一种方法来规范化它们。如果您在 OpenCV 上查看有限差分系数 (en.wikipedia.org/wiki/Finite_difference_coefficient) 和 Sobel 内核中的系数,您会发现它们差别很大。
  • 当然,这就是我想要表达的观点,可能没有很好地解释;您可以使用有限差分滤波器。例如 opencv createDerivFilter 来做到这一点。 Sobel 并没有什么不同,只是没有标准化。

标签: python opencv


【解决方案1】:

您可以使用Sobelscale 参数:

cv2.Sobel(img, dx=dx, dy=dy, ksize=ksize, scale=2**(2+dx+dy-ksize*2), ddepth=CV_32F)

当您以这种方式缩放输出时,您通常想要ddepth=-1,而是希望得到浮点数或双精度数的结果。

【讨论】:

    【解决方案2】:

    我认为这个 sn-p 可以解决问题:

    def gradient(img, dx, dy, ksize):
        deriv_filter = cv2.getDerivKernels(dx=dx, dy=dy, ksize=ksize, normalize=True)
        return cv2.sepFilter2D(img, -1, deriv_filter[0], deriv_filter[1])
    

    【讨论】:

      猜你喜欢
      • 2012-03-22
      • 2019-03-29
      • 1970-01-01
      • 2015-10-22
      • 2012-10-05
      • 2020-09-10
      • 2021-01-07
      • 1970-01-01
      • 2017-06-20
      相关资源
      最近更新 更多