用c++实现颜色空间rgb,grey,luv和lab的互转
(2013-03-27 15:51:54)
标签:
颜色空间转换cpp图像处理 |
分类: 编程 |
现在做计算机视觉,为了便于用到工程上,很多时候都直接用c++写了,并且不太想用opencv(感觉太臃肿)。写了几种常用的颜色空间转换代码,希望和大家分享http://www/uc/myshow/blog/misc/gif/E___6690EN00SIGG.gif:
rgb转grey,rgb转luv,rgb转lab;
grey转rgb,grey转luv,grey转lab;
luv转rgb,luv转grey;
lab转rgb,lab转grey;
double R = ((double) rgb[0]) /
(double)255.0;
double G = ((double) rgb[1]) /
(double)255.0;
double B = ((double) rgb[2]) /
(double)255.0;
double y = (double)0.212671 * R +
(double)0.715160 * G + (double)0.072169 * B;
if (y > (double)0.008856) {
grey[0] = (double)116.0
* pow(y, (double)1.0 / (double)3.0) - (double)16.0;
}
else {
grey[0] = (double)903.3
* y;
}
double L, u,
v;
double R =
((double) rgb[0]) / (double)255.0;
double G =
((double) rgb[1]) / (double)255.0;
double B =
((double) rgb[2]) / (double)255.0;
double x =
(double)0.412453 * R + (double)0.357580 * G + (double)0.180423 *
B;
double y =
(double)0.212671 * R + (double)0.715160 * G + (double)0.072169 *
B;
double z =
(double)0.019334 * R + (double)0.119193 * G + (double)0.950227 *
B;
if (y >
0.008856) {
L = (double)116.0 * pow(y, (double)1.0 /
(double)3.0) - (double)16.0;
}
else {
L = (double)903.3 * y;
}
double sum = x +
15 * y + 3 * z;
if (sum != 0)
{
u = 4 * x / sum, v = 9 * y / sum;
}
else {
u = 4.0, v = (double)9.0 / (double)15.0;
}
luv[0] =
L;
luv[1] = 13 * L
* (u - (double)0.19784977571475);
luv[2] = 13 * L
* (v - (double)0.46834507665248);
double R = ((double) rgb[0]) /
(double)255.0;
double G = ((double) rgb[1]) /
(double)255.0;
double B = ((double) rgb[2]) /
(double)255.0;
double X = 0.412453 * R +
0.357580 * G + 0.180423 * B;
double Y = 0.212671 * R +
0.715160 * G + 0.072169 * B;
double Z = 0.019334 * R +
0.119193 * G + 0.950227 * B;
double xr = X / 0.950456, yr = Y / 1.000,
zr = Z / 1.088854;
if (yr > 0.008856) {
lab[0] = 116.0 * pow(yr,
1.0 / 3.0) - 16.0;
}
else {
lab[0] = 903.3 *
yr;
}
double fxr, fyr, fzr;
if (xr > 0.008856) {
fxr = pow(xr, 1.0 /
3.0);
}
else {
fxr = 7.787 * xr + 16.0
/ 116.0;
}
if (yr > 0.008856) {
fyr = pow(yr, 1.0 /
3.0);
}
else {
fyr = 7.787 * yr + 16.0
/ 116.0;
}
if(zr > 0.008856) {
fzr = pow(zr, 1.0 /
3.0);
}
else {
fzr = 7.787 * zr + 16.0
/ 116.0;
}
lab[1] = 500.0 * (fxr - fyr);
lab[2] = 200.0 * (fyr - fzr);
if (grey[0] < (double)0.1) {
rgb[0] = rgb[1] = rgb[2]
= 0;
}
else {
double y;
if(grey[0] <=
(double)7.9996) {
y =
255 * grey[0] / (double)903.3;
}
else {
y =
(grey[0] + (double)16.0) / (double)116.0, y = 255
* y * y * y;
}
rgb[0] = (unsigned
char)((y < 0) ? 0 : ((y > 255) ? 255 : y));
rgb[2] = rgb[1] =
rgb[0];
}
luv[0] = grey[0], luv[1] = luv[2] =
0;
lab[0] = grey[0], lab[1] = lab[2] =
0;
if (luv[0] < 0.1) {
rgb[0] = rgb[1] = rgb[2]
= 0;
}
else {
double x, y, z, u,
v;
if (luv[0] <=
(double)7.9996) {
y =
luv[0] / (double)903.3;
}
else {
y =
(luv[0] + (double)16.0) / (double)116.0, y = y *
y * y;
}
u = luv[1] / (13 *
luv[0]) + (double)0.19784977571475;
v = luv[2] / (13 *
luv[0]) + (double)0.46834507665248;
x = 9 * u * y / (4 *
v);
z = (12 - 3 * u - 20 *
v) * y / (4 * v);
double R =
(double)3.240479 * x - (double)1.537150 * y - (double)0.498535 *
z;
double G =
(double)-0.969256 * x + (double)1.875992 * y + (double)0.041556 *
z;
double B =
(double)0.055648 * x - (double)0.204043 * y + (double)1.057311 *
z;
R *= 255, G *= 255, B *=
255;
rgb[0] = (unsigned
char)((R < 0) ? 0 : ((R > 255) ? 255 : R));
rgb[1] = (unsigned
char)((G < 0) ? 0 : ((G > 255) ? 255 : G));
rgb[2] = (unsigned
char)((B < 0) ? 0 : ((B > 255) ? 255 : B));
}
grey[0] = luv[0];
double X, Y, Z;
double P = (lab[0] + 16.0) / 116.0;
if (lab[0] > 7.9996) {
Y = 1.000 * P * P *
P;
}
else {
Y = 1.000 * lab[0] /
903.3;
}
double yr = Y / 1.000, fy;
if (yr > 0.008856) {
fy = pow(yr, 1.0 /
3.0);
}
else {
fy = 7.787 * yr + 16.0 /
116.0;
}
double fx = lab[1] / 500.0 + fy, fz = fy -
lab[2] / 200.0;
if(fx > 0.2069) {
X = 0.950456 * fx * fx *
fx;
}
else {
X = 0.950456 / 7.787 *
(fx - 16.0 / 116.0);
}
if (fz > 0.2069) {
Z = 1.088854 * fz * fz *
fz;
}
else {
Z = 1.088854 / 7.787 *
(fz - 16.0 / 116.0);
}
double R = 3.240479 * X - 1.537150 * Y -
0.498535 * Z;
double G = -0.969256 * X + 1.875992 * Y +
0.041556 * Z;
double B = 0.055648 * X - 0.204043 * Y +
1.057311 * Z;
R *= 255, G *= 255, B *= 255;
rgb[0] = (unsigned char)((R < 0) ? 0 :
((R > 255) ? 255 : R));
rgb[1] = (unsigned char)((G < 0) ? 0 :
((G > 255) ? 255 : G));
rgb[2] = (unsigned char)((B < 0) ? 0 :
((B > 255) ? 255 : B));
grey[0] = lab[0];
rgb转grey:
void RgbToGrey(unsigned char *rgb, double
*grey)
{
}
rgb转lvu:
void RgbToLuv(unsigned char *rgb,
double *luv)
{
}
rgb转lab:
void RgbToLab(unsigned char *rgb, double *lab)
{
}
grey转rgb:
void GreyToRgb(double *grey, unsigned char *rgb)
{
}
grey转luv:
void GreyToLuv(double *grey,
double *luv)
{
}
grey转lab:
void GreyToLab(double *grey, double *lab)
{
}
luv转rgb:
void LuvToRgb(double *luv, unsigned char *rgb)
{
}
luv转grey:
void LuvToGrey(double *luv,
double *grey)
{
}
lab转rgb:
void LabToRgb(double *lab, unsigned char *rgb)
{
}
lab转grey:
void LabToGrey(double *lab,
double *grey)
{
}