How to replicate v9's color conversion to LAB under v10

Mathematica 10(.0.0) appears to use a different flavor of the LAB color space, but I would like to emulate the same behavior observed in version 9(.0.0).

v9

Brown
(*RGBColor[0.6, 0.4, 0.2]*)

ColorConvert[Brown, "RGB" -> "LAB"]
(*{0.714252,0.0598271,0.283735}*)


v10

Brown // FullForm
(*RGBColor[0.6,0.4,0.2]*)

ColorConvert[Brown, "RGB" -> "LAB"] // FullForm
(*LABColor[0.4802420048160916, 0.17425620426156752, 0.3687165422680724]*)


v10 ColorConversion's documentation mentions a D50 white point and LABColor's even lists some formulas, but v9's docs avoid the subject completely.

Which conversion is correct? Are they equivalent, only with a different "black magic" color space parameter? And, if so, how could I replicate v9's results under v10?

• Related: 7483. One of the answers replicates the V9 conversion. Nov 6, 2014 at 1:45
• v9's lightness of 0.71 is far too light to be brown. Here's an independent implementation of RGB to Lab conversion, whose results are close to v10's (although slightly different because it uses a D65 white point).
– user484
Nov 6, 2014 at 3:47

I had implemented my own color conversion functions previously so that I could convert to the Msh color space, a polar version of LAB, so I thought I'd give it a go.

To do the color conversion, you have to know what reference white value is being used. The numeric values can be found here where they are referred to as reference illuminant tristimulus values. Next you need a transformation matrix to go from sRGB to XYZ color spaces, and the exact matrix you use depends again on the reference white.

Version 10 uses a D50 reference for XYZ and LAB, while version 9 seems to have used a D65 (but this is a small difference and not enough to account for the dramatically different values you find).

Here is what happens in version 10:

rgb2labV10[r_, g_, b_] := Module[{
referenceWhite = {96.42, 100.0, 82.49},
transformation = {
{0.4360747, 0.3850649, 0.1430804},
{0.2225045, 0.7168786, 0.0606169},
{0.0139322, 0.0971045, 0.7141733}
},
rgblinear, x, y, z, f},
(*Transform RGB to linear RGB *)

rgblinear =
If[# > .04045, ((# + 0.055)/1.055)^2.4, #/12.92] & /@ {r, g, b};
(*Transform linear RGB to XYZ *)
{x, y, z} =
100 transformation.rgblinear;

(*Transform XYZ to LAB *)

f = If[((#) > 0.008856), (#^(1/3)), (7.787 # + 4/29.)] &;
{x, y, z} = f /@ ({x, y, z}/referenceWhite);
{116.0 (y - 4./29), 500.0 (x - y), 200 (y - z)}/100
]

rgb2labV10[.6, .4, .2]
(* {0.480242, 0.174275, 0.368625} *)


For some reason, in the previous version, Mathematica omits the step of first converting to linear RGB color - even though this seems to be the norm. See here, here, and here for example.

The conversion is therefore given by

rgb2labV9[r_, g_, b_] := Module[{
referenceWhite = {95.047, 100.0, 108.883},
transformation = {
{0.4124564, 0.3575761, 0.1804375},
{0.2126729, 0.7151522, 0.072175},
{0.0193339, 0.119192, 0.9503041}
},
x, y, z, f},
(*Transform linear RGB to XYZ *)
{x, y, z} =
100 transformation.{r, g, b};

(*Transform XYZ to LAB *)

f = If[((#) > 0.008856), (#^(1/3)), (7.787 # + 4/29.)] &;
{x, y, z} = f /@ ({x, y, z}/referenceWhite);
{116.0 (y - 4./29), 500.0 (x - y), 200 (y - z)}/100
]

rgb2labV9[.6, .4, .2]
(* {0.714258, 0.0598473, 0.283741} *)

• If waiting a year is what it takes to have a nice answer like this one, so be it! I have a few other unanswered questions wink wink Feb 12, 2016 at 12:43
• You accounted for chromatic adaptation in this case, yes? Feb 12, 2016 at 13:07
• @J.M., ja - I followed the formulas from this site Feb 12, 2016 at 13:09
• It bothers me slightly that I only have accuracy up to about 4 decimal places, but I suppose that Mathematica might truncate their conversion matrices a little bit more than Bruce Lindbloom does. Feb 12, 2016 at 13:12
• Why is it that Mathematica and MatLab can't get colorspaces right? They both seem to have a lot of errors in their built-in color functions. D65 is the standard illuminant, not D50. But you might need D50 if you are working with ICC profiles for printing (the print industry uses D50. Everyone else, including the paper and ink industries, use D65 — figure that one out, LOL). Illuminants and chromatic adaptation should be abstracted away from the color spaces. Neither XYZ nor LAB, LUV or other requires any particular illuminant, and there are plenty of reasons to be flexible on this. Dec 3, 2020 at 3:18