Ok guys
Here is the original code from EasyRGB, not in C but "Each conversion formula is written as a "neutral programming function", easy to be translate in any specific programming language:
Code: Select all
CIE-L*1, CIE-a*1, CIE-b*1 //Color #1 CIE-L*ab values
CIE-L*2, CIE-a*2, CIE-b*2 //Color #2 CIE-L*ab values
WHT-L, WHT-C, WHT-H //Wheight factors
xC1 = sqrt( CIE-a*1 * CIE-a*1 + CIE-b*1 * CIE-b*1 )
xC2 = sqrt( CIE-a*2 * CIE-a*2 + CIE-b*2 * CIE-b*2 )
xCX = ( xC1 + xC2 ) / 2
xGX = 0.5 * ( 1 - sqrt( ( xCX ^ 7 ) / ( ( xCX ^ 7 ) + ( 25 ^ 7 ) ) ) )
xNN = ( 1 + xGX ) * CIE-a*1
xC1 = sqrt( xNN * xNN + CIE-b*1 * CIE-b*1 )
xH1 = CieLab2Hue( xNN, CIE-b*1 )
xNN = ( 1 + xGX ) * CIE-a*2
xC2 = sqrt( xNN * xNN + CIE-b*2 * CIE-b*2 )
xH2 = CieLab2Hue( xNN, CIE-b*2 )
xDL = CIE-L*2 - CIE-L*1
xDC = xC2 - xC1
if ( ( xC1 * xC2 ) == 0 ) {
xDH = 0
}
else {
xNN = round( xH2 - xH1, 12 )
if ( abs( xNN ) <= 180 ) {
xDH = xH2 - xH1
}
else {
if ( xNN > 180 ) xDH = xH2 - xH1 - 360
else xDH = xH2 - xH1 + 360
}
}
xDH = 2 * sqrt( xC1 * xC2 ) * sin( dtor( xDH / 2 ) )
xLX = ( CIE-L*1 + CIE-L*2 ) / 2
xCY = ( xC1 + xC2 ) / 2
if ( ( xC1 * xC2 ) == 0 ) {
xHX = xH1 + xH2
}
else {
xNN = abs( round( xH1 - xH2, 12 ) )
if ( xNN > 180 ) {
if ( ( xH2 + xH1 ) < 360 ) xHX = xH1 + xH2 + 360
else xHX = xH1 + xH2 - 360
}
else {
xHX = xH1 + xH2
}
xHX /= 2
}
xTX = 1 - 0.17 * cos( dtor( xHX - 30 ) ) + 0.24
* cos( deg2rad( 2 * xHX ) ) + 0.32
* cos( deg2rad( 3 * xHX + 6 ) ) - 0.20
* cos( dtor( 4 * xHX - 63 ) )
xPH = 30 * exp( - ( ( xHX - 275 ) / 25 ) * ( ( xHX - 275 ) / 25 ) )
xRC = 2 * sqrt( ( xCY ^ 7 ) / ( ( xCY ^ 7 ) + ( 25 ^ 7 ) ) )
xSL = 1 + ( ( 0.015 * ( ( xLX - 50 ) * ( xLX - 50 ) ) )
/ sqrt( 20 + ( ( xLX - 50 ) * ( xLX - 50 ) ) ) )
xSC = 1 + 0.045 * xCY
xSH = 1 + 0.015 * xCY * xTX
xRT = - sin( deg2rad( 2 * xPH ) ) * xRC
xDL = xDL / ( WHT-L * xSL )
xDC = xDC / ( WHT-C * xSC )
xDH = xDH / ( WHT-H * xSH )
Delta E00 = sqrt( xDL ^ 2 + xDC ^ 2 + xDH ^ 2 + xRT * xDC * xDH )
CieLab2Hue( var_a, var_b ) //Function returns CIE-H° value
{
var_bias = 0
if ( var_a >= 0 && var_b == 0 ) return 0
if ( var_a < 0 && var_b == 0 ) return 180
if ( var_a == 0 && var_b > 0 ) return 90
if ( var_a == 0 && var_b < 0 ) return 270
if ( var_a > 0 && var_b > 0 ) var_bias = 0
if ( var_a < 0 ) var_bias = 180
if ( var_a > 0 && var_b < 0 ) var_bias = 360
return ( rad2deg( atan( var_b / var_a ) ) + var_bias )
}
I'm using this for "deg2rad" function
Code: Select all
function dToRadians pDegrees
return pDegrees / 180 * pi
end dToRadians
And this for "rad2deg"
Code: Select all
function rToDegrees pRadians
return pRadians * 180 / pi
end rToDegrees
And her is my translation to livecode (not a google one
)
Code: Select all
on DeltaE2000 tData
-- CIEL1, CIEa1, CIEb1 //Color #1 CIE-L*ab values
--CIEL2, CIEa2, CIEb2 //Color #2 CIE-L*ab values
--WHT-L, WHT-C, WHT-H //Wheight factors
put 96.422 into WHTL
put 100.000 into WHTC
put 82.521 into WHTH
set the itemdel to comma
put item 1 of tData into CIEL1
put item 2 of tData into CIEa1
put item 3 of tData into CIEb1
put item 4 of tData into CIEL2
put item 5 of tData into CIEa2
put item 6 of tData into CIEb2
put sqrt( CIEa1 * CIEa1 + CIEb1 * CIEb1 ) into xC1
put sqrt( CIEa2 * CIEa2 + CIEb2 * CIEb2 ) into xC2
put ( xC1 + xC2 ) / 2 into xCX
put 0.5 * ( 1 - sqrt( ( xCX^7 ) / ( ( xCX^7 ) + ( 25^7 ) ) ) ) into xGX
put ( 1 + xGX ) * CIEa1 into xNN
put sqrt( xNN * xNN + CIEb1 * CIEb1 ) into xC1
put CieLab2Hue( xNN, CIEb1 ) into xH1
put ( 1 + xGX ) * CIEa2 into xNN
put sqrt( xNN * xNN + CIEb2 * CIEb2 ) into xC2
put CieLab2Hue( xNN, CIEb2 ) into xH2
put CIEL2 - CIEL1 into xDL
put xC2 - xC1 into xDC
if ( xC1 * xC2 ) = 0 then
put 0 into xDH
else
put round(( xH2 - xH1), 12) into xNN
if ( abs( xNN ) <= 180 ) then
put xH2 - xH1 into xDH
else
if ( xNN > 180 ) then
put xH2 - xH1 - 360 into xDH
else
put xH2 - xH1 + 360 into xDH
end if
end if
end if
put 2 * sqrt( xC1 * xC2 ) * sin( xDH / 2 ) into xDH
put ( CIEL1 + CIEL2 ) / 2 into xLX
put ( xC1 + xC2 ) / 2 into xCY
if ( xC1 * xC2 ) = 0 then
put xH1 + xH2 into xHX
else
put abs( round( xH1 - xH2, 12 ) ) into xNN
if xNN > 180 then
if ( ( xH2 + xH1 ) < 360 ) then
put xH1 + xH2 + 360 into xHX
else
put xH1 + xH2 - 360 into xHX
end if
else
put xH1 + xH2 into xHX
end if
put xHX / 2 into xHX
end if
put 1 - 0.17 * cos( xHX - 30 ) + 0.24 * cos( dToRadians( 2 * xHX ) ) + 0.32 * cos( dToRadians( 3 * xHX + 6 ) ) - 0.20 * cos( 4 * xHX - 63 ) into xTX
put 30 * exp( - ( ( xHX - 275 ) / 25 ) * ( ( xHX - 275 ) / 25 ) ) into xPH
put 2 * sqrt( ( xCY ^ 7 ) / ( ( xCY ^ 7 ) + ( 25 ^ 7 ) ) ) into xRC
put 1 + ( ( 0.015 * ( ( xLX - 50 ) * ( xLX - 50 ) ) ) / sqrt( 20 + ( ( xLX - 50 ) * ( xLX - 50 ) ) ) ) into xSL
put 1 + 0.045 * xCY into xSC
put 1 + 0.015 * xCY * xTX into xSH
put - sin( dToRadians( 2 * xPH ) ) * xRC into xRT
put xDL / ( WHTL * xSL ) into xDL
put xDC / ( WHTC * xSC ) into xDC
put xDH / ( WHTH * xSH ) into xDH
put sqrt( xDL ^ 2 + xDC ^ 2 + xDH ^ 2 + xRT * xDC * xDH ) into DeltaE94
return DeltaE94
end DeltaE2000
and this for CIElab2Hue function
Code: Select all
function CIElab2Hue var_a, var_b
-- CieLab2Hue( var_a, var_b ) //Function returns CIE-H° value
-- {
put 0 into var_bias
if var_a >= 0 and var_b = 0 then return 0
if var_a < 0 and var_b = 0 then return 180
if var_a = 0 and var_b > 0 then return 90
if var_a = 0 and var_b < 0 then return 270
if var_a > 0 and var_b > 0 then put 0 into var_bias
if var_a < 0 then put 180 into var_bias
if var_a > 0 and var_b < 0 then put 360 into var_bias
return ( rToDegrees( atan( var_b / var_a ) ) + var_bias )
end CIElab2Hue
When I say "not accurate" I mean "not correct"
I'm comparing two value : one measured by a spectrophotometer that give me Lab value -
ex :
L = 67.757847
a = -36.857219
b = -33.628765
And the other Lab value come from a list of commercial colors. I compare each color of the list with the measured color with the DeltaE2000 formula to get a result value.
The lowest value give me the best matching color.
With my current translation the result is wrong because the color are not matching.
Perhaps it's now more clear ... ahem... perhaps not