python - 如何使用 np.gradient 模拟 cv2.Sobel?
问题描述
我想在 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
功能有限,只有少数情况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
由于以下原因(我强调),必须将边框设置为零:
梯度是使用内部点的二阶精确中心差异和边界处的一阶或二阶精确单侧(前向或后向)差异计算的。
另一方面,cv2.Sobel
默认情况下,使用cv2.BORDER_REFLECT_101
,以便您始终获得0
边框。
大多数其他情况cv2.Sobel
将涉及(高斯)平滑,参见。链接的文档:
Sobel 算子结合了高斯平滑和微分,因此结果或多或少能抵抗噪声。
不能单独使用np.gradient
. 如果你想拥有它,你将cv2.Sobel
使用 NumPy 方法重写。
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
NumPy: 1.20.2
OpenCV: 4.5.1
----------------------------------------
推荐阅读
- ios - 仅在某些特定的 ViewController 中启用横向
- web-scraping - 直接使用 POST 请求 URL 时不起作用
- java - 透明的 JButton 在单击时变为浅蓝色
- java - 从集合类获取同步集合是否会同步一个类?
- java - 由于 API 问题导致应用程序崩溃
- multithreading - 如何强制在 Swift 中更新 UI?
- java - 如何检查sqlite中是否存在记录,如果存在,则更新它。?
- python - 如何创建两个单独的 pygame 显示?如果我不能,我怎么能创建两个 pygame 实例?
- selenium - Selenium 的 Chrome 驱动程序卡在黑屏中
- javascript - React Hooks - 我应该使用'useState'来表示不变的状态吗?