LAB,RGB,XYZ颜色转换不正确,反之亦然
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LAB,RGB,XYZ颜色转换不正确,反之亦然相关的知识,希望对你有一定的参考价值。
我正在为项目创建自定义颜色选择器,它采用的是Photoshop风格,我可以使所有其他转换按预期方式工作,但我无法使RGBToLAB和LABToRGB正常工作。
问题不仅在于颜色显示不正确,而且转换也不完美。
样本:
- LAB _ 58:0:0
- XYZ _ 0.25960986510312:0.25960986510312:0.25960986510312
- RGB _ {R:10 G:8 B:7 A:255}
- XYZ _ 0.250358161840588:5.51162077338675:66.3836625496266
- LAB _ 85.3739502460609:0:0
初始LAB与最后一个LAB不同,这表明转换存在缺陷。我不仅会得到错误的颜色,而且值也会发生变化,尤其是当LAB.L假定为常数时(在此示例中,因为这是滑块当前所控制的)]
上面的LAB-> RGB-> LAB转换有缺陷,但是XYZ-> RGB-> XYZ转换也有缺陷。
显然,我对转换LABToLAB不感兴趣,但以上内容确实指出了转换中的缺陷。
我尝试过的事情:
This cginc code intended for unity, which is where i'm at now
Private Function LABToXYZ(LAB As LAB) As XYZ Dim X, Y, Z As New Double Y = ((LAB.L + 16.0) / 116.0) X = ((LAB.A / 500.0) + Y) Z = (Y - (LAB.B / 200.0)) Dim Less = 0.206897 If (X > Less) Then X = Math.Pow(X, 3) Else X = ((X - 16.0 / 116.0) / 7.787) End If If (Y > Less) Then Y = Math.Pow(Y, 3) Else Y = ((Y - 16.0 / 116.0) / 7.787) End If If (Z > Less) Then Z = Math.Pow(Z, 3) Else Z = ((Z - 16.0 / 116.0) / 7.787) End If Return New XYZ(X, Y, Z) End Function Private Function XYZToRGB(XYZ As XYZ) As Color Dim R, G, B As New Double Dim X, Y, Z As New Double X = (XYZ.X / 100) Y = (XYZ.Y / 100) Z = (XYZ.Z / 100) R = ((X * 3.2406) + (Y * -1.5372) + (Z * -0.4986)) G = ((X * -0.9689) + (Y * 1.8758) + (Z * 0.0415)) B = ((X * 0.0557) + (Y * -0.204) + (Z * 1.057)) Dim Less As Double = 0.0031308 If (R > Less) Then X = ((1.055 * Math.Pow(R, (1.0 / 2.4))) - 0.055) Else X = (R * 12.92) End If If (G > Less) Then Y = ((1.055 * Math.Pow(G, (1.0 / 2.4))) - 0.055) Else Y = (G * 12.92) End If If (B > Less) Then Z = ((1.055 * Math.Pow(B, (1.0 / 2.4))) - 0.055) Else Z = (B * 12.92) End If Return New Color(CSng(X), CSng(Y), CSng(Z)) End Function Private Function RGBToXYZ(Color As Color) As XYZ Dim RGB = ColorToRGB(Color) Dim X, Y, Z As New Double Dim Less As Double = 0.04045 If (RGB.R > Less) Then X = Math.Pow(((RGB.R + 0.055) / 1.055), 2.4) Else X = (RGB.R / 12.92) End If If (RGB.G > Less) Then Y = Math.Pow(((RGB.G + 0.055) / 1.055), 2.4) Else Y = (RGB.G / 12.92) End If If (RGB.B > Less) Then Z = Math.Pow(((RGB.B + 0.055) / 1.055), 2.4) Else Z = (RGB.B / 12.92) End If X = (((X * 0.4124) + (Y * 0.3576) + (Z * 0.1805)) * 100.0) Y = (((X * 0.2126) + (Y * 0.7152) + (Z * 0.0722)) * 100.0) Z = (((X * 0.0193) + (Y * 0.1192) + (Z * 0.9505)) * 100.0) Return New XYZ(X, Y, Z) End Function Private Function XYZToLAB(XYZ As XYZ) As LAB Dim X, Y, Z As New Double Dim L, A, B As New Double Dim Less As Double = 0.008856 X = ((XYZ.X / 95.047) + (XYZ.Y / 100) + (XYZ.Z / 108.883)) Y = ((XYZ.X / 95.047) + (XYZ.Y / 100) + (XYZ.Z / 108.883)) Z = ((XYZ.X / 95.047) + (XYZ.Y / 100) + (XYZ.Z / 108.883)) If (X > Less) Then X = Math.Pow(X, (1.0 / 3.0)) Else X = ((7.787 * X) + (16.0 / 116.0)) End If If (Y > Less) Then Y = Math.Pow(Y, (1.0 / 3.0)) Else Y = ((7.787 * Y) + (16.0 / 116.0)) End If If (Z > Less) Then Z = Math.Pow(Z, (1.0 / 3.0)) Else Z = ((7.787 * Z) + (16.0 / 116.0)) End If L = ((116.0 * Y) - 16.0) A = (500.0 * (X - Y)) B = (200.0 * (Y - Z)) Return New LAB(L, A, B) End Function Function ColorToRGB(Color As Color) As RGB Return New RGB((Convert.ToInt32(Color.R) / 255), (Convert.ToInt32(Color.G) / 255), (Convert.ToInt32(Color.B) / 255)) End Function Public Class RGB Public ReadOnly Min As Double = 0 Public ReadOnly Max As Double = 1 Public Sub New() End Sub Public Sub New(R As Double, G As Double, B As Double) Me.R = R Me.G = G Me.B = B End Sub Public Sub New(Color As Color) Me.R = (Convert.ToInt32(Color.R) / 255) Me.G = (Convert.ToInt32(Color.G) / 255) Me.B = (Convert.ToInt32(Color.B) / 255) End Sub Private _R As New Double Private _G As New Double Private _B As New Double Public Property R As Double Get Return _R End Get Set _R = LimitInRange(Value, Min, Max) End Set End Property Public Property G As Double Get Return _G End Get Set _G = LimitInRange(Value, Min, Max) End Set End Property Public Property B As Double Get Return _B End Get Set _B = LimitInRange(Value, Min, Max) End Set End Property Overrides Function ToString() As String Return (_R.ToString & ":"c & _G.ToString & ":"c & _B.ToString) End Function End Class Public Class XYZ Public ReadOnly Min As Double = 0 Public ReadOnly Max As Double = 100 Public Sub New() End Sub Public Sub New(X As Double, Y As Double, Z As Double) Me.X = X Me.Y = Y Me.Z = Z End Sub Private _X As New Double Private _Y As New Double Private _Z As New Double Public Property X As Double Get Return _X End Get Set _X = LimitInRange(Value, Min, Max) End Set End Property Public Property Y As Double Get Return _Y End Get Set _Y = LimitInRange(Value, Min, Max) End Set End Property Public Property Z As Double Get Return _Z End Get Set _Z = LimitInRange(Value, Min, Max) End Set End Property Overrides Function ToString() As String Return (_X.ToString & ":"c & _Y.ToString & ":"c & _Z.ToString) End Function End Class Public Class LAB Public ReadOnly Min As Double = -128 Public ReadOnly Max As Double = 127 Sub New() End Sub Sub New(L As Double, A As Double, B As Double) Me.L = L Me.A = A Me.B = B End Sub Private _L As New Double Private _A As New Double Private _B As New Double Property L As Double Get Return _L End Get Set _L = LimitInRange(Value, 0, 100) End Set End Property Property A As Double Get Return _A End Get Set _A = LimitInRange(Value, Min, Max) End Set End Property Property B As Double Get Return _B End Get Set _B = LimitInRange(Value, Min, Max) End Set End Property Overrides Function ToString() As String Return (_L.ToString & ":"c & _A.ToString & ":"c & _B.ToString) End Function End Class Function LimitInRange(Value As Double, Min As Double, Max As Double) As Double Select Case Value Case <= Min Return Min Case >= Max Return Max Case Else Return Value End Select End Function
我需要VB.Net中的代码,这就是为什么我正在为我的项目转换和改编统一代码的原因,但是我遇到了麻烦,需要一些帮助。
[如果有人知道我在做什么错,我会很乐意听。
UPDATE 1:我试图通过不匹配两种转换方法来更正转换,但是我正接近完美的转换,但是我担心这么长时间解决这个问题可能会使我望而却步。
样本:
- LAB _ 0:0:0
- XYZ _ 0.262413383082537:0.262413383082537:0.262413383082537
- RGB _ {R:10 G:8 B:7 A:255}
- XYZ _ 0.250358161840588:0.253536089358344:0.236754082437929
- LAB _ 2.29017121228677:-0.12373260790384:0.261362975778545
您看到的问题比以前少了,但仍然存在。
Private Function LABToXYZ(LAB As LAB) As XYZ
Dim X, Y, Z As New Double
Y = ((LAB.L + 16.0) / 116.0)
X = ((LAB.A / 500.0) + Y)
Z = (Y - (LAB.B / 200.0))
Dim Less = 0.008856
If (X > Less) Then
X = Math.Pow(X, 3)
Else
X = ((X - 16.0 / 116.0) / 7.787)
End If
If (Y > Less) Then
Y = Math.Pow(Y, 3)
Else
Y = ((Y - 16.0 / 116.0) / 7.787)
End If
If (Z > Less) Then
Z = Math.Pow(Z, 3)
Else
Z = ((Z - 16.0 / 116.0) / 7.787)
End If
Return New XYZ(X * 100, Y * 100, Z * 100)
End Function
Private Function XYZToRGB(XYZ As XYZ) As Color
Dim R, G, B As New Double
Dim X, Y, Z As New Double
X = (XYZ.X / 100)
Y = (XYZ.Y / 100)
Z = (XYZ.Z / 100)
R = ((X * 3.2406) + (Y * -1.5372) + (Z * -0.4986))
G = ((X * -0.9689) + (Y * 1.8758) + (Z * 0.0415))
B = ((X * 0.0557) + (Y * -0.204) + (Z * 1.057))
Dim Less As Double = 0.0031308
If (R > Less) Then
R = ((1.055 * Math.Pow(R, (1.0 / 2.4))) - 0.055)
Else
R = (R * 12.92)
End If
If (G > Less) Then
G = ((1.055 * Math.Pow(G, (1.0 / 2.4))) - 0.055)
Else
G = (G * 12.92)
End If
If (B > Less) Then
B = ((1.055 * Math.Pow(B, (1.0 / 2.4))) - 0.055)
Else
B = (B * 12.92)
End If
Return New Color(CSng(R), CSng(G), CSng(B))
End Function
Private Function RGBToXYZ(Color As Color) As XYZ
Dim RGB = ColorToRGB(Color)
Dim X, Y, Z As New Double
Dim R, G, B As New Double
Dim Less As Double = 0.04045
If (RGB.R > Less) Then
r = Math.Pow(((RGB.R + 0.055) / 1.055), 2.4)
Else
R = (RGB.R / 12.92)
End If
If (RGB.G > Less) Then
G = Math.Pow(((RGB.G + 0.055) / 1.055), 2.4)
Else
G = (RGB.G / 12.92)
End If
If (RGB.B > Less) Then
B = Math.Pow(((RGB.B + 0.055) / 1.055), 2.4)
Else
B = (RGB.B / 12.92)
End If
R *= 100
G *= 100
B *= 100
X = ((R * 0.4124) + (G * 0.3576) + (B * 0.1805))
Y = ((R * 0.2126) + (G * 0.7152) + (B * 0.0722))
Z = ((R * 0.0193) + (G * 0.1192) + (B * 0.9505))
Return New XYZ(X, Y, Z)
End Function
Private Function XYZToLAB(XYZ As XYZ) As LAB
Dim X, Y, Z As New Double
Dim L, A, B As New Double
Dim Less As Double = 0.008856
X = XYZ.X / 100
Y = XYZ.Y / 100
Z = XYZ.Z / 100
If (X > Less) Then
X = Math.Pow(X, (1.0 / 3.0))
Else
X = ((7.787 * X) + (16.0 / 116.0))
End If
If (Y > Less) Then
Y = Math.Pow(Y, (1.0 / 3.0))
Else
Y = ((7.787 * Y) + (16.0 / 116.0))
End If
If (Z > Less) Then
Z = Math.Pow(Z, (1.0 / 3.0))
Else
Z = ((7.787 * Z) + (16.0 / 116.0))
End If
L = ((116.0 * Y) - 16.0)
A = (500.0 * (X - Y))
B = (200.0 * (Y - Z))
Return New LAB(L, A, B)
End Function
UPDATE 2:进一步的测试显示XNA.Framework.Color中异常异常的行为,导致任何分数都被解释为%。这意味着200.10将超过最大颜色值(255)的200%,这会将其限制为最大颜色值(255),因此,除非指定整数,否则最终可能会得到非常错误的输出。
我正在尝试使代码from this example as well不匹配。我觉得我正在进步,即使我不得不放弃在转换中使用XNA.Framework.Color类。
如果找到一个解决方案,我将提供最终解决方案。
UPDATE 3:在线测试here (source code here)和here显示我的LABToXYZ不正确。
我的结果:
- 实验室_ 100:0:0
- XYZ _ 95.047:100:100
他们的结果:
- 实验室_ 100:0:0
XYZ _ 95.05:100:108.88
Public Function LABtoXYZ(LAB As LAB) As XYZ Dim X, Y, Z As Double Y = ((LAB.L + 16.0) / 116.0) X = ((LAB.A / 500.0) + Y) Z = (Y - (LAB.B / 200.0)) Dim Pow_X = Math.Pow(X, 3.0) Dim Pow_Y = Math.Pow(Y, 3.0) Dim Pow_Z = Math.Pow(Z, 3.0) Dim Less = 216 / 24389 If (Pow_X > Less) Then X = Pow_X Else X = ((X - (16.0 / 116.0)) / 7.787) End If If (Pow_Y > Less) Then Y = Pow_Y Else Y = ((Y - (16.0 / 116.0)) / 7.787) End If If (Pow_Z > Less) Then Z = Pow_Z Else Z = ((Z - (16.0 / 116.0)) / 7.787) End If Return New XYZ((X * 95.047), (Y * 100.0), (Z * 108.883)) End Function
但是使用全0进行LAB会导致全0的XYZ,这是正确的行为,我无法判断出什么问题,是Z错误,但是我的代码中的错误在哪里?
更多示例here似乎表明我的代码是正确的,但是我仍然得到错误的Z。
UPDATE 4:进一步完善和重做所有代码,我发现对发现的示例here进行了转换和改编,给了我我想要的结果,即使示例中存在一些错误,尤其是^ 2.2,应该是^ 2.4。
我还发现了一些精度问题,必须将双精度数转换为整数才能使转换完美,但这可能是最终的更新,除非我遇到任何问题,否则我将在一段时间内继续解决这个问题在实践中测试代码。当我确信代码没有缺陷时,我会回来并将其标记为已回答。
样本:测试1
- LAB _ 1:0:0
- XYZ _ 0.105222895807779:0.110706172533356:0.120540201839494
- RGB _ 4:4:4:255
- XYZ _ 0.115400959145268:0.12141079341953535:0.132216354033874
- LAB _ 1:0:0
测试2
- LAB _ 10:0:0
- XYZ _ 1.07024816003116:1.12601992701628:1.22604427713313
- RGB _ 27:27:27:255
- XYZ _ 1.04175693531671:1.09600940064882:1.19355423730657
- LAB _ 10:0:0
测试3
- LAB _ 100:0:0
- XYZ _ 95.047:100:108.883
- RGB _ 255:255:255:255
- XYZ _ 95.05:100:108.9
- LAB _ 100:0:0
测试4
- LAB _ 11:0:0
- XYZ _ 1.19854884694432:1.26100649883144:1.37302170612264
- RGB _ 29:29:29:255
- XYZ _ 1.16783071832485:1.22864883569159:1.33799858206814
- LAB _ 11:0:0
如上所示,有一个很小的变化,如果不进行四舍五入,将导致不完美的转换。
[The Classes
Public Class RGB
Public ReadOnly Min As Double = 0.0
Public ReadOnly Max As Double = 255.0
Public Sub New()
End Sub
Public Sub New(R As Integer, G As Integer, B As Integer)
Me.R = R
Me.G = G
Me.B = B
End Sub
Public Sub New(R As Integer, G As Integer, B As Integer, A As Integer)
Me.R = R
Me.G = G
Me.B = B
Me.A = A
End Sub
Public Sub New(R As Double, G As Double, B As Double, A As Double)
Me.R = Convert.ToInt32(R)
Me.G = Convert.ToInt32(G)
Me.B = Convert.ToInt32(B)
Me.A = Convert.ToInt32(A)
End Sub
Public Sub New(R As Double, G As Double, B As Double)
Me.R = Convert.ToInt32(R * 255)
Me.G = Convert.ToInt32(G * 255)
Me.B = Convert.ToInt32(B * 255)
End Sub
Public Sub New(Color As Color)
Me.R = Convert.ToInt32(Color.R)
Me.G = Convert.ToInt32(Color.G)
Me.B = Convert.ToInt32(Color.B)
Me.A = Convert.ToInt32(Color.A)
End Sub
Private _R As New Double
Private _G As New Double
Private _B As New Double
Private _A As Double = 255
Public Property R As Double
Get
Return _R
End Get
Set
_R = LimitInRange(Value, Min, Max)
End Set
End Property
Public Property G As Double
Get
Return _G
End Get
Set
_G = LimitInRange(Value, Min, Max)
End Set
End Property
Public Property B As Double
Get
Return _B
End Get
Set
_B = LimitInRange(Value, Min, Max)
End Set
End Property
Public Property A As Double
Get
Return _A
End Get
Set
_A = LimitInRange(Value, Min, Max)
End Set
End Property
Overrides Function ToString() As String
Return (_R.ToString & ":"c & _G.ToString & ":"c & _B.ToString & ":"c & _A.ToString)
End Function
Public Shared Operator =(Left As RGB, Right As RGB) As Boolean
If ((Left.R = Right.R) AndAlso (Left.G = Right.G) AndAlso (Left.B = Right.B) AndAlso (Left.A = Right.A)) Then
Return True
Else
Return False
End If
End Operator
Public Shared Operator <>(Left As RGB, Right As RGB) As Boolean
Return (Not (Left = Right))
End Operator
End Class
Public Class XYZ
Public ReadOnly Min As Double = 0
Public Sub New()
End Sub
Public Sub New(X As Double, Y As Double, Z As Double)
Me.X = X
Me.Y = Y
Me.Z = Z
End Sub
Private _X As New Double
Private _Y As New Double
Private _Z As New Double
Public Property X As Double
Get
Return _X
End Get
Set
_X = LimitInRange(Value, Min, 95.05)
End Set
End Property
Public Property Y As Double
Get
Return _Y
End Get
Set
_Y = LimitInRange(Value, Min, 100)
End Set
End Property
Public Property Z As Double
Get
Return _Z
End Get
Set
_Z = LimitInRange(Value, Min, 108.9)
End Set
End Property
Overrides Function ToString() As String
Return (_X.ToString & ":"c & _Y.ToString & ":"c & _Z.ToString)
End Function
End Class
Public Class LAB
Public ReadOnly Min As Double = -128
Public ReadOnly Max As Double = 127
Sub New()
End Sub
Sub New(L As Double, A As Double, B As Double)
Me.L = L
Me.A = A
Me.B = B
End Sub
Private _L As New Double
Private _A As New Double
Private _B As New Double
Property L As Double
Get
Return _L
End Get
Set
_L = LimitInRange(Value, 0, 100)
End Set
End Property
Property A As Double
Get
Return _A
End Get
Set
_A = LimitInRange(Value, Min, Max)
End Set
End Property
Property B As Double
Get
Return _B
End Get
Set
_B = LimitInRange(Value, Min, Max)
End Set
End Property
Overrides Function ToString() As String
Return (_L.ToString & ":"c & _A.ToString & ":"c & _B.ToString)
End Function
End Class
转换器
Public Function LABtoXYZ(LAB As LAB) As XYZ
Dim X, Y, Z As New Double
Y = ((LAB.L + 16.0) / 116.0)
X = ((LAB.A / 500.0) + Y)
Z = (Y - (LAB.B / 200.0))
Dim Pow_X = Math.Pow(X, 3.0)
Dim Pow_Y = Math.Pow(Y, 3.0)
Dim Pow_Z = Math.Pow(Z, 3.0)
Dim Less = (216 / 24389)
If (Pow_X > Less) Then
X = Pow_X
Else
X = ((X - (16.0 / 116.0)) / 7.787)
End If
If (Pow_Y > Less) Then
Y = Pow_Y
Else
Y = ((Y - (16.0 / 116.0)) / 7.787)
End If
If (Pow_Z > Less) Then
Z = Pow_Z
Else
Z = ((Z - (16.0 / 116.0)) / 7.787)
End If
Return New XYZ((X * 95.047), (Y * 100.0), (Z * 108.883))
End Function
Private Function XYZToRGB(XYZ As XYZ) As RGB
Dim X, Y, Z As New Double
Dim R, G, B As New Double
Dim Pow As Double = (1.0 / 2.4)
Dim Less As Double = 0.0031308
X = (XYZ.X / 100)
Y = (XYZ.Y / 100)
Z = (XYZ.Z / 100)
R = ((X * 3.24071) + (Y * -1.53726) + (Z * -0.498571))
G = ((X * -0.969258) + (Y * 1.87599) + (Z * 0.0415557))
B = ((X * 0.0556352) + (Y * -0.203996) + (Z * 1.05707))
If (R > Less) Then
R = ((1.055 * Math.Pow(R, Pow)) - 0.055)
Else
R *= 12.92
End If
If (G > Less) Then
G = ((1.055 * Math.Pow(G, Pow)) - 0.055)
Else
G *= 12.92
End If
If (B > Less) Then
B = ((1.055 * Math.Pow(B, Pow)) - 0.055)
Else
B *= 12.92
End If
Return New RGB(R, G, B)
End Function
Private Function RGBToXYZ(RGB As RGB) As XYZ
Dim X, Y, Z As New Double
Dim R, G, B As New Double
Dim Less As Double = 0.04045
R = (RGB.R / 255)
G = (RGB.G / 255)
B = (RGB.B / 255)
If (R > Less) Then
R = Math.Pow(((R + 0.055) / 1.055), 2.4)
Else
R = (R / 12.92)
End If
If (G > Less) Then
G = Math.Pow(((G + 0.055) / 1.055), 2.4)
Else
G = (G / 12.92)
End If
If (B > Less) Then
B = Math.Pow(((B + 0.055) / 1.055), 2.4)
Else
B = (B / 12.92)
End If
X = ((R * 0.4124) + (G * 0.3576) + (B * 0.1805))
Y = ((R * 0.2126) + (G * 0.7152) + (B * 0.0722))
Z = ((R * 0.0193) + (G * 0.1192) + (B * 0.9505))
Return New XYZ(X * 100, Y * 100, Z * 100)
End Function
Private Function XYZToLAB(XYZ As XYZ) As LAB
Dim X, Y, Z As New Double
Dim L, A, B As New Double
Dim Less As Double = 0.008856
Dim Pow As Double = (1.0 / 3.0)
X = ((XYZ.X / 100) / 0.9505)
Y = (XYZ.Y / 100)
Z = ((XYZ.Z / 100) / 1.089)
If (X > Less) Then
X = Math.Pow(X, Pow)
Else
X = ((7.787 * X) + (16.0 / 116.0))
End If
If (Y > Less) Then
Y = Math.Pow(Y, Pow)
Else
Y = ((7.787 * Y) + (16.0 / 116.0))
End If
If (Z > Less) Then
Z = Math.Pow(Z, Pow)
Else
Z = ((7.787 * Z) + (16.0 / 116.0))
End If
L = ((116.0 * Y) - 16.0)
A = (500.0 * (X - Y))
B = (200.0 * (Y - Z))
'We solve the precision problem by rounding to nearest integer
'This makes the conversion perfect.
Return New LAB(CInt(L), CInt(A), CInt(B))
End Function
在将其标记为已解决之前,需要进行进一步测试。
UPDATE 5:到目前为止还没有任何问题...当仅发布问题时,我不知道如何将其标记为已回答。完整的免费代码和更多内容可以找到here。
我尚未解析您的所有代码,但在您的第一个代码块中,函数RGBToXYZ中存在问题。
,但是X现在是新值!这不是在变量上轻率的地方。X = (((X * 0.4124) + (Y * 0.3576) + (Z * 0.1805)) * 100.0) Y = (((X * 0.2126) + (Y * 0.7152) + (Z * 0.0722)) * 100.0) Z = (((X * 0.0193) + (Y * 0.1192) + (Z * 0.9505)) * 100.0) Return New XYZ(X, Y, Z)
您为X做矩阵,然后对Y矩阵使用X 再次
这应该是这样的:
Dim Xout, Yout, Zout As New Double Xout = ((X * 0.4124) + (Y * 0.3576) + (Z * 0.1805)) Yout = ((X * 0.2126) + (Y * 0.7152) + (Z * 0.0722)) Zout = ((X * 0.0193) + (Y * 0.1192) + (Z * 0.9505)) Return New XYZ(Xout, Yout, Zout)
此外,我建议将XYZ保持在0.0-1.0范围内。
还有其他用途:
LABToXYZ缺少所需的光源转换。它需要返回:
具有:X = (X * 0.95047) Z = (Z * 1.08883)
然后XYZtoLAB
X = ((XYZ.X / 95.047) + (XYZ.Y / 100) + (XYZ.Z / 108.883)) Y = ((XYZ.X / 95.047) + (XYZ.Y / 100) + (XYZ.Z / 108.883)) Z = ((XYZ.X / 95.047) + (XYZ.Y / 100) + (XYZ.Z / 108.883))
哪个会使X Y和Z都相同...
应该(假设将XYZ保持为0-1):
X = (XYZ.X / 0.95047) Y = (XYZ.Y) Z = (XYZ.Z / 1.08883)
[我刚刚意识到您已经解决了自己的问题,我会把它留在这里,以防万一有人碰到它来寻找相似的答案。
以上是关于LAB,RGB,XYZ颜色转换不正确,反之亦然的主要内容,如果未能解决你的问题,请参考以下文章
RGB、CMY、CMYK、YUV、HSV、HSI、LAB颜色空间详解
Reinhard颜色迁移理论基础(RGB与Lab颜色空间转换)与代码实现(附matlab代码)
pytorchtensor张量vector向量numpy array数组image图像RGB空间LAB空间之间相互转换大全