使用 Numpy 在 python 中移动 HSV 像素值
Shifting HSV pixel values in python using Numpy
我正在尝试转换(移动)HSV 图像(取自视频帧)中每个像素的值。
想法是通过使用以下等式将红色和黄色值反转为蓝色值,将黄色和红色反转为蓝色(以避免在程序后面使用三个阈值,而我只能使用一个)。
(Hue + 90) % 180 (in OpenCV 3 Hue is in range [0,180])
这是我想出的:
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)
不幸的是,它不起作用,因为我选择了整个色调通道而不是它的像素值
这里有两种不同的可能性,我不确定您想要哪一种,但实现起来都很简单。您可以反转(反转可能是一个更好的词)彩虹色相,您可以使用 180 - hue
来实现。或者您可以像您提到的那样使用 (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)
这些是在 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)
色相通道为uint8类型,取值范围为[0, 179]。因此,当加上一个大数或一个负数时,Pythonreturns一个垃圾数。这是我基于 变色代码的解决方案:
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 shift_channel(c, amount):
if amount > 0:
lim = 255 - amount
c[c >= lim] = 255
c[c < lim] += amount
elif amount < 0:
amount = -amount
lim = amount
c[c <= lim] = 0
c[c > lim] -= amount
return c
rand_h, rand_s, rand_v = 50, 50, 50
img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(img_hsv)
# Random shift hue
shift_h = random.randint(-rand_h, rand_h)
h = ((h.astype('int16') + shift_h) % 180).astype('uint8')
# Random shift saturation
shift_s = random.randint(-rand_s, rand_s)
s = shift_channel(s, shift_s)
# Random shift value
shift_v = random.randint(-rand_v, rand_v)
v = shift_channel(v, shift_v)
shift_hsv = cv2.merge([h, s, v])
print(shift_h, shift_s, shift_v)
img_rgb = cv2.cvtColor(shift_hsv, cv2.COLOR_HSV2RGB)
我正在尝试转换(移动)HSV 图像(取自视频帧)中每个像素的值。
想法是通过使用以下等式将红色和黄色值反转为蓝色值,将黄色和红色反转为蓝色(以避免在程序后面使用三个阈值,而我只能使用一个)。
(Hue + 90) % 180 (in OpenCV 3 Hue is in range [0,180])
这是我想出的:
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)
不幸的是,它不起作用,因为我选择了整个色调通道而不是它的像素值
这里有两种不同的可能性,我不确定您想要哪一种,但实现起来都很简单。您可以反转(反转可能是一个更好的词)彩虹色相,您可以使用 180 - hue
来实现。或者您可以像您提到的那样使用 (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)
这些是在 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)
色相通道为uint8类型,取值范围为[0, 179]。因此,当加上一个大数或一个负数时,Pythonreturns一个垃圾数。这是我基于
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 shift_channel(c, amount):
if amount > 0:
lim = 255 - amount
c[c >= lim] = 255
c[c < lim] += amount
elif amount < 0:
amount = -amount
lim = amount
c[c <= lim] = 0
c[c > lim] -= amount
return c
rand_h, rand_s, rand_v = 50, 50, 50
img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(img_hsv)
# Random shift hue
shift_h = random.randint(-rand_h, rand_h)
h = ((h.astype('int16') + shift_h) % 180).astype('uint8')
# Random shift saturation
shift_s = random.randint(-rand_s, rand_s)
s = shift_channel(s, shift_s)
# Random shift value
shift_v = random.randint(-rand_v, rand_v)
v = shift_channel(v, shift_v)
shift_hsv = cv2.merge([h, s, v])
print(shift_h, shift_s, shift_v)
img_rgb = cv2.cvtColor(shift_hsv, cv2.COLOR_HSV2RGB)