我尝试在 CIELAB 空间中的颜色之间进行线性插值,并在线性 RGB 空间中检索颜色。
我的工作流程如下:
问题是,这些中间颜色在我的 RGB 空间之外,尽管我显然是从其中的 2 种颜色开始的。具体来说:在 RGB(1,0,0) 和 RGB(0,0,1) 之间插值时,G 通道获得约 -0.058 的负值。
如果我使用原色和白点,即线性 sRGB 的矩阵,则会出现同样的问题。
这正常吗?在我看来,L*a*b* 颜色空间可能无法保证两个 RGB 可表示颜色之间的直线也在该可表示区域内,这似乎是合理的。如果不正常的话,错误可能出在哪里呢?如果正常的话应该怎么处理?
我的代码:
import numpy as np
mat = np.array([[0.49,0.31,0.2],[0.17697,0.81240,0.01063],[0.,0.01,0.99]])
def RGB_to_Lab(R,G,B):
X,Y,Z = (mat@[[R],[G],[B]])[:,0]
Xn, Yn, Zn = (mat@[[1],[1],[1]])[:,0]
f = lambda t: t**(1/3) if t>(6/29)**3 else (1/3)*(29/6)**2*t+4/29
L = 116*f(Y/Yn) - 16
a = 500*(f(X/Xn)-f(Y/Yn))
b = 200*(f(Y/Yn)-f(Z/Zn))
return L, a, b
def Lab_to_RGB(L,a,b):
f = lambda t:t**3 if t>6/29 else 3*(6/29)**2*(t-4/29)
Xn, Yn, Zn = (mat@[[1],[1],[1]])[:,0]
X = Xn*f((L+16)/116+a/500)
Y = Yn*f((L+16)/116)
Z = Zn*f((L+16)/116-b/200)
R,G,B = (np.linalg.inv(mat)@[[X],[Y], [Z]])[:,0]
return R,G,B
def steps(n):
Lab = np.array(RGB_to_Lab(1,0,0))
Lab2 = np.array(RGB_to_Lab(0,0,1))
for i in range(n+1):
r = i/n
tmp = r*Lab2+(1-r)*Lab
print(Lab_to_RGB(*tmp))
CIE 实验室受到可见光谱的限制,即标准观察者对光的敏感度,因此在该空间中进行插值可能会生成负 RGB 值,因为实际上没有任何 RGB 颜色空间,例如sRGB,覆盖全部。