Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Library : Other (not classified elsewhere) » Add new color Standard convertions RGB <-> Cie XYZ <-> Cie L*a*b*
Add new color Standard convertions RGB <-> Cie XYZ <-> Cie L*a*b* [message #32252] Tue, 03 May 2011 15:53 Go to next message
tojocky is currently offline  tojocky
Messages: 607
Registered: April 2008
Location: UK
Contributor

Hello All (especialy Mirek),

According by addresses:
- http://en.wikipedia.org/wiki/Lab_color_space#cite_note-12
- http://www.easyrgb.com/index.php?X=MATH&H=01#text1
- and others source-code projects

I propose to add the following functions in Core/Color.h/cpp:
void RGBtoXYZ(double r, double g, double b, double& x, double& y, double& z){
	r /= 255;
	g /= 255;
	b /= 255;
	double delta = 0.04045;//?
	if (r > delta)
		r = pow(((r + 0.055) / 1.055), 2.4);
	else r /= 12.92;
		
	if (g > delta)
		g = pow(((g + 0.055) / 1.055), 2.4);
	else g /= 12.92;
		
	if (b > delta)
		b = pow(((b + 0.055) / 1.055), 2.4);
	else b /= 12.92;

	//Observer. = 2, Illuminant = D65
	x = r * 41.24 + g * 35.76 + b * 18.05;
	y = r * 21.26 + g * 71.52 + b * 7.22;
	z = r * 1.93 + g * 11.92 + b * 95.05;
}

void XYZtoRGB(double x, double y, double z, int &r, int &g, int &b){
	double dr,dg,db;
	dr =  0.032406  * x - 0.015372 * y - 0.0049865 * z;
	dg = -0.0096891 * x + 0.018758 * y + 0.00041514* z;
	db =  0.00055708* x - 0.0020401* y + 0.01057   * z;

	if(dr > 0.0031308)
		dr = exp(log(dr) / 2.4) * 1.055-0.055;
	else dr = dr*12.92;

	if(dg > 0.0031308)
		dg = exp(log(dg) / 2.4) * 1.055 - 0.055;
	else dg = dg*12.92;

	if(db > 0.0031308)
		db = exp(log(db) / 2.4) * 1.055 - 0.055;
	else db = db*12.92;

	dr *= 255;
	dg *= 255;
	db *= 255;
	
	dr = minmax<double>(0.0,dr, 255.0);
	dg = minmax<double>(0.0,dg, 255.0);
	db = minmax<double>(0.0,db, 255.0);

	r = int(dr + 0.5); //?0.5
	g = int(dg + 0.5); //?0.5
	b = int(db + 0.5); //?0.5
}

void XYZtoCEILab(double x, double y, double z, double& l, double& a, double& b){
	x /= 95.047;           //ref_X =  95.047   Observer= 2, Illuminant= D65
	y /= 100.000;          //ref_Y = 100.000
	z /= 108.883;          //ref_Z = 108.883
	double delta = 0.008856; //pow(6/29,3);
	double delta2 = 7.787; //pow(29/6, 2)/3;
	
	if (x > delta)
		x = pow(x, 1/3);
	else x = (delta2 * x) + (4 / 29);
	
	if (y > delta)
		y = pow(y, 1/3);
	else y = (delta2 * y) + (4 / 29);
	
	if (z > delta)
		z = pow(z, 1/3);
	else z = (delta2 * z) + (4 / 29);
	
	l = (116 * y) - 16;
	a = 500 * (x - y);
	b = 200 * (y - z);
}

void CEILabtoXYZ(double l, double a, double b, double& x, double& y, double& z){
	y = (l + 16) / 116;
	x = y + a / 500;
	z = y - b / 200;
	
	double delta = 0.20689655; //6/29;
	double delta2 = 7.787; //pow(29/6, 2)/3;
	
	if (x > delta)
		x = pow(x, 3);
	else x = ((delta2 * x) - (4 / 29)) / delta2;
	
	if (y > delta)
		y = pow(y, 3);
	else y = ((delta2 * y) - (4 / 29)) / delta2;
	
	if (z > delta)
		z = pow(z, 3);
	else z = ((delta2 * z) - (4 / 29)) / delta2;
}

void RGBtoCEILab(double r, double g, double b, double& l, double& a, double& lb){
	double x,y,z;
	RGBtoXYZ(r,g,b,x,y,z);
	XYZtoCEILab(x,y,z,l,a,lb);
}

void CEILabtoRGB(double l, double a, double lb, double& r, double& g, double& b){
	double x,y,z;
	CEILabtoXYZ(l,a,lb,x,y,z);
	RGBtoXYZ(x,y,z,r,g,b);
}


This functions I will use in histogram equalization of image according by:
http://en.wikipedia.org/wiki/Histogram_equalisation

HSV/HSL is not so exact as CIE L*a*b*

Any comment are welcome!
Re: Add new color Standard convertions RGB <-> Cie XYZ <-> Cie L*a*b* [message #32775 is a reply to message #32252] Tue, 07 June 2011 20:57 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12183
Registered: November 2005
Ultimate Member
tojocky wrote on Tue, 03 May 2011 09:53

Hello All (especialy Mirek),

According by addresses:
- http://en.wikipedia.org/wiki/Lab_color_space#cite_note-12
- http://www.easyrgb.com/index.php?X=MATH&H=01#text1
- and others source-code projects

I propose to add the following functions in Core/Color.h/cpp:
void RGBtoXYZ(double r, double g, double b, double& x, double& y, double& z){
	r /= 255;
	g /= 255;
	b /= 255;
	double delta = 0.04045;//?
	if (r > delta)
		r = pow(((r + 0.055) / 1.055), 2.4);
	else r /= 12.92;
		
	if (g > delta)
		g = pow(((g + 0.055) / 1.055), 2.4);
	else g /= 12.92;
		
	if (b > delta)
		b = pow(((b + 0.055) / 1.055), 2.4);
	else b /= 12.92;

	//Observer. = 2, Illuminant = D65
	x = r * 41.24 + g * 35.76 + b * 18.05;
	y = r * 21.26 + g * 71.52 + b * 7.22;
	z = r * 1.93 + g * 11.92 + b * 95.05;
}

void XYZtoRGB(double x, double y, double z, int &r, int &g, int &b){
	double dr,dg,db;
	dr =  0.032406  * x - 0.015372 * y - 0.0049865 * z;
	dg = -0.0096891 * x + 0.018758 * y + 0.00041514* z;
	db =  0.00055708* x - 0.0020401* y + 0.01057   * z;

	if(dr > 0.0031308)
		dr = exp(log(dr) / 2.4) * 1.055-0.055;
	else dr = dr*12.92;

	if(dg > 0.0031308)
		dg = exp(log(dg) / 2.4) * 1.055 - 0.055;
	else dg = dg*12.92;

	if(db > 0.0031308)
		db = exp(log(db) / 2.4) * 1.055 - 0.055;
	else db = db*12.92;

	dr *= 255;
	dg *= 255;
	db *= 255;
	
	dr = minmax<double>(0.0,dr, 255.0);
	dg = minmax<double>(0.0,dg, 255.0);
	db = minmax<double>(0.0,db, 255.0);

	r = int(dr + 0.5); //?0.5
	g = int(dg + 0.5); //?0.5
	b = int(db + 0.5); //?0.5
}

void XYZtoCEILab(double x, double y, double z, double& l, double& a, double& b){
	x /= 95.047;           //ref_X =  95.047   Observer= 2, Illuminant= D65
	y /= 100.000;          //ref_Y = 100.000
	z /= 108.883;          //ref_Z = 108.883
	double delta = 0.008856; //pow(6/29,3);
	double delta2 = 7.787; //pow(29/6, 2)/3;
	
	if (x > delta)
		x = pow(x, 1/3);
	else x = (delta2 * x) + (4 / 29);
	
	if (y > delta)
		y = pow(y, 1/3);
	else y = (delta2 * y) + (4 / 29);
	
	if (z > delta)
		z = pow(z, 1/3);
	else z = (delta2 * z) + (4 / 29);
	
	l = (116 * y) - 16;
	a = 500 * (x - y);
	b = 200 * (y - z);
}

void CEILabtoXYZ(double l, double a, double b, double& x, double& y, double& z){
	y = (l + 16) / 116;
	x = y + a / 500;
	z = y - b / 200;
	
	double delta = 0.20689655; //6/29;
	double delta2 = 7.787; //pow(29/6, 2)/3;
	
	if (x > delta)
		x = pow(x, 3);
	else x = ((delta2 * x) - (4 / 29)) / delta2;
	
	if (y > delta)
		y = pow(y, 3);
	else y = ((delta2 * y) - (4 / 29)) / delta2;
	
	if (z > delta)
		z = pow(z, 3);
	else z = ((delta2 * z) - (4 / 29)) / delta2;
}

void RGBtoCEILab(double r, double g, double b, double& l, double& a, double& lb){
	double x,y,z;
	RGBtoXYZ(r,g,b,x,y,z);
	XYZtoCEILab(x,y,z,l,a,lb);
}

void CEILabtoRGB(double l, double a, double lb, double& r, double& g, double& b){
	double x,y,z;
	CEILabtoXYZ(l,a,lb,x,y,z);
	RGBtoXYZ(x,y,z,r,g,b);
}


This functions I will use in histogram equalization of image according by:
http://en.wikipedia.org/wiki/Histogram_equalisation

HSV/HSL is not so exact as CIE L*a*b*

Any comment are welcome!


This is fine code, but I am afraid too specialised for Core (I guess Core is sort of overloaded now).

What about bazaar or plugin or maybe Geom? Or perhaps Painter?

Maybe we should start a new "high level" raster graphics package? I think the equalization code would fit nicely there.
Re: Add new color Standard convertions RGB <-> Cie XYZ <-> Cie L*a*b* [message #32776 is a reply to message #32775] Tue, 07 June 2011 23:03 Go to previous message
tojocky is currently offline  tojocky
Messages: 607
Registered: April 2008
Location: UK
Contributor

mirek wrote on Tue, 07 June 2011 21:57



This is fine code, but I am afraid too specialised for Core (I guess Core is sort of overloaded now).

What about bazaar or plugin or maybe Geom? Or perhaps Painter?

Maybe we should start a new "high level" raster graphics package? I think the equalization code would fit nicely there.


This code is not quite correct. I have the latest tested version. I used this code to autolevel color images (converted into CIE L*a*b*). HSV autolevel of color images losts some color (this problem persists in Photoshop too).

Ok, I can prepare a package and uploat into bazaar. But I think it is a better idea to include it in Painter.

[Updated on: Wed, 08 June 2011 23:06]

Report message to a moderator

Previous Topic: new! ANTI VIRUS FALSE POSITIVE with Upp (GUI MT FileSel)
Next Topic: Weired appearance of GUI elements
Goto Forum:
  


Current Time: Mon Feb 17 14:34:29 CET 2020

Total time taken to generate the page: 0.00991 seconds