色彩空间转换

本文详细介绍了RGB、YUV、XYZ、LAB、HSV等色彩空间之间的转换算法,包括RGB到YUV、XYZ、LAB、HSV的转换公式,以及这些色彩空间相互间的转换过程。
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->//RGB转换为YUV
voidRGB2YUV(doubleR,doubleG,doubleB,double&Y,double&U,double&V)
{
Y
=static_cast<double>(0.257*R+0.504*G+0.098*B+16);//y
U=static_cast<double>(-0.148*R-0.291*G+0.439*B+128);//u
V=static_cast<double>(0.439*R-0.368*G-0.071*B+128);//v
}

//YUV转换为RGB
voidYUV2RGB(doubleY,doubleU,doubleV,double&R,double&G,double&B)
{
R
=static_cast<double>(1.0*Y+8+1.402*(V-128));//r
G=static_cast<double>(1.0*Y-0.34413*(U-128)-0.71414*(V-128));
B
=static_cast<double>(1.0*Y+1.772*(U-128)+0);
}
//RGB转换为XYZ
voidRGB2XYZ(doubler,doubleg,doublebdouble&x,double&y,double&z)
{

doublevar_R,var_G,var_B;
var_R
=(r/255.0f);
var_G
=(g/255.0f);
var_B
=(b/255.0f);

if(var_R>0.04045)
{
var_R
=pow((var_R+0.055)/1.055,2.4);

}
else
{
var_R
=var_R/12.92;
}
if(var_G>0.04045)
{
var_G
=pow((var_G+0.055)/1.055,2.4);
}
else
{
var_G
=var_G/12.92;
}
if(var_B>0.04045)
{
var_B
=pow((var_B+0.055)/1.055,2.4);
}
else
{
var_B
=var_B/12.92;
}

var_R
=var_R*100.0f;
var_G
=var_G*100.0f;
var_B
=var_B*100.0f;

//Observer.=2°,Illuminant=D65
x=var_R*0.4124+var_G*0.3576+var_B*0.1805;
y
=var_R*0.2126+var_G*0.7152+var_B*0.0722;
z
=var_R*0.0193+var_G*0.1192+var_B*0.9505;
}

//XYZ转换为LAB
voidXYZ2LAB(doublex,doubley,doublez,double&L,double&A,double&B)
{
doublevar_X,var_Y,var_Z;
var_X
=x/95.047f;
var_Y
=y/100.000f;
var_Z
=z/108.883f;

if(var_X>0.008856)
{
var_X
=pow((float)var_X,1.0f/3.0f);
}
else
{
var_X
=(7.787*var_X)+(16/116);
}
if(var_Y>0.008856)
{
var_Y
=pow((float)var_Y,1.0f/3.0f);
}
else
{
var_Y
=(7.787*var_Y)+(16/116);
}
if(var_Z>0.008856)
{
var_Z
=pow((float)var_Z,1.0f/3.0f);
}
else
{
var_Z
=(7.787*var_Z)+(16/116);
}

L
=(116*var_Y)-16;
A
=500*(var_X-var_Y);
B
=200*(var_Y-var_Z);
}

//RGB转换为LAB
voidRGB2LAB(doubler,doubleg,doubleb,double&L,double&A,double&B)
{
doublex,y,z;
RGB2XYZ(r,g,b,x,y,z);
XYZ2LAB(x,y,z,L,A,B);
}
//LAB转换为RGB
voidLAB2RGB(doubleL,doubleA,doubleB,double&R,double&G,double&B)
{
doublex,y,z[3];
this->LAB2XYZ(L,A,B,x,y,z);
this->XYZ2RGB(x,y,z,R,G,B);
}
//LAB转换为XYZ
voidLAB2XYZ(doublelab_L,doublelab_A,doublelab_B,double&X,double&Y,double&Z)
{
doublevar_X,var_Y,var_Z;

var_Y
=(lab_L+16)/116;
var_X
=lab_A/500+var_Y;
var_Z
=var_Y-lab_B/200;

if(pow((double)var_Y,3)>0.008856)
var_Y
=pow((double)var_Y,3);
else
var_Y
=(var_Y-16/116)/7.787;
if(pow((double)var_X,3)>0.008856)
var_X
=pow((double)var_X,3);
else
var_X
=(var_X-16/116)/7.787;
if(pow((double)var_Z,3)>0.008856)
var_Z
=pow((double)var_Z,3);
else
var_Z
=(var_Z-16/116)/7.787;

X
=95.047*var_X;
Y
=100.000*var_Y;
Z
=108.883*var_Z;
}

