13,795,575 members
Alternative Tip/Trick
alternative version

Stats

6.8K views
1 bookmarked
Posted 4 Oct 2011
Licenced CPOL

Random Color Generator

, 5 Oct 2011
Eric,Thank...
Eric,

Thanks for implementing my color distance code. Since you are using CIE Lab color space from Guillaume's library, I had another look at the RGB <> CIEXYZ <> CIELab formulas. They are not quite correct. In your project, you will not see a big difference. However, if you will use the lib for other purposes, you'll see a BIG difference.

Further, Guillaume's library uses sRGB with D50 reference white, like all other copy/paste solutions. If you would compare the conversion with PhotoShop, you'll be surprised that the results do not match. Adobe uses RGB Bradford adapted with D65 reference white.

If you want to use RGB Bradford adapted CIELab conversion, do the following:

`public static readonly CIEXYZ D50 = new CIEXYZ(0.96422, 1.00000, 0.82521);`

In `RGBtoXYZ `method change matrix constants to:
```0.4360747  0.3850649  0.1430804
0.2225045  0.7168786  0.0606169
0.0139322  0.0971045  0.7141733```

In `XYZtoRGB `method, change matrix constants to (watchout for +/- signs):
```3.1338561 -1.6168667 -0.4906146
-0.9787684  1.9161415  0.0334540
0.0719453 -0.2289914  1.4052427```

In XYZtoLab method:
`change D65 to D50`

In LabtoXYZ method:
`change D65 to D50`

Here are the corrections for sRGB with D65 reference white:

```public static CIEXYZ RGBtoXYZ(int red, int green, int blue)
{
// normalize red, green, blue values
double rLinear = (double)red/255.0;
double gLinear = (double)green/255.0;
double bLinear = (double)blue/255.0;

// convert to a sRGB form
// corrected 2.2 to 2.4 (Rob)
double r = (rLinear > 0.04045)? Math.Pow((rLinear + 0.055)/(1 + 0.055), 2.4) : (rLinear/12.92) ;
double g = (gLinear > 0.04045)? Math.Pow((gLinear + 0.055)/(1 + 0.055), 2.4) : (gLinear/12.92) ;
double b = (bLinear > 0.04045)? Math.Pow((bLinear + 0.055)/(1 + 0.055), 2.4) : (bLinear/12.92) ;

// converts using sRGB Working Space Matrix and D65 Reference White
// expanded constants (Rob)
return new CIEXYZ(
(r*0.4124564 + g*0.3575761 + b*0.1804375),
(r*0.2126729 + g*0.7151522 + b*0.0721750),
(r*0.0193339 + g*0.1191920 + b*0.9503041)
);
}

public static RGB XYZtoRGB(double x, double y, double z)
{
// using sRGB Working Space Matrix and D65 Reference White
// expanded constants (Rob)
double[] Clinear = new double[3];
Clinear[0] = x*3.2404542 - y*1.5371385 - z*0.4985314; // red
Clinear[1] = -x*0.9692660 + y*1.8760108 - z*0.0415560; // green
Clinear[2] = x*0.0556434 - y*0.2040259 + z*1.0572252; // blue

for(int i=0; i<3; i++)
{
Clinear[i] = (Clinear[i]<=0.0031308)? 12.92*Clinear[i] : (1+0.055)* Math.Pow(Clinear[i], (1.0/2.4)) - 0.055;
}

return new RGB(
Convert.ToInt32( Double.Parse(String.Format("{0:0.00}", Clinear[0]*255.0)) ),
Convert.ToInt32( Double.Parse(String.Format("{0:0.00}", Clinear[1]*255.0)) ),
Convert.ToInt32( Double.Parse(String.Format("{0:0.00}", Clinear[2]*255.0)) )
);
}```

Happy coding.

Rob

Share

 Switzerland
No Biography provided

You may also be interested in...

 First Prev Next
 Reason for my vote of 5 Rob seems to really know the subject... Eric Ouellet4-Oct-11 10:34 Eric Ouellet 4-Oct-11 10:34
 Hello Rob, This is what I did and would appreciate your co... Eric Ouellet4-Oct-11 10:03 Eric Ouellet 4-Oct-11 10:03
 Thanks Rob, To be honnest, your alternative almost gave me ... Eric Ouellet4-Oct-11 9:19 Eric Ouellet 4-Oct-11 9:19
 Last Visit: 11-Dec-18 11:13     Last Update: 11-Dec-18 11:13 Refresh 1