Python 如何使用OpenCV将渐变/幅度应用于图像?
目前,我正在跟随一项大学作业,在该作业中,我们应该自己实施canny边缘检测。应用高斯模糊没有任何问题,但现在我试图显示网站上显示的强度大小 我实现了上述网站上的功能,并创建了运行canny边缘检测的功能。目前,该函数是这样的:Python 如何使用OpenCV将渐变/幅度应用于图像?,python,opencv,edge-detection,canny-operator,sobel,Python,Opencv,Edge Detection,Canny Operator,Sobel,目前,我正在跟随一项大学作业,在该作业中,我们应该自己实施canny边缘检测。应用高斯模糊没有任何问题,但现在我试图显示网站上显示的强度大小 我实现了上述网站上的功能,并创建了运行canny边缘检测的功能。目前,该函数是这样的: def canny_edge(img): noise_reduction = cv.filter2D(img, -1, gaussian_kernel(5)) cv.imshow('Blur', noise_reduction) magnitud
def canny_edge(img):
noise_reduction = cv.filter2D(img, -1, gaussian_kernel(5))
cv.imshow('Blur', noise_reduction)
magnitude, gradient = sobel_filters(img)
magnitude = magnitude.astype(np.uint8)
sobel = magnitude * gradient
sobel = sobel.astype(np.uint8)
test = img + (255 - gradient * noise_reduction)
plt.imshow(gradient, cmap='gray')
plt.show()
cv.imshow('Gradient', magnitude)
cv.imshow('Original Image', img)
我必须将震级和sobel数组转换为np.uint8
,否则它们将包含float
值,从而导致显示图像时出错。目前,我正在使用变量test
尝试各种方法,比如梯度-降噪
,上面的线条等等。问题是我总是得到与这些类似的图像(左侧图像显示测试
,右侧图像显示梯度
,底部图像显示幅度
):
我不太熟悉所有可用的OpenCV函数,但我想可能需要使用其中一些我不知道的函数来实现此目的。不幸的是,我无法在教程链接中找到有关如何将
sobel\u filters
函数返回的幅值应用于图像的任何信息以上是ed。提前感谢您对如何解决此问题的任何意见。我认为ndimage.filters.convalve可能存在问题。我得到了与您类似的结果。但是使用Python/OpenCV,以下内容似乎可以很好地工作
输入:
震级:
方向:
我想你可能需要在
.astype(np.uint8)
之前添加.clip(0255)
。看起来你得到了强度环绕。好的,我加入了震级=震级。clip(0255)
直接将数组转换为np.uint8
之前,我仍然得到相同的结果,因此我想这不是问题所在。我还假设.clip(0255)
只是确保值介于0和255之间,但据我记忆所及,如果值高于255,OpenCV还会向控制台打印一条警告,并说明如何在255处自动剪裁值。不过还是要感谢您的这一想法。提供了什么工具或代码sobel_filters()
?这会给出sobel梯度的x和y分量还是大小和方向?您将输出标记为大小和梯度。对于sobel操作来说,这似乎不正确,因为sobel操作通常只提供梯度的x和y分量。该函数在我链接的网站上定义。如果我了解该网站正确地说,它在x和y方向应用Sobel运算符,并返回“梯度的幅值G和斜率θ”。至少这是直接写在代码段上方的内容,实际上对应于返回的变量。由于变量是根据数学公式计算的,梯度的大小及其方向应该是函数提供的。这一切似乎都是正确的。您是否查看了每个步骤以确保结果看起来合理?我可以让scipy.ndimage.convolve给出类似的结果。您需要使输入图像浮动,或者至少在高斯滤波器工作后我这样做了。另一个注释。OpenCV的filter2D不进行相关而不是真正的卷积。因此在scipy中,您需要使用correlate不卷积得到相似的极性,这只会影响方向,而不会影响大小。
import cv2
import numpy as np
import skimage.exposure
img = cv2.imread('black_dress.png', cv2.IMREAD_GRAYSCALE)
img = cv2.GaussianBlur(img, (0,0), sigmaX=1.5, sigmaY=1.5)
Kx = np.array([[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]])
Ky = np.array([[1, 2, 1],
[0, 0, 0],
[-1, -2, -1]])
Ix = cv2.filter2D(img, -1, Kx)
Iy = cv2.filter2D(img, -1, Ky)
G = np.hypot(Ix, Iy)
G = skimage.exposure.rescale_intensity(G, in_range='image', out_range=(0,255)).astype(np.uint8)
theta = np.arctan2(Iy, Ix)
theta = skimage.exposure.rescale_intensity(theta, in_range='image', out_range=(0,255)).astype(np.uint8)
cv2.imwrite('black_dress_gradient_magnitude.png', G)
cv2.imwrite('black_dress_gradient_direction.png', theta)
cv2.imshow("magnitude", G)
cv2.imshow("direction", theta)
cv2.waitKey(0)