📄 color.h
字号:
template<typename Real>voidRGB_converter_to_HSV<Real>::RGB_to_HSV(const double r, const double g, const double b, double* const h, double* const s, double* const v){ const double min = std::min(r,std::min(g,b)); const double max = std::max(r,std::max(g,b)); const double delta = max - min; *v = max; if (max!=0) *s = delta / max; else { *s = 0; *h = 0; return; } if (delta==0) { *s = 0; *h = 0; return; } if(r==max) { *h = ( g - b ) / delta; // between yellow & magenta } else if( g == max ) { *h = 2 + ( b - r ) / delta; // between cyan & yellow } else { *h = 4 + ( r - g ) / delta; // between magenta & cyan } *h /= 6; if(*h<0){ *h += 1; }} template<typename Real>voidRGB_converter_to_HSV<Real>::HSV_to_RGB(const double h,const double s,const double v, double* const r,double* const g,double* const b){ if(s==0) { // achromatic (grey) *r = v; *g = v; *b = v; return; } const int i = static_cast<int>(floor(6*h)); const double f = 6*h - i; const double p = v * ( 1 - s ); const double q = v * ( 1 - s * f ); const double t = v * ( 1 - s * ( 1 - f ) ); switch(i) { case 6: case 0: *r = v; *g = t; *b = p; break; case 1: *r = q; *g = v; *b = p; break; case 2: *r = p; *g = v; *b = t; break; case 3: *r = p; *g = q; *b = v; break; case 4: *r = t; *g = p; *b = v; break; default: *r = v; *g = p; *b = q; break; } }//@}/* ############################## # class RGB_converter_to_RGB # ##############################*/template<typename Real>voidRGB_converter_to_RGB<Real>::from_RGB_to_cartesian(const double r, const double g, const double b, component_type* const x, component_type* const y, component_type* const z){ *x = static_cast<component_type>(r); *y = static_cast<component_type>(g); *z = static_cast<component_type>(b);}template<typename Real>voidRGB_converter_to_RGB<Real>::from_cartesian_to_RGB(const component_type x, const component_type y, const component_type z, double* const r, double* const g, double* const b){ *r = static_cast<double>(x); *g = static_cast<double>(y); *b = static_cast<double>(z);}/* ############################## # class RGB_converter_to_XYZ # ##############################*///! Assume CIE-RGB.template<typename Real>voidRGB_converter_to_XYZ<Real>::from_RGB_to_cartesian(const double r, const double g, const double b, component_type* const x, component_type* const y, component_type* const z){ const double rg = std::pow(r,2.2); const double gg = std::pow(g,2.2); const double bg = std::pow(b,2.2); *x = static_cast<component_type>(rg*0.488718 + gg*0.310680 + bg*0.200602); *y = static_cast<component_type>(rg*0.176204 + gg*0.812985 + bg*0.0108109); *z = static_cast<component_type>(rg*0.0 + gg*0.0102048 + bg*0.989795);// *x = static_cast<component_type>(r*0.412453 + g*0.357580 + b*0.180423);// *y = static_cast<component_type>(r*0.212671 + g*0.715160 + b*0.072169);// *z = static_cast<component_type>(r*0.019334 + g*0.119193 + b*0.950227);}//! Assume CIE-RGB.template<typename Real>voidRGB_converter_to_XYZ<Real>::from_cartesian_to_RGB(const component_type x, const component_type y, const component_type z, double* const r, double* const g, double* const b){// const double R =// static_cast<double>(x*3.240479 + y*-1.537150 + z*-0.498535);// const double G =// static_cast<double>(x*-0.969256 + y*1.875992 + z*0.041556);// const double B =// static_cast<double>(x*0.055648 + y*-0.204043 + z*1.057311); const double R = static_cast<double>(x*2.37067 + y*-0.900040 + z*-0.470634); const double G = static_cast<double>(x*-0.513885 + y*1.42530 + z*0.0885814); const double B = static_cast<double>(x*0.00529818 + y*-0.0146949 + z*1.00940); *r = std::pow(std::max(0.0,R),1.0/2.2); *g = std::pow(std::max(0.0,G),1.0/2.2); *b = std::pow(std::max(0.0,B),1.0/2.2); /* if (R<0.0) { *r = 0.0; } else if (R>1.0) { *r = 1.0; } else { *r = std::pow(R,1.0/2.2); } if (G<0.0) { *g = 0.0; } else if (G>1.0) { *g = 1.0; } else { *g = std::pow(G,1.0/2.2); } if (B<0.0) { *b = 0.0; } else if (B>1.0) { *b = 1.0; } else { *b = std::pow(B,1.0/2.2); } */}/* ############################## # class RGB_converter_to_Luv # ##############################*/// Reference white is CIE Etemplate<typename Real>const double RGB_converter_to_Luv<Real>::Xn = 1.0;template<typename Real>const double RGB_converter_to_Luv<Real>::Yn = 1.0;template<typename Real>const double RGB_converter_to_Luv<Real>::Zn = 1.0;// template<typename Real>// const double RGB_converter_to_Luv<Real>::Xn = 0.95045592705;// template<typename Real>// const double RGB_converter_to_Luv<Real>::Yn = 1.0;// template<typename Real>// const double RGB_converter_to_Luv<Real>::Zn = 1.0890577508;template<typename Real>doubleRGB_converter_to_Luv<Real>::L2Y(const double l){ return (l>8) ? Yn*pow((l+16)/116,3.0) : Yn*l/24389.0*27.0;}template<typename Real>doubleRGB_converter_to_Luv<Real>::Y2L(const double y){ const double ratio = y/Yn; return (ratio>216.0/24389.0) ? 116 * pow(ratio,1.0/3.0) - 16 : 24389.0/27.0 * ratio;}template<typename Real>voidRGB_converter_to_Luv<Real>::from_RGB_to_cartesian(const double r, const double g, const double b, component_type* const x, component_type* const y, component_type* const z){ // const double X = r*0.412453 + g*0.357580 + b*0.180423;// const double Y = r*0.212671 + g*0.715160 + b*0.072169;// const double Z = r*0.019334 + g*0.119193 + b*0.950227; double X,Y,Z; RGB_converter_to_XYZ<double>::from_RGB_to_cartesian(r,g,b,&X,&Y,&Z); *x = static_cast<component_type>(Y2L(Y / Yn)); const double tmp = Xn + 15 * Yn + 3 * Zn; const double unp = 4 * Xn / tmp; const double vnp = 9 * Yn / tmp; const double tmp2 = X + 15 * Y + 3 * Z; const double up = (X==0)? 0 : 4 * X / tmp2; const double vp = (Y==0)? 0 : 9 * Y / tmp2; *y = static_cast<component_type>(13 * (*x) * (up - unp)); *z = static_cast<component_type>(13 * (*x) * (vp - vnp));}template<typename Real>voidRGB_converter_to_Luv<Real>::from_cartesian_to_RGB(const component_type x, const component_type y, const component_type z, double* const r, double* const g, double* const b){ const double Y = L2Y(static_cast<double>(x)); const double tmp = Xn + 15 * Yn + 3 * Zn; const double unp = 4 * Xn / tmp; const double vnp = 9 * Yn / tmp; const double Q = ((x==0) ? 0 : static_cast<double>(y) / (13 * static_cast<double>(x))) + unp; const double R = ((x==0) ? 0 : static_cast<double>(z) / (13 * static_cast<double>(x))) + vnp; const double A = 3 * Y * (5 * R - 3); const double Z = (R == 0) ? 0 : (((Q - 4) * A - 15 * Q * R * Y) / (12 * R)); const double X = (R == 0) ? 0 : (-(A / R + 3 * Z));// const double red = X*3.240479 + Y*-1.537150 + Z*-0.498535;// const double green = X*-0.969256 + Y*1.875992 + Z*0.041556;// const double blue = X*0.055648 + Y*-0.204043 + Z*1.057311; double red,green,blue; RGB_converter_to_XYZ<double>::from_cartesian_to_RGB(X,Y,Z,&red,&green,&blue);/* if (red<0.0) { *r = 0.0; } else if (red>1.0) { *r = 1.0; } else { *r = red; } if (green<0.0) { *g = 0.0; } else if (green>1.0) { *g = 1.0; } else { *g = green; } if (blue<0.0) { *b = 0.0; } else if (blue>1.0) { *b = 1.0; } else { *b = blue; }*/}/* ############################## # class RGB_converter_to_Lab # ##############################*/// Reference white is CIE Etemplate<typename Real>const double RGB_converter_to_Lab<Real>::Xn = 1.0;template<typename Real>const double RGB_converter_to_Lab<Real>::Yn = 1.0;template<typename Real>const double RGB_converter_to_Lab<Real>::Zn = 1.0;template<typename Real>voidRGB_converter_to_Lab<Real>::from_RGB_to_cartesian(const double r, const double g, const double b, component_type* const x, component_type* const y, component_type* const z){ double X,Y,Z; RGB_converter_to_XYZ<double>::from_RGB_to_cartesian(r,g,b,&X,&Y,&Z); const double xr = X/Xn; const double yr = Y/Yn; const double zr = Z/Zn; const double fx = (xr>216.0/24389.0) ? std::pow(xr,1.0/3.0) : (24389.0/27.0*xr + 16.0) / 116.0; const double fy = (yr>216.0/24389.0) ? std::pow(yr,1.0/3.0) : (24389.0/27.0*yr + 16.0) / 116.0; const double fz = (zr>216.0/24389.0) ? std::pow(zr,1.0/3.0) : (24389.0/27.0*zr + 16.0) / 116.0; *x = 116.0*fy - 16.0; *y = 500.0 * (fx-fy); *z = 200.0 * (fy-fz);}template<typename Real>voidRGB_converter_to_Lab<Real>::from_cartesian_to_RGB(const component_type x, const component_type y, const component_type z, double* const r, double* const g, double* const b){ const double yr = (x>8) ? std::pow((x+16.0) / 116.0,3.0) : x / 24389.0 * 27.0; const double fy = (yr>216.0/24389.0) ? (x+16.0) / 116.0 : (24389.0/27.0*yr+16.0) / 116.0; const double fx = y / 500.0 + fy; const double fz = fy - z / 200.0; const double xr = (fx > std::pow(216.0/24389.0,1.0/3.0)) ? std::pow(fx,3.0) : (116.0*fx - 16.0) / 24389.0 * 27.0; const double zr = (fz > std::pow(216.0/24389.0,1.0/3.0)) ? std::pow(fz,3.0) : (116.0*fz - 16.0) / 24389.0 * 27.0; const double X = xr*Xn; const double Y = yr*Yn; const double Z = zr*Zn; RGB_converter_to_XYZ<double>::from_cartesian_to_RGB(X,Y,Z,r,g,b);/* double red,green,blue; RGB_converter_to_XYZ<double>::from_cartesian_to_RGB(X,Y,Z,&red,&green,&blue); if (red<0.0) { *r = 0.0; } else if (red>1.0) { *r = 1.0; } else { *r = red; } if (green<0.0) { *g = 0.0; } else if (green>1.0) { *g = 1.0; } else { *g = green; } if (blue<0.0) { *b = 0.0; } else if (blue>1.0) { *b = 1.0; } else { *b = blue; }*/}/* ##################################### # class RGB_converter_to_grey_level # ##################################### */template<typename Real>voidRGB_converter_to_grey_level<Real>::from_RGB_to_cartesian(const double r, const double g, const double b, component_type* const x, component_type* const y, component_type* const z){ *x = static_cast<component_type>((r+g+b)/3.0); *y = static_cast<component_type>(0); *z = static_cast<component_type>(0);}template<typename Real>voidRGB_converter_to_grey_level<Real>::from_cartesian_to_RGB(const component_type x, const component_type y, const component_type z, double* const r, double* const g, double* const b){ *r = static_cast<double>(x); *g = static_cast<double>(x); *b = static_cast<double>(x);}/* ######################### # Fonctions hors classe # ######################### */template<typename RGB_converter>std::ostream& operator<<(std::ostream& s, const Basic_color<RGB_converter>& c){ s<<c.x<<"\t"<<c.y<<"\t"<<c.z<<"\t"; return s;}#undef CONST_STATIC#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -