Обратите внимание на следующее изображение:
Соблюдайте следующий код Python:
import cv2
img = cv2.imread("rainbow.png", cv2.IMREAD_COLOR)
img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # convert it to hsv
img = cv2.cvtColor(img, cv2.COLOR_HSV2BGR) # convert back to BGR
cv2.imwrite("out.png", img)
Вот выходное изображение:
Если вы не можете видеть это, то здесь очевидна потеря визуальной точности. Для сравнения, здесь оригинал рядом с выходным изображением увеличен вокруг желтых:
Что здесь происходит? Есть ли способ предотвратить появление этих блочных артефактов? Мне нужно преобразовать в цветовое пространство HSL, чтобы повернуть оттенок, но я не могу этого сделать, если я собираюсь получить такие артефакты.
Как примечание, у выходного изображения нет артефактов, когда я не делаю два преобразования; сами преобразования действительно являются причиной.
Вернитесь к компьютеру сейчас - попробуйте так:
#!/usr/bin/env python3
import numpy as np
import cv2
img = cv2.imread("rainbow.png", cv2.IMREAD_COLOR)
img = img.astype(np.float32)/255 # go to 32-bit float on 0..1
img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # convert it to hsv
img = cv2.cvtColor(img, cv2.COLOR_HSV2BGR) # convert back to BGR
cv2.imwrite("output.png", (img*255).astype(np.uint8))
Я думаю, что проблема заключается в том, что когда вы используете 8-битное представление без знака, оттенок "сплющивается" из диапазона 0..360 в диапазон 0..180 с шагом 2 градуса, чтобы оставаться в пределах 8-битного диапазон без знака 0..255, вызывающий шаги между соседними значениями. Решение состоит в том, чтобы перейти к 32-разрядным числам с плавающей запятой и масштабировать до диапазона 0..1.