使用Numpy在python中移动HSV像素值

使用Numpy在python中移动HSV像素值,numpy,colors,opencv3.0,hsv,Numpy,Colors,Opencv3.0,Hsv,我试图转换(移位)HSV图像中每个像素的值(取自视频帧) 我们的想法是通过使用以下等式将红色和黄色值转换为蓝色值,从而将黄色和红色转换为蓝色(以避免在程序后面使用三个阈值,而我只能使用一个阈值) (色调+90)%180(在OpenCV 3中,色调在[0180]范围内) 以下是我的想法: hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV); H = hsv[:,:,0] mask= [H<75 and H>128] print("orig",hsv

我试图转换(移位)HSV图像中每个像素的值(取自视频帧)

我们的想法是通过使用以下等式将红色和黄色值转换为蓝色值,从而将黄色和红色转换为蓝色(以避免在程序后面使用三个阈值,而我只能使用一个阈值)

(色调+90)%180(在OpenCV 3中,色调在[0180]范围内)

以下是我的想法:

hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV);
H = hsv[:,:,0]
mask= [H<75 and H>128]
print("orig",hsv[mask])
hsv[mask] = ((hsv[mask]+90) % 180)
hsv=cv2.cvt颜色(帧,cv2.COLOR\u BGR2HSV);
H=hsv[:,:,0]
掩码=[H128]
打印(“原稿”,hsv[遮罩])
hsv[屏蔽]=((hsv[屏蔽]+90)%180)

不幸的是,这种方法不起作用,因为我选择的是整个色调通道,而不是它的像素值。这里有两种不同的可能性,我不确定你想要哪种,但它们都很容易实现。您可以反转(反转可能是一个更好的词)色调彩虹,您只需使用
180-hue
即可。或者您可以使用您提到的
(色调+90)%180
将颜色移动180度

反转颜色:

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
rev_h = 180 - h
rev_hsv = cv2.merge([rev_h, s, v])
rev_img = cv2.cvtColor(rev_hsv, cv2.COLOR_HSV2BGR)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
shift_h = (h + 90) % 180
shift_hsv = cv2.merge([shift_h, s, v])
shift_img = cv2.cvtColor(shift_hsv, cv2.COLOR_HSV2BGR)
改变颜色:

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
rev_h = 180 - h
rev_hsv = cv2.merge([rev_h, s, v])
rev_img = cv2.cvtColor(rev_hsv, cv2.COLOR_HSV2BGR)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
shift_h = (h + 90) % 180
shift_hsv = cv2.merge([shift_h, s, v])
shift_img = cv2.cvtColor(shift_hsv, cv2.COLOR_HSV2BGR)
这些是在OpenCV中实现这一点的惯用方法

现在,您希望执行与上面相同的操作,但仅针对满足条件的某些遮罩像素子集。这并不难做到;如果要移动某些遮罩像素:

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
h_mask = (h < 75) | (h > 128)
h[h_mask] = (h[h_mask] + 90) % 180
shift_hsv = cv2.merge([h, s, v])
shift_img = cv2.cvtColor(shift_hsv, cv2.COLOR_HSV2BGR)
hsv=cv2.cvt颜色(img,cv2.COLOR\u BGR2HSV)
h、 s,v=cv2.分流(hsv)
h_掩码=(h<75)|(h>128)
h[h_掩码]=(h[h_掩码]+90)%180
shift_hsv=cv2.合并([h,s,v])
shift\u img=cv2.CVT颜色(shift\u hsv,cv2.COLOR\u HSV2BGR)

色调通道为uint8类型,值范围为[0179]。因此,当使用大数字或负数进行add时,Python将返回一个垃圾号。以下是我基于颜色变换代码的解决方案:

img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(img_hsv)
shift_h = random.randint(-50, 50)
h = ((h.astype('int16') + shift_h) % 180).astype('uint8')
shift_hsv = cv2.merge([h, s, v])
用于随机色调、饱和度和值移动。基于以下内容切换频道:

def移位_通道(c,数量):
如果金额>0:
lim=255-金额
c[c>=lim]=255
c[c
您正在使用令人困惑的变量名。首先,使用H、S、V作为0、1、2作为第一、第二和第三个通道,然后重新将它们指定为实际的2D数组,而不是每个通道的索引。然后你用S和V索引到第二和第三维度,这大概不是你想要做的(相反你想要
[H,:,:]
[S,:,:]
,和
[V,:,:,:]
),但是你可以简单地做
H,S,V=cv2。拆分(hsv)
,你的生活就会简单得多。我已经编辑了这个问题,因为我发现代码是非常错误的哦,我的意思是
[:,:,H]
,但你似乎明白了这一点。您的新代码应该可以工作,但由于它是numpy数组,您需要这样做:
mask=(H128)
。Python的
关键字只对布尔值有效,但是
HOh,你可能真的想
把它们放在一起,而不是
。显然,没有像素可以同时小于75和>128。谢谢你的回答!我需要改变颜色,但还有一件事-我不需要改变范围(75128)中的值,小心-
h+90
会使字节范围256溢出,因为h已经大于166。你可能想在添加之前转换为uint16,否则色调会在转换过程中被破坏。很好的捕捉-我想知道为什么我的色调在转换为红色时被破坏。当然,179+90=269,这对于uint8字节来说太多了。您的
.astype('int16')
为我解决了这个问题。