//XYZ转换为RGB
voidXYZ2RGB(doublex,doubley,doublez,double&R,double&G,double&B)
{
doublevar_X,var_Y,var_Z,var_R,var_G,var_B;
doublex,y,z;

var_X
=x/100.0f;//Xfrom0to95.047(Observer=2°,Illuminant=D65)
var_Y=y/100.0f;//Yfrom0to100.000
var_Z=z/100.0f;//Zfrom0to108.883

var_R
=var_X*3.2406+var_Y*-1.5372+var_Z*-0.4986;
var_G
=var_X*-0.9689+var_Y*1.8758+var_Z*0.0415;
var_B
=var_X*0.0557+var_Y*-0.2040+var_Z*1.0570;

if(var_R>0.0031308)
var_R
=1.055*(pow(var_R,(1/2.4)))-0.055;
else
var_R
=12.92*var_R;
if(var_G>0.0031308)
var_G
=1.055*(pow(var_G,(1/2.4)))-0.055;
else
var_G
=12.92*var_G;
if(var_B>0.0031308)
var_B
=1.055*(pow(var_B,(1/2.4)))-0.055;
else
var_B
=12.92*var_B;
R
=var_R*255.0f;
G
=var_G*255.0f;
b
=var_B*255.0f;
}

//RGB转换为HSV
voidRGB2HSV(doubleR,doubleG,doubleB,double&H,double&S,doubleV)
{
doublevar_R,var_G,var_B;

var_R
=(R/255);//RGBfrom0to255
var_G=(G/255);
var_B
=(B/255);

doublevar_Min,var_Max,del_Max;
var_Min
=min(min(var_R,var_G),var_B);
var_Max
=max(max(var_R,var_G),var_B);
del_Max
=var_Max-var_Min;//DeltaRGBvalue

doubleH,S,V;
V
=var_Max;

if(del_Max==0)//Thisisagray,nochroma
{
H
=0;//HSVresultsfrom0to1
S=0;
}
else//Chromaticdata
{
S
=del_Max/var_Max;

doubledel_R,del_G,del_B;
del_R
=(((var_Max-var_R)/6)+(del_Max/2))/del_Max;
del_G
=(((var_Max-var_G)/6)+(del_Max/2))/del_Max;
del_B
=(((var_Max-var_B)/6)+(del_Max/2))/del_Max;

if(var_R==var_Max)
H
=del_B-del_G;
elseif(var_G==var_Max)
H
=(1/3)+del_R-del_B;
elseif(var_B==var_Max)
H
=(2/3)+del_G-del_R;

if(H<0)
H
+=1;
if(H>1)
H
-=1;
}
}

