简体   繁体   English

OpenCV Python - 替换图像中的通道

[英]OpenCV Python - Replace Channels in an Image

I'm currently using a Sobel filter on the x and y axis and computing an angle for that.我目前在 x 和 y 轴上使用 Sobel 过滤器并为此计算一个角度。 The output image is a weighted average of the two directions that is in HSV colorspace.输出图像是 HSV 颜色空间中两个方向的加权平均值。

I'm trying to replace the H channel with the computed angles (a 1d list in the range [0,pi]) and then set the S and V channel to 255 if H is non-zero我试图用计算出的角度([0,pi] 范围内的 1d 列表)替换 H 通道,然后如果 H 不为零,则将 S 和 V 通道设置为 255

The code I'm using to compute the angles is:我用来计算角度的代码是:

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

And to swap the channels:并交换频道:

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

Before swapping the channels I have:在交换频道之前,我有: 前 But after the swap I get:但交换后我得到: 后

I'm expected results similar to:我的预期结果类似于:

在此处输入图片说明

If the input image was a white background with a black circle如果输入图像是带有黑色圆圈的白色背景

There are a couple of issues related to colorspace (HSV and BGR, array dtype's, and ranges).有几个与色彩空间相关的问题(HSV 和 BGR、数组 dtype 和范围)。 For most part, OpenCV expects the user to pay attention to these things.在大多数情况下,OpenCV 希望用户注意这些事情。

  1. You are treating the numpy array as being in HSV colorspace, but cv2.imshow interprets the image as BGR.您将 numpy 数组视为在 HSV 色彩空间中,但cv2.imshow将图像解释为 BGR。 The color array needs to be explicitly converted to BGR, like this: cv2.imshow("image", cv2.cvtColor(color, cv2.COLOR_HSV2BGR)) color数组需要显式转换为 BGR,如下所示: cv2.imshow("image", cv2.cvtColor(color, cv2.COLOR_HSV2BGR))

  2. If gray is a uint8 image, then Sx/Sy will contain only non-negative values.如果gray是 uint8 图像,则 Sx/Sy 将仅包含非负值。 That basically sets all negative derivatives to zero, which is wrong.这基本上将所有负导数设置为零,这是错误的。 Would suggest changing Sobel ddepth argument to be CV_32F (so that it ensures that output is floating point): Sx = cv2.Sobel(gray, cv2.CV_32F, 1, 0, ksize=3) (and similarly for Sy ).建议将 Sobel ddepth 参数更改为 CV_32F(以确保输出为浮点数): Sx = cv2.Sobel(gray, cv2.CV_32F, 1, 0, ksize=3) (对于Sy )。 Or you can explicitly ensure that gray.dtype is np.float32 .或者您可以明确确保gray.dtypenp.float32

  3. Output of np.rad2deg is (in theory) in [0, 360] range, but the numpy array representing an image should have values in [0, 255]. np.rad2deg输出(理论上)在 [0, 360] 范围内,但表示图像的 numpy 数组应具有 [0, 255] 中的值。 Here is one possible way to deal with this situation:这是处理这种情况的一种可能方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM