首页 > 解决方案 > OpenCV Python - 替换图像中的通道

问题描述

我目前在 x 和 y 轴上使用 Sobel 滤波器并为此计算一个角度。输出图像是 HSV 颜色空间中两个方向的加权平均值。

我正在尝试用计算出的角度([0,pi] 范围内的一维列表)替换 H 通道,然后如果 H 不为零,则将 S 和 V 通道设置为 255

我用来计算角度的代码是:

 Sx = cv2.Sobel(gray, -1, 1, 0, ksize=3)
 Sy = cv2.Sobel(gray, -1, 0, 1, ksize=3)
 theta = np.arctan2(Sy, Sx)

并交换频道:

color[:,:,0] = np.rad2deg(theta)
color[color[:, :, 0] > 0, 1] = 255
color[color[:, :, 0] > 0, 2] = 255

在交换我拥有的频道之前: 前 但在交换之后我得到: 后

我的预期结果类似于:

在此处输入图像描述

如果输入图像是带有黑色圆圈的白色背景

标签: pythonnumpyopencvcomputer-vision

解决方案


有几个与色彩空间相关的问题(HSV 和 BGR、数组 dtype 和范围)。在大多数情况下,OpenCV 希望用户注意这些事情。

  1. 您将 numpy 数组视为在 HSV 颜色空间中,但cv2.imshow将图像解释为 BGR。该color数组需要显式转换为 BGR,如下所示:cv2.imshow("image", cv2.cvtColor(color, cv2.COLOR_HSV2BGR))

  2. 如果gray是 uint8 图像,则 Sx/Sy 将仅包含非负值。这基本上将所有负导数设置为零,这是错误的。建议将 Sobel ddepth 参数更改为 CV_32F (以确保输出为浮点数):(Sx = cv2.Sobel(gray, cv2.CV_32F, 1, 0, ksize=3)同样适用于Sy)。或者您可以明确确保gray.dtypenp.float32.

  3. 的输出np.rad2deg(理论上)在 [0, 360] 范围内,但表示图像的 numpy 数组的值应在 [0, 255] 范围内。这是处理这种情况的一种可能方法:

theta = np.arctan2(Sy, Sx)
# Instead of converting [-pi, pi] range to degrees, linearly convert
# the array to [0, 255] range using cv2.normalize.
hue_value = cv2.normalize(theta, dst=None, alpha=255.0, norm_type=cv2.NORM_MINMAX)
# Select nonzero values as a mask.
mask = np.logical_or(theta > 0.01, theta < -0.01)
color[:,:,0] = hue_value
color[mask, 1] = 255
color[mask, 2] = 255

推荐阅读