我目前正在尝试从原始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空间中没有直接匹配吗?
最佳答案
是的,删除代码中的astype('uint8')
位,如果正确实现了转换,则差异应该消失。
您可以在Wikipedia中查看转换公式。没有什么是不可逆的,转换是彼此的完美逆。
但是,此转换包含三次方,它确实会拉伸一些值。将转换舍入为整数可能会导致颜色发生明显变化。
而且,Luv域是高度不规则的,因此验证Luv值是否会导致RGB值可能不容易。您的陈述“我已经验证luv1的条目都在允许的输入范围内”,这使我相信您认为Luv域是一个框。它不是。 u和v的范围随L的变化而变化。一个不错的练习是从RGB立方体的采样开始,并将其映射到Luv,然后绘制这些点以查看Luv域的形状。维基百科提供了一个示例,显示了for the sRGB gamut的外观。
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位浮点数的数字精度。关于python - 将图像从RGB转换为LUV并反向转换为不同的图像,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53768922/