Python 如何在给定内核大小的情况下规范化OpenCV Sobel过滤器

Python 如何在给定内核大小的情况下规范化OpenCV Sobel过滤器,python,opencv,Python,Opencv,在给定内核大小的情况下,如何调用OpenCV Sobel函数来计算图像的实际导数?也就是说,考虑到图像是f(x,y)的函数,x,y以像素为单位从[0,0]到[width,height] dimg_x = cv2.Sobel(img, ddepth=-1, dx=1, dy=0, ksize=ksize) 可能需要对渐变图像应用一些缩放,但我不知道如何在给定内核大小的情况下计算它。我认为这段代码可以实现以下目的: def gradient(img, dx, dy, ksize): der

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

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

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

我认为这段代码可以实现以下目的:

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])

您可以使用
Sobel
scale
参数:

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

当您以这种方式缩放输出时,通常不希望使用
ddepth=-1
,而是将结果作为浮点或双精度运算。

Sobel渐变是渐变的近似值。所以,这取决于你称之为“实际”导数的是什么。所有的数值方法都是近似的。在某一点上,您可以简单地分别计算行和列的水平或垂直方向上的差异。@Cyb3rFly3r所说的“实际”是指定义。我同意这是一个近似值,但对于某些应用来说,它的比例是100倍是不可接受的。导数的定义需要一个连续函数,这是数字图像中没有的,它是一些未知函数的离散表示。有很多方法可以尝试近似梯度,也许索贝尔不是你们想要的。最简单的方法之一是沿列和行使用numpy.diff。@考虑到基础函数是线性的,沿行和列的Cyb3rFly3r差是导数的一阶近似值。它是粗糙的,易受噪音影响等。这就是为什么我使用更大的索贝尔核来获得导数。但是它们在OpenCV中没有标准化,所以我正在寻找一种方法来标准化它们。如果你看看OpenCV上的有限差分系数()和Sobel内核中的系数,你会发现它们差别很大;您可以使用有限差分过滤器。例如,opencv
createDerivFilter
就可以做到这一点。没有什么不同,只是没有正常化。