-
// RGBYUV
-
// RGBXYZ
-
// RGBLAB
-
// RGBHSV
-
// RGBCMY
-
// XYZLAB
-
// YUV ->XYZ
-
// LAB ->HSV
-
// XYZ ->HSV
-
// RGB ->CMYK
-
// CMYK->CMY
-
// http://www.cnblogs.com/phinecos/archive/2009/05/03/1448121.html
-
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
-
// http://www.programmershare.com/1288015/
-
// http://blog.sina.com.cn/s/blog_6806030c0101ei9z.html
-
#include
-
template
-
const T& HYMin(const T& refT1, const T& refT2)
-
{
-
return (refT1 < refT2) ? refT1 : refT2;
-
}
-
template
-
const T& HYMax(const T& refT1, const T& refT2)
-
{
-
return (refT1 > refT2) ? refT1 : refT2;
-
}
-
// RGB转换为YUV
-
void RGB2YUV(double dR, double dG, double dB, double &dY, double &dU, double &dV)
-
{
-
dY = 0.257 * dR + 0.504 * dG + 0.098 * dB + 16; // y
-
dU = -0.148 * dR - 0.291 * dG + 0.439 * dB + 128; // u
-
dV = 0.439 * dR - 0.368 * dG - 0.071 * dB + 128; // v
-
}
-
// YUV转换为RGB
-
void YUV2RGB(double dY, double dU, double dV, double &dR, double &dG, double &dB)
-
{
-
dR = 1.0 * dY + 8 + 1.402 * (dV - 128);
-
dG = 1.0 * dY - 0.34413 * (dU - 128) - 0.71414 * (dV - 128);
-
dB = 1.0 * dY + 1.772 * (dU - 128) + 0;
-
}
-
// RGB转换为XYZ
-
void RGB2XYZ(double dR, double dG, double dB, double &dX, double &dY, double &dZ)
-
{
-
double dTempR = (dR / 255.0);
-
double dTempG = (dG / 255.0);
-
double dTempB = (dB / 255.0);
-
if(0.04045 < dTempR)
-
{
-
dTempR = pow((dTempR + 0.055) / 1.055, 2.4);
-
}
-
else
-
{
-
dTempR /= 12.92;
-
}
-
if(0.04045 < dTempG)
-
{
-
dTempG = pow((dTempG + 0.055) / 1.055, 2.4);
-
}
-
else
-
{
-
dTempG /= 12.92;
-
}
-
if(0.04045 < dTempB)
-
{
-
dTempB = pow((dTempB + 0.055) / 1.055, 2.4);
-
}
-
else
-
{
-
dTempB /= 12.92;
-
}
-
dTempR *= 100.0;
-
dTempG *= 100.0;
-
dTempB *= 100.0;
-
//Observer. = 2°, Illuminant = D65
-
dX = 0.4124564 * dTempR + 0.3575761 * dTempG + 0.1804375 * dTempB;
-
dY = 0.2126729 * dTempR + 0.7151522 * dTempG + 0.0721750 * dTempB;
-
dZ = 0.0193339 * dTempR + 0.1191920 * dTempG + 0.9503041 * dTempB;
-
}
-
// XYZ转换为LAB
-
void XYZ2LAB(double dX, double dY, double dZ, double &dL, double &dA ,double &dB)
-
{
-
double dTempX = dX / 95.047;
-
double dTempY = dY / 100.000;
-
double dTempZ = dZ / 108.883;
-
if(0.008856 < dTempX)
-
{
-
dTempX = pow((float)dTempX, 1.0f / 3.0f);
-
}
-
else
-
{
-
dTempX = ( 7.787 * dTempX ) + (16.0 / 116.0);
-
}
-
if(0.008856 < dTempY)
-
{
-
dTempY = pow((float)dTempY, 1.0f / 3.0f);
-
}
-
else
-
{
-
dTempY = (7.787 * dTempY) + (16.0 / 116.0);
-
}
-
if(0.008856 < dTempZ)
-
{
-
dTempZ = pow((float)dTempZ, 1.0f / 3.0f);
-
}
-
else
-
{
-
dTempZ = (7.787 * dTempZ) + (16.0 / 116.0);
-
}
-
dL = (116 * dTempY) - 16;
-
dA = 500 * (dTempX - dTempY);
-
dB = 200 * (dTempY - dTempZ);
-
}
-
// RGB转换为LAB
-
void RGB2LAB(double dR, double dG, double dB, double &dLAB_L, double &dLAB_A, double &dLAB_B)
-
{
-
double dX, dY, dZ;
-
RGB2XYZ(dR, dG, dB, dX, dY, dZ);
-
XYZ2LAB(dX, dY, dZ, dLAB_L, dLAB_A, dLAB_B);
-
}
-
// LAB转换为XYZ
-
void LAB2XYZ(double dLAB_L, double dLAB_A, double dLAB_B, double &dX, double &dY, double &dZ)
-
{
-
double dTempY = (dLAB_L + 16) / 116;
-
double dTempX = dLAB_A / 500 + dTempY;
-
double dTempZ = dTempY - dLAB_B / 200;
-
if(pow((double)dTempY, 3) > 0.008856)
-
{
-
dTempY = pow((double)dTempY, 3);
-
}
-
else
-
{
-
dTempY = (dTempY - 16 / 116) / 7.787;
-
}
-
if(pow((double)dTempX, 3) > 0.008856)
-
{
-
dTempX = pow((double)dTempX, 3);
-
}
-
else
-
{
-
dTempX = (dTempX - 16 / 116) / 7.787;
-
}
-
if(pow((double)dTempZ, 3) > 0.008856)
-
{
-
dTempZ = pow((double)dTempZ, 3);
-
}
-
else
-
{
-
dTempZ = (dTempZ - 16.0 / 116.0) / 7.787;
-
}
-
dX = 95.047 * dTempX;
-
dY = 100.000 * dTempY;
-
dZ = 108.883 * dTempZ;
-
}
-
// XYZ转换为RGB
-
void XYZ2RGB(double dX, double dY, double dZ, double &dR, double &dG, double &dB)
-
{
-
double dTempX = dX / 100.0f; // X from 0 to 95.047 (Observer = 2°, Illuminant = D65)
-
double dTempY = dY / 100.0f; // Y from 0 to 100.000
-
double dTempZ = dZ / 100.0f; // Z from 0 to 108.883
-
double dTempR = dTempX * 3.2404542 + dTempY * -1.5371385 + dTempZ * -0.4985314;
-
double dTempG = dTempX * -0.9692660 + dTempY * 1.8760108 + dTempZ * 0.0415560;
-
double dTempB = dTempX * 0.0556434 + dTempY * -0.2040259 + dTempZ * 1.0572252;
-
if(0.0031308 < dTempR)
-
{
-
dTempR = 1.055 * (pow(dTempR, (1 / 2.4))) - 0.055;
-
}
-
else
-
{
-
dTempR *= 12.92;
-
}
-
if(0.0031308 < dTempG)
-
{
-
dTempG = 1.055 * (pow(dTempG, (1 / 2.4))) - 0.055;
-
}
-
else
-
{
-
dTempG *= 12.92;
-
}
-
if(0.0031308 < dTempB)
-
{
-
dTempB = 1.055 * (pow(dTempB, (1 / 2.4))) - 0.055;
-
}
-
else
-
{
-
dTempB *= 12.92;
-
}
-
dR = 255.0f * dTempR;
-
dG = 255.0f * dTempG;
-
dB = 255.0f * dTempB;
-
}
-
// LAB转换为RGB
-
void LAB2RGB(double dLAB_L, double dLAB_A, double dLAB_B, double &dR, double &dG, double &dB)
-
{
-
double dX, dY, dZ;
-
LAB2XYZ(dLAB_L, dLAB_A, dLAB_B, dX, dY, dZ);
-
XYZ2RGB(dX, dY, dZ, dR, dG, dB);
-
}
-
// RGB转换为HSV
-
void RGB2HSV(double dR, double dG, double dB, double &dH, double &dS, double& dV)
-
{
-
double dTempR = (dR / 255); // RGB from 0 to 255
-
double dTempG = (dG / 255);
-
double dTempB = (dB / 255);
-
double dMin, dMax, dDelMax;
-
dMin = HYMin(HYMin(dTempR, dTempG), dTempB);
-
dMax = HYMax(HYMax(dTempR, dTempG), dTempB);
-
dDelMax = dMax - dMin; // Delta RGB value
-
dV = dMax;
-
if(0 == dMax) // This is a gray, no chroma
-
{
-
dH = 0.0; // HSV results from 0 to 1
-
dS = 0.0;
-
}
-
else // Chromatic data
-
{
-
dS = dDelMax / dMax;
-
double dDelR = (((dMax - dTempR) / 6) + (dDelMax / 2)) / dDelMax;
-
double dDelG = (((dMax - dTempG) / 6) + (dDelMax / 2)) / dDelMax;
-
double dDelB = (((dMax - dTempB) / 6) + (dDelMax / 2)) / dDelMax;
-
if(dTempR == dMax)
-
{
-
dH = dDelB - dDelG;
-
}
-
else if(dTempG == dMax)
-
{
-
dH = (1.0 / 3.0) + dDelR - dDelB;
-
}
-
else if(dTempB == dMax)
-
{
-
dH = (2.0 / 3.0) + dDelG - dDelR;
-
}
-
if(0 > dH)
-
{
-
dH += 1.0;
-
}
-
if(1 < dH)
-
{
-
dH -= 1.0;
-
}
-
}
-
}
-
// HSV转换为RGB
-
void HSV2RGB(double dH, double dS, double dV, double &dR, double &dG, double &dB)
-
{
-
if(dS == 0) // HSV from 0 to 1
-
{
-
dR = 255.0f * dV;
-
dG = 255.0f * dV;
-
dB = 255.0f * dV;
-
}
-
else
-
{
-
// 86912219
-
double dTempH, dTempI, dTemp1, dTemp2, dTemp3;
-
dTempH = 6.0f * dH;
-
if(6 == dTempH)
-
{
-
dTempH = 0.0; // H must be < 1
-
}
-
dTempI = int(dTempH); //Or var_i = floor( var_h )
-
dTemp1 = dV * (1 - dS);
-
dTemp2 = dV * (1 - dS * (dTempH - dTempI));
-
dTemp3 = dV * (1 - dS * (1 - (dTempH - dTempI)));
-
double dTempR, dTempG, dTempB;
-
if(0 == dTempI)
-
{
-
dTempR = dV;
-
dTempG = dTemp3 ;
-
dTempB = dTemp1;
-
}
-
else if(1 == dTempI)
-
{
-
dTempR = dTemp2 ;
-
dTempG = dV;
-
dTempB = dTemp1;
-
}
-
else if(2 == dTempI)
-
{
-
dTempR = dTemp1;
-
dTempG = dV;
-
dTempB = dTemp3;
-
}
-
else if (3 == dTempI)
-
{
-
dTempR = dTemp1 ;
-
dTempG = dTemp2 ;
-
dTempB = dV;
-
}
-
else if(4 == dTempI)
-
{
-
dTempR = dTemp3;
-
dTempG = dTemp1;
-
dTempB = dV;
-
}
-
else
-
{
-
dTempR = dV;
-
dTempG = dTemp1;
-
dTempB = dTemp2;
-
}
-
dR = 255.0f * dTempR; // RGB results from 0 to 255
-
dG = 255.0f * dTempR;
-
dB = 255.0f * dTempR;
-
}
-
}
-
// YUV转换为XYZ
-
void YUV2XYZ(double dL, double dU, double dV, double &dX, double &dY, double &dZ)
-
{
-
double dTempY, dRefX, dRefY, dRefZ, dRefU, dRefV, dTempU, dTempV;
-
dTempY = (dL + 16) / 116;
-
if(pow(dTempY, 3) > 0.008856)
-
{
-
dTempY = pow(dTempY, 3);
-
}
-
else
-
{
-
dTempY = (dTempY - 16.0 / 116.0) / 7.787;
-
}
-
dRefX = 95.047; //Observer= 2°, Illuminant= D65
-
dRefY = 100.000;
-
dRefZ = 108.883;
-
dRefU = (4 * dRefX ) / (dRefX + (15 * dRefY) + (3 * dRefZ));
-
dRefV = (9 * dRefY ) / (dRefX + (15 * dRefY) + (3 * dRefZ));
-
dTempU = dU / (13 * dL) + dRefU;
-
dTempV = dV / (13 * dL) + dRefV;
-
dY = dTempY * 100;
-
dX = -(9 * dY * dTempU) / ((dTempU - 4) * dTempV - dTempU * dTempV);
-
dZ = (9 * dY - (15 * dTempV * dY) - (dTempV * dX)) / (3 * dTempV);
-
}
-
// XYZ转换为HSV
-
void XYZ2HSV(double dX, double dY, double dZ,double &dH, double &dS, double &dV)
-
{
-
double dR, dG, dB;
-
XYZ2RGB(dX, dY, dZ, dR, dG, dB);
-
RGB2HSV(dR, dG, dB, dH, dS, dV);
-
}
-
// LAB转换为HSV
-
void LAB2HSV(double dL, double dA, double dB, double &dH, double &dS, double &dV)
-
{
-
double dX, dY, dZ;
-
LAB2XYZ(dL, dA, dB, dX, dY, dZ);
-
XYZ2HSV(dX, dY, dZ, dH, dS, dV);
-
}
-
// RGB转换为CMY
-
void RGB2CMY(double dR, double dG, double dB, double &dC, double &dM, double dY)
-
{
-
dC = 1.0 - (dR / 255.0f);
-
dM = 1.0 - (dG / 255.0f);
-
dY = 1.0 - (dB / 255.0f);
-
}
-
//CMY转换为RGB
-
void CMY2RGB(double dC, double dM, double dY, double &dR, double &dG, double &dB)
-
{
-
dR = (1.0f - dC) * 255.0f;
-
dG = (1.0f - dM) * 255.0f;
-
dB = (1.0f - dY) * 255.0f;
-
}
-
//RGB转换为CMYK
-
void RGB2CMYK(double dR, double dG, double dB, double &dC, double &dM, double dY, double &dK)
-
{
-
// RGB2CMY
-
RGB2CMY(dR, dG, dB, dC, dM, dY);
-
//CMYK and CMY values from 0 to 1
-
double dTempK = 1.0;
-
if(dC < dTempK)
-
{
-
dTempK = dC;
-
}
-
if(dM < dTempK)
-
{
-
dTempK = dM;
-
}
-
if(dY < dTempK)
-
{
-
dTempK = dY;
-
}
-
if(1 == dTempK)
-
{ //Black
-
dC = 0;
-
dM = 0;
-
dY = 0;
-
}
-
else
-
{
-
dC = (dC - dTempK) / (1 - dTempK);
-
dM = (dM - dTempK) / (1 - dTempK);
-
dY = (dY - dTempK) / (1 - dTempK);
-
}
-
dK = dTempK;
-
}
-
// CMYK转换为CMY
-
void CMYK2CMY(double dC1, double dM1, double dY1, double dK1, double &dC2, double &dM2, double dY2)
-
{
-
dC2 = (dC1 * (1 - dK1) + dK1);
-
dM2 = (dM1 * (1 - dK1) + dK1);
-
dY2 = (dY1 * (1 - dK1) + dK1);
-
}
// RGBHSL互转描述, 我已验证, 这个就是Windows颜色选择对话框的颜色选择转换算法
http://www.cnblogs.com/daiguagua/p/3311756.html