Сдвиг значений пикселей HSV в питоне с использованием Numpy
Я пытаюсь преобразовать (сдвинуть) значения каждого пикселя изображения HSV (взятого из кадра видео).
Идея состоит в том, чтобы инвертировать желтый и красный цвета в синий (чтобы избежать использования трех пороговых значений в программе позже, когда я смогу использовать только один), инвертируя красные и желтые значения в синие, используя следующее уравнение.
(Оттенок + 90) % 180 (в OpenCV 3 оттенок находится в диапазоне [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)
К сожалению, это не работает, так как при таком подходе я выбираю весь канал оттенка, а не его значения пикселей
1 ответ
Здесь есть две разные возможности, и я не уверен, что вы хотите, но обе они тривиальны для реализации. Вы можете инвертировать (может быть лучше слово) радугу оттенка, которую вы можете просто сделать, используя 180 - hue
, Или вы можете сместить цвет на 180 градусов, используя (hue + 90) % 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]. Поэтому при добавлении с большим числом или отрицательным числом Python возвращает число мусора. Вот моя база решения на основе кода изменения цвета @alkasm:
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])
Для случайного изменения оттенка, насыщенности и значения. Сдвиг основания канала на @ bill-grates:
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)