Преобразование изображения из RGB в LUV и обратно приводит к другому изображению - PullRequest
0 голосов
/ 13 декабря 2018

В настоящее время я пытаюсь начать с исходного изображения RGB, преобразовать его в LUV, выполнить некоторые операции (а именно, повернуть оттенки), а затем повернуть его обратно в RGB для отображения.Тем не менее, я столкнулся с неприятной проблемой, когда преобразование RGB в LUV (и наоборот), похоже, меняет изображение.В частности, если я начну с изображения LUV, преобразую его в RGB, а затем верну обратно в LUV, не меняя ничего другого, исходное изображение будет другим.Это произошло как для Python (cv2), так и для Matlab (с открытым исходным кодом) реализаций алгоритмов преобразования цветов, а также для моих собственных кодов, написанных вручную.Вот пример:

luv1 = np.array([[[100,6.12,0]]]).astype('float32')
rgb1 = cv2.cvtColor(luv1,cv2.COLOR_Luv2RGB)
luv2 = cv2.cvtColor(rgb1,cv2.COLOR_RGB2Luv)
print(luv2)
[[[99.36293    1.3064307 -1.0494182]]]

Как видите, координаты LUV изменились по сравнению со входом.Это потому, что определенные координаты LUV не имеют прямого совпадения в пространстве RGB?

1 Ответ

0 голосов
/ 14 декабря 2018

Да, удалите бит astype('uint8') в своем коде, и разница должна исчезнуть, если преобразование выполнено правильно.

Уравнения для преобразования можно посмотреть в Википедии .Там нет ничего необратимого, преобразования являются совершенными противоположностями друг другу.

Однако это преобразование содержит мощность 3 rd , которая значительно растягивает некоторые значения.Округление преобразования в целое число может привести к значительному изменению цвета.

Кроме того, область Luv очень нерегулярна, и может быть нелегко проверить, что значения Luv приведут к значимому значению RGB.Ваше утверждение «Я проверил, что в luv1 есть записи, все из которых попадают в допустимые диапазоны ввода», заставляет меня поверить, что вы думаете, что домен Luv - это поле.Это не.Диапазоны для u и v изменяются с L .Хорошее упражнение - начать с выборки куба RGB и сопоставить их с Luv, затем нанести эти точки на график, чтобы увидеть форму домена Luv.В Википедии есть пример того, как это может выглядеть для гаммы sRGB .

Функция OpenCV cvtColor будет ограничивать значения RGB в диапазоне [0,1] (если тип float32), что приводит к необратимым изменениям цвета, если входные данные находятся за пределами гаммы.

Вот пример, который показывает, что преобразование является обратимым.Я начинаю со значений RGB, поскольку их легко проверить как действительные:

import numpy as np
import cv2

rgb1 = np.array([[[1.0,1.0,1.0],[0.5,1.0,0.5],[0.0,0.5,0.5],[0.0,0.0,0.0]]], 'float32')
luv1 = cv2.cvtColor(rgb1, cv2.COLOR_RGB2Luv)
rgb2 = cv2.cvtColor(luv1, cv2.COLOR_Luv2RGB)
np.max(np.abs(rgb2-rgb1))

Возвращает 2.8897537e-06, что является числовой точностью для 32-разрядных чисел с плавающей запятой.

...