代码较为简洁,可以直接使用,RGB色彩空间与Lab色彩空间的相互转换的代码,可用于颜色聚类,或者颜色提取
struct BGR
{
int b;
int g;
int r;
};
struct Lab
{
double L;
double a;
double b;
};
void BGR2Lab(BGR &bgr, Lab &lab)
{
double b, g, r;
double x, y, z;
b = bgr.b / 255.0;
g = bgr.g / 255.0;
r = bgr.r / 255.0;
r = (r > 0.04045) ? pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
g = (g > 0.04045) ? pow((g + 0.055) / 1.055f, 2.4) : g / 12.92;
b = (b > 0.04045) ? pow((b + 0.055) / 1.055f, 2.4) : b / 12.92;
x = (r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047;
y = (r * 0.2126 + g * 0.7152 + b * 0.0722) / 1.00000;
z = (r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883;
//std::cout << pow(x, 0.3333) << " " << pow(y, 0.3333) << " " << pow(z, 1 / 3) << " " << std::endl;
x = (x > 0.008856) ? pow(x, 0.3333) : (7.787 * x) + 16.0 / 116.0;
y = (y > 0.008856) ? pow(y, 0.3333) : (7.787 * y) + 16.0 / 116.0;
z = (z > 0.008856) ? pow(z, 0.3333) : (7.787 * z) + 16.0 / 116.0;
//std::cout << x << " " << y << " " << z << " " << std::endl;
lab.L = (116.0 * y) - 16.0;
lab.a = 500.0 * (x - y);
lab.b = 200.0 * (y - z);
}
void Lab2BGR(Lab &lab, BGR &bgr)
{
double b, g, r;
double x, y, z;
double min, max;
double delta;
y = (lab.L + 16.0) / 116.0;
x = lab.a / 500.0 + y;
z = y - lab.b / 200.0;
x = 0.95047 * ((x * x * x > 0.008856) ? x * x * x : (x - 16 / 116.0) / 7.787);
y = 1.00000 * ((y * y * y > 0.008856) ? y * y * y : (y - 16 / 116.0) / 7.787);
z = 1.08883 * ((z * z * z > 0.008856) ? z * z * z : (z - 16 / 116.0) / 7.787);
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.2040 + z * 1.0570;
// std::cout << b << " " << g << " " << r << std::endl;
r = (r > 0.0031308) ? (1.055 * pow(r, 0.4166) - 0.055) : 12.92 * r;
g = (g > 0.0031308) ? (1.055 * pow(g, 0.4166) - 0.055) : 12.92 * g;
b = (b > 0.0031308) ? (1.055 * pow(b, 0.4166) - 0.055) : 12.92 * b;
bgr.b = MAX(0, MIN(1, b)) * 255;
bgr.g = MAX(0, MIN(1, g)) * 255;
bgr.r = MAX(0, MIN(1, r)) * 255;
}