通过 Sobel 算子,我已经能够确定图像的梯度幅度。我在下面显示这个:
现在我想确定梯度方向。为此,我关注了这篇文章,它使用了函数cv2.phase
. 在此之后,角度被硬编码为特定颜色,具体取决于函数返回的度数。我的问题是这个函数为我返回的值在 0 到 90 度的范围内。因此,我得到的图像仅由红色和青色组成。
我的代码如下:
# where gray_blur is a grayscale image of dimension 512 by 512
# 3x3 sobel filters for edge detection
sobel_x = np.array([[ -1, 0, 1],
[ -2, 0, 2],
[ -1, 0, 1]])
sobel_y = np.array([[ -1, -2, -1],
[ 0, 0, 0],
[ 1, 2, 1]])
# Filter the blurred grayscale images using filter2D
filtered_blurred_x = cv2.filter2D(gray_blur, -1, sobel_x)
filtered_blurred_y = cv2.filter2D(gray_blur, -1, sobel_y)
# Compute the orientation of the image
orien = cv2.phase(np.array(filtered_blurred_x, np.float32), np.array(filtered_blurred_y, dtype=np.float32), angleInDegrees=True)
image_map = np.zeros((orien.shape[0], orien.shape[1], 3), dtype=np.int16)
# Define RGB colours
red = np.array([255, 0, 0])
cyan = np.array([0, 255, 255])
green = np.array([0, 255, 0])
yellow = np.array([255, 255, 0])
# Set colours corresponding to angles
for i in range(0, image_map.shape[0]):
for j in range(0, image_map.shape[1]):
if orien[i][j] < 90.0:
image_map[i, j, :] = red
elif orien[i][j] >= 90.0 and orien[i][j] < 180.0:
image_map[i, j, :] = cyan
elif orien[i][j] >= 180.0 and orien[i][j] < 270.0:
image_map[i, j, :] = green
elif orien[i][j] >= 270.0 and orien[i][j] < 360.0:
image_map[i, j, :] = yellow
# Display gradient orientation
f, ax1 = plt.subplots(1, 1, figsize=(20,10))
ax1.set_title('gradient orientation')
ax1.imshow(image_map)
Run Code Online (Sandbox Code Playgroud)
显示图像:
提前致谢。
ddepth
的参数很cv2.filter2D
重要。您将其设置为 -1,这意味着过滤后的图像将具有与输入相同的深度。gray_blur
似乎是无符号整数(可能是 uint8),因此过滤器输出也是如此。
由于您的过滤器可能会产生负值,因此它们会使 uint8 下溢。设置 ddepth 以从过滤器接收完整的值范围:
filtered_blurred_x = cv2.filter2D(gray_blur, cv2.CV_32F, sobel_x)
filtered_blurred_y = cv2.filter2D(gray_blur, cv2.CV_32F, sobel_y)
Run Code Online (Sandbox Code Playgroud)
有了这个,您的过滤图像现在编码一个方向,并且该方向将映射完整的 360 度。
您还可以使用 HSV 颜色空间来编码方向和幅度,因为色调与角度一起工作,并且您可以使用 V 来编码幅度。
例如,使用你的代码和性感的莱娜:
import cv2 as cv
import numpy as np
im = cv.imread("lenna.png", -1)
im_gray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
k = 5
gray_blur = cv.bilateralFilter(im_gray, k, k * 2, k / 2) # To perserve edges
# 3x3 sobel filters for edge detection
sobel_x = np.array([[ -1, 0, 1],
[ -2, 0, 2],
[ -1, 0, 1]])
sobel_y = np.array([[ -1, -2, -1],
[ 0, 0, 0],
[ 1, 2, 1]])
# Filter the blurred grayscale images using filter2D
filtered_blurred_x = cv.filter2D(gray_blur, cv.CV_32F, sobel_x)
filtered_blurred_y = cv.filter2D(gray_blur, cv.CV_32F, sobel_y)
mag = cv.magnitude(filtered_blurred_x, filtered_blurred_y)
orien = cv.phase(filtered_blurred_x, filtered_blurred_y, angleInDegrees=True)
orien = orien / 2. # Go from 0:360 to 0:180
hsv = np.zeros_like(im)
hsv[..., 0] = orien # H (in OpenCV between 0:180)
hsv[..., 1] = 255 # S
hsv[..., 2] = cv.normalize(mag, None, 0, 255, cv.NORM_MINMAX) # V 0:255
bgr = cv.cvtColor(hsv, cv.COLOR_HSV2BGR)
cv.imshow("Color coded edges", bgr)
cv.waitKey(0)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4003 次 |
最近记录: |