首页 > 解决方案 > 如何使用 OpenCV 将梯度/幅度应用于图像?

问题描述

我目前正在学习本教程作为大学作业的一部分,我们应该自己实现精明的边缘检测。应用高斯模糊没有任何问题,但现在我正在尝试显示网站上显示的幅度强度。

我实现了上述网站上的功能,并创建了一个用于运行精明边缘检测的功能。目前这是函数的样子:

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)

我必须将幅度和索贝尔数组转换np.uint8为,否则它们会包含float在显示图像时导致错误的值。目前,我正在使用该变量test来尝试各种事情,例如gradient - noise_reduction,您在上面看到的行等。问题是我总是得到看起来与这些相似的图像(左边的图像显示test,右边的图像显示gradient,图像在底部显示magnitude):

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

我对所有可用的 OpenCV 函数都不太熟悉,但我想使用其中一些我不知道的函数可能很重要。不幸的是,在上面链接的教程中,我无法找到有关sobel_filters函数返回的幅度如何应用于图像的任何信息。提前感谢您提供有关如何解决此问题的任何意见。

标签: pythonopencvedge-detectioncanny-operatorsobel

解决方案


我认为 ndimage.filters.convolve 可能存在问题。我得到了和你相似的结果。但以下似乎使用 Python/OpenCV 可以正常工作

输入:

在此处输入图像描述

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)

震级:

在此处输入图像描述

方向:

在此处输入图像描述


推荐阅读