OpenCV Python-替换图像中的通道

OpenCV Python-替换图像中的通道,python,numpy,opencv,computer-vision,Python,Numpy,Opencv,Computer Vision,我现在在x轴和y轴上使用Sobel过滤器,并计算出一个角度。输出图像是HSV颜色空间中两个方向的加权平均值 我试图用计算的角度(范围[0,pi]中的1d列表)替换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[:,:,

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

我试图用计算的角度(范围[0,pi]中的1d列表)替换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
在交换频道之前,我有: 但在交换之后,我得到:

我预期的结果类似于:


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

则存在与颜色空间(HSV和BGR、阵列数据类型和范围)相关的两个问题。在很大程度上,OpenCV希望用户注意这些事情

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

  • 如果
    gray
    是uint8图像,则Sx/Sy将仅包含非负值。这基本上将所有负导数都设为零,这是错误的。建议将Sobel ddepth参数更改为CV_32F(以确保输出为浮点):
    Sx=cv2.Sobel(灰色,cv2.CV_32F,1,0,ksize=3)
    (类似地,对于
    Sy
    )。或者您可以明确地确保
    gray.dtype
    np.float32

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

  • θ=np.arctan2(Sy,Sx) #不是将[-pi,pi]范围转换为度,而是线性转换 #使用cv2.normalize将数组设置为[0255]范围。 色调值=cv2.规格化(θ,dst=无,α=255.0,标准类型=cv2.标准最小值) #选择非零值作为掩码。 掩码=np.逻辑或(θ>0.01,θ<-0.01) 颜色[:,:,0]=色调值 颜色[遮罩,1]=255 颜色[遮罩,2]=255
    有两个与颜色空间相关的问题(HSV和BGR、阵列数据类型和范围)。在很大程度上,OpenCV希望用户注意这些事情

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

  • 如果
    gray
    是uint8图像,则Sx/Sy将仅包含非负值。这基本上将所有负导数都设为零,这是错误的。建议将Sobel ddepth参数更改为CV_32F(以确保输出为浮点):
    Sx=cv2.Sobel(灰色,cv2.CV_32F,1,0,ksize=3)
    (类似地,对于
    Sy
    )。或者您可以明确地确保
    gray.dtype
    np.float32

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

  • θ=np.arctan2(Sy,Sx) #不是将[-pi,pi]范围转换为度,而是线性转换 #使用cv2.normalize将数组设置为[0255]范围。 色调值=cv2.规格化(θ,dst=无,α=255.0,标准类型=cv2.标准最小值) #选择非零值作为掩码。 掩码=np.逻辑或(θ>0.01,θ<-0.01) 颜色[:,:,0]=色调值 颜色[遮罩,1]=255 颜色[遮罩,2]=255
    尝试将以下内容的输出添加到您的问题
    color.dtype
    np.min(color[…,0])
    np.max(color[…,0])
    尝试将以下内容的输出添加到您的问题
    color.dtype
    np min(color[…,0]),
    np max(color[…,0])
    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