//HSV转换为RGB
voidHSV2RGB(doubleH,doubleS,doubleV,double&R,double&G,double&B)
{
doubleR,G,B;
if(S==0)//HSVfrom0to1
{
R
=V*255.0f;
G
=V*255.0f;
B
=V*255.0f;
}
else
{
doublevar_h,var_i,var_1,var_2,var_3;
var_h
=H*6.0f;
if(var_h==6)
var_h
=0;//Hmustbe<1
var_i=int(var_h);//Orvar_i=floor(var_h)
var_1=V*(1-S);
var_2
=V*(1-S*(var_h-var_i));
var_3
=V*(1-S*(1-(var_h-var_i)));

doublevar_r,var_g,var_b;
if(var_i==0)
{
var_r
=V;
var_g
=var_3;
var_b
=var_1;
}
elseif(var_i==1)
{
var_r
=var_2;
var_g
=V;
var_b
=var_1;
}
elseif(var_i==2)
{
var_r
=var_1;
var_g
=V;
var_b
=var_3;
}
elseif(var_i==3)
{
var_r
=var_1;
var_g
=var_2;
var_b
=V;
}
elseif(var_i==4)
{
var_r
=var_3;
var_g
=var_1;
var_b
=V;
}
else
{
var_r
=V;
var_g
=var_1;
var_b
=var_2;
}

R
=var_r*255.0f;//RGBresultsfrom0to255
G=var_g*255.0f;
B
=var_b*255.0f;
}
}
//YUV转换为XYZ
voidYUV2XYZ(doubleL,doubleU,doubleV,double&X,double&Y,double&Z)
{
doublevar_Y,ref_X,ref_Y,ref_Z,ref_U,ref_V,var_U,var_V;
var_Y
=(L+16)/116;
if(pow(var_Y,3)>0.008856)
var_Y
=pow(var_Y,3);
else
var_Y
=(var_Y-16/116)/7.787;

ref_X
=95.047;//Observer=2°,Illuminant=D65
ref_Y=100.000;
ref_Z
=108.883;

ref_U
=(4*ref_X)/(ref_X+(15*ref_Y)+(3*ref_Z));
ref_V
=(9*ref_Y)/(ref_X+(15*ref_Y)+(3*ref_Z));

var_U
=U/(13*L)+ref_U;
var_V
=V/(13*L)+ref_V;

Y
=var_Y*100;
X
=-(9*Y*var_U)/((var_U-4)*var_V-var_U*var_V);
Z
=(9*Y-(15*var_V*Y)-(var_V*X))/(3*var_V);

}
//LAB转换为HSV
voidLAB2HSV(doubleL,doubleA,doubleB,double&H,double&S,double&V)
{
doubleX,Y,Z;
this->LAB2XYZ(L,A,B,X,Y,Z);
this->XYZ2HSV(X,Y,Z,H,S,V);
}
//XYZ转换为HSV
voidXYZ2HSV(doubleX,doubleY,doubleZ,double&H,double&S,double&V)
{
doubleR,G,B;
this->XYZ2RGB(X,Y,Z,R,G,B);
this->RGB2HSV(R,G,B,H,S,V);
}
//RGB转换为CMY
voidRGB2CMY(doubleR,doubleG,doubleB,double&C,double&M,doubleY)
{
C
=1.0-(R/255.0f);
M
=1.0-(G/255.0f);
Y
=1.0-(B/255.0f);
}
//CMY转换为RGB
voidCMY2RGB(doubleC,doubleM,doubleY,double&R,double&G,double&B)
{
R
=(1.0f-C)*255.0f;
G
=(1.0f-M)*255.0f;
B
=(1.0f-Y)*255.0f;
}
//RGB转换为CMYK
voidRGB2CMYK(doubleR,doubleG,doubleB,double&C,double&M,doubleY,double&K)
{
doublebufCMY[3];
//RGB2CMY
this->RGB2CMY(R,G,B,C,M,Y);
//CMYKandCMYvaluesfrom0to1
doublevar_K;

var_K
=1;

if(C<var_K)
var_K
=C;
if(M<var_K)
var_K
=M;
if(Y<var_K)
var_K
=Y;
if(var_K==1)
{
//Black
C=0;
M
=0;
Y
=0;
}
else
{
C
=(C-var_K)/(1-var_K);
M
=(M-var_K)/(1-var_K);
Y
=(Y-var_K)/(1-var_K);
}
K
=var_K;

}
//CMYK转换为CMY
voidCMYK2CMY(doubleC1,doubleM1,doubleY1,doubleK1,double&C2,double&M2,doubleY2)
{
C2
=(C1*(1-K1)+K1);
M2
=(M1*(1-K1)+K1);
Y2
=(Y1*(1-K1)+K1);
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值