如何使用np.gradient模仿cv2.Sobel?
How to mimic cv2.Sobel using np.gradient?
我想得到x轴和y轴方向的图像。但是,我想使用 np.gradient
函数进行编码,而不使用 cv2.Sobel
过滤器。
所以,我想像这样转换代码
x_grad = cv2.Sobel(image1, cv2.CV_64F, 1, 0, ksize=5)
像这样
x_grad = np.gradient(image1, axis=0)
但是,数值不一样。我该如何解决?
np.gradient
has limited functionality, and only a few cases of cv2.Sobel
可以以某种方式复制,即:
import cv2
import numpy as np
image = cv2.imread('path/to/your/image.png', cv2.IMREAD_GRAYSCALE)
grad_cv2 = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=1)
grad_np = 2 * np.gradient(image, axis=1)
grad_np[:, [0, -1]] = 0
print(np.all(grad_cv2 == grad_np))
# True
grad_cv2 = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=1)
grad_np = 2 * np.gradient(image, axis=0)
grad_np[[0, -1], :] = 0
print(np.all(grad_cv2 == grad_np))
# True
grad_cv2 = cv2.Sobel(image, cv2.CV_64F, 1, 1, ksize=3)
grad_np = 2 * np.gradient(2 * np.gradient(image, axis=1), axis=0)
grad_np[:, [0, -1]] = 0
grad_np[[0, -1], :] = 0
print(np.all(grad_cv2 == grad_np))
# True
需要系数 2
,因为默认情况下 np.gradient
除以 2
。
必须将边框设置为零,因为以下原因(我强调):
The gradient is computed using second order accurate central differences in the interior points and either first or second order accurate one-sides (forward or backwards) differences at the boundaries.
另一方面,cv2.Sobel
默认情况下使用 cv2.BORDER_REFLECT_101
,因此您总是得到 0
作为边框。
大多数其他 cv2.Sobel
的情况将涉及(高斯)平滑,参见。链接文档:
The Sobel operators combine Gaussian smoothing and differentiation, so the result is more or less resistant to the noise.
不能单独使用 np.gradient
进行攻击。如果你想拥有它,你将使用 NumPy 方法重写 cv2.Sobel
。
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
NumPy: 1.20.2
OpenCV: 4.5.1
----------------------------------------
我想得到x轴和y轴方向的图像。但是,我想使用 np.gradient
函数进行编码,而不使用 cv2.Sobel
过滤器。
所以,我想像这样转换代码
x_grad = cv2.Sobel(image1, cv2.CV_64F, 1, 0, ksize=5)
像这样
x_grad = np.gradient(image1, axis=0)
但是,数值不一样。我该如何解决?
np.gradient
has limited functionality, and only a few cases of cv2.Sobel
可以以某种方式复制,即:
import cv2
import numpy as np
image = cv2.imread('path/to/your/image.png', cv2.IMREAD_GRAYSCALE)
grad_cv2 = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=1)
grad_np = 2 * np.gradient(image, axis=1)
grad_np[:, [0, -1]] = 0
print(np.all(grad_cv2 == grad_np))
# True
grad_cv2 = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=1)
grad_np = 2 * np.gradient(image, axis=0)
grad_np[[0, -1], :] = 0
print(np.all(grad_cv2 == grad_np))
# True
grad_cv2 = cv2.Sobel(image, cv2.CV_64F, 1, 1, ksize=3)
grad_np = 2 * np.gradient(2 * np.gradient(image, axis=1), axis=0)
grad_np[:, [0, -1]] = 0
grad_np[[0, -1], :] = 0
print(np.all(grad_cv2 == grad_np))
# True
需要系数 2
,因为默认情况下 np.gradient
除以 2
。
必须将边框设置为零,因为以下原因(我强调):
The gradient is computed using second order accurate central differences in the interior points and either first or second order accurate one-sides (forward or backwards) differences at the boundaries.
另一方面,cv2.Sobel
默认情况下使用 cv2.BORDER_REFLECT_101
,因此您总是得到 0
作为边框。
大多数其他 cv2.Sobel
的情况将涉及(高斯)平滑,参见。链接文档:
The Sobel operators combine Gaussian smoothing and differentiation, so the result is more or less resistant to the noise.
不能单独使用 np.gradient
进行攻击。如果你想拥有它,你将使用 NumPy 方法重写 cv2.Sobel
。
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
NumPy: 1.20.2
OpenCV: 4.5.1
----------------------------------------