Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

ColConvert.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Array_Element_ColConvert_h
00002 #define Impala_Core_Array_Element_ColConvert_h
00003 
00004 #include "Core/Array/Element/ArithTypes.h"
00005 #include "Core/Array/Element/E1Sum.h"
00006 #include "Core/Array/Element/E1Min.h"
00007 
00008 namespace Impala
00009 {
00010 namespace Core
00011 {
00012 namespace Array
00013 {
00014 namespace Element
00015 {
00016 
00017 
00018 // RGB - CMY
00019 
00024 inline Vec3Real64
00025 ColRGB2CMY(const Vec3Real64& v)
00026 {
00027     return Vec3Real64(1, 1, 1) - v;
00028 }
00029 
00034 inline Vec3Real64
00035 ColCMY2RGB(const Vec3Real64& v)
00036 {
00037     return Vec3Real64(1, 1, 1) - v;
00038 }
00039 
00040 // RGB - XYZ 1931 through Rec709
00041 
00046 inline Vec3Real64
00047 ColRGB2XYZ(const Vec3Real64& v)
00048 {
00049     // Using Rec709
00050     // X = 100 * (0.412452 R/255 + 0.357580 G/255 + 0.180423 B/255)
00051     // Y = 100 * (0.212671 R/255 + 0.715160 G/255 + 0.072169 B/255)
00052     // Z = 100 * (0.019334 R/255 + 0.119193 G/255 + 0.950227 B/255)
00053 
00054     double X = v.X() * 0.161746 + v.Y() * 0.140227 + v.Z() * 0.070754;
00055     double Y = v.X() * 0.083400 + v.Y() * 0.280455 + v.Z() * 0.028301;
00056     double Z = v.X() * 0.007582 + v.Y() * 0.046742 + v.Z() * 0.372638;
00057     
00058     return Vec3Real64(X, Y, Z);
00059 }
00060 
00065 inline Vec3Real64
00066 ColXYZ2RGB(const Vec3Real64& v)
00067 {
00068     // Using rec709
00069     // R = 255 * (3.240479 X/100 - 1.537150 * Y/100 - 0.498535 * Z/100)
00070     // G = 255 * (-0.969256 * X/100 + 1.875992 * Y/100 + 0.041556 * Z/100)
00071     // B = 255 * (0.055648 * Z/100 - 0.204043 * Y/100 + 1.057311 * Z/100)
00072 
00073     double R = v.X() * 8.25322145 + v.Y() * -3.9197325 + v.Z() * -1.27126425;
00074     double G = v.X() * -2.4716028 + v.Y() * 4.7837796 + v.Z() * 0.1059678;
00075     double B = v.X() * 0.1419024 + v.Y() * -0.52030965 + v.Z() * 2.69614305;
00076 
00077     return Vec3Real64(R, G, B);
00078 }
00079 
00080 // CMY - XYZ 1931 through Rec709
00081 
00086 inline Vec3Real64
00087 ColCMY2XYZ(const Vec3Real64& v)
00088 {
00089     // Using rec709
00090     // R = 1-C, G = 1-M, B = 1-Y
00091 
00092     double X = 95.045385
00093         - v.X() * 0.161746 - v.Y() * 0.140227 - v.Z() * 0.070754;
00094     double Y = 100.0
00095         - v.X() * 0.083400 - v.Y() * 0.280455 - v.Z() * 0.028301;
00096     double Z = 108.87531
00097         - v.X() * 0.007582 - v.Y() * 0.046742 - v.Z() * 0.372638;
00098 
00099     return Vec3Real64(X, Y, Z);
00100 }
00101 
00106 inline Vec3Real64
00107 ColXYZ2CMY(const Vec3Real64& v)
00108 {
00109     // Using rec709
00110     // C = 1-R, M = 1-G, Y = 1-B
00111 
00112     double C = 255.0
00113         - v.X() * 8.25322145 - v.Y() * -3.9197325 - v.Z() * -1.27126425;
00114     double M = 255.0
00115         - v.X() * -2.4716028 - v.Y() * 4.7837796 - v.Z() * 0.1059678;
00116     double Y = 255.0
00117         - v.X() * 0.1419024 - v.Y() * -0.52030965 - v.Z() * 2.69614305;
00118 
00119     return Vec3Real64(C, M, Y);
00120 }
00121 
00122 // Lab - XYZ 1931
00123 // Using D65 (95.0, 100.0, 108.9) as ref white
00124 const double Xn = 95.0;
00125 const double Yn = 100.0;
00126 const double Zn = 108.9;
00127 
00128 static inline double
00129 Y2L(double YYn)
00130 {
00131     return (YYn > 0.008856) ? 116.0 * pow(YYn , 1.0 / 3.0) - 16.0
00132                             : 903.3 * YYn;
00133 }
00134 
00135 static inline double
00136 L2Y(double L)
00137 {
00138     return (L > 7.999625) ? Yn * pow((L + 16.0) / 116.0, 3.0)
00139                           : Yn * (L / 903.3);
00140 }
00141 
00142 static inline double
00143 f4ab(double r)
00144 {
00145     return (r > 0.008856) ? pow(r, 1.0 / 3.0) 
00146                           : 7.787 * r + (16.0 / 116.0);
00147 }
00148 
00149 static inline double
00150 fInv4ab(double r, double Ltmp)
00151 {
00152     return (Ltmp > 0.206893) ? pow(r, 3.0)
00153                              : (r - 16.0 / 116.0) / 7.787;
00154 }
00155 
00160 inline Vec3Real64
00161 ColLab2XYZ(const Vec3Real64& v)
00162 {
00163     double Y = L2Y(v.X());
00164 
00165     double Ltmp = (v.X() + 16.0) / 116.0; // == f(Y / Yn)
00166     double atmp = Ltmp + v.Y() / 500.0;
00167     double X = Xn * fInv4ab(atmp, Ltmp);
00168     double btmp = Ltmp - v.Z() / 200.0;
00169     double Z = Zn * fInv4ab(btmp, Ltmp);
00170     return Vec3Real64(X, Y, Z);
00171 }
00172 
00177 inline Vec3Real64
00178 ColXYZ2Lab(const Vec3Real64& v)
00179 {
00180     Vec3Real64 n = v / Vec3Real64(Xn, Yn, Zn);
00181 
00182     double L = Y2L(n.Y());
00183 
00184     double fnX = f4ab(n.X());
00185     double fnY = f4ab(n.Y());
00186     double fnZ = f4ab(n.Z());
00187         
00188     double a = 500.0 * (fnX - fnY);
00189     double b = 200.0 * (fnY - fnZ);
00190     return Vec3Real64(L, a, b);
00191 }
00192 
00193 
00194 // Luv - XYZ 1931
00195 // Using D65 (95.0, 100.0, 108.9) as ref white
00196 
00201 inline Vec3Real64
00202 ColLuv2XYZ(const Vec3Real64& v)
00203 {
00204     double Y = L2Y(v.X());
00205     double tmp = Xn + 15 * Yn + 3 * Zn;
00206     double unp = 4 * Xn / tmp;
00207     double vnp = 9 * Yn / tmp;
00208     double Q = v.Y() / (13 * v.X()) + unp;
00209     double R = v.Z() / (13 * v.X()) + vnp;
00210     double A = 3 * Y * (5 * R - 3);
00211     double Z = ((Q - 4) * A - 15 * Q * R * Y) / (12 * R);
00212     double X = -(A / R + 3 * Z);
00213     return Vec3Real64(X, Y, Z);
00214 }
00215 
00220 inline Vec3Real64
00221 ColXYZ2Luv(const Vec3Real64& v)
00222 {
00223     double L = Y2L(v.Y() / Yn);
00224     double tmp = Xn + 15 * Yn + 3 * Zn;
00225     double unp = 4 * Xn / tmp;
00226     double vnp = 9 * Yn / tmp;
00227     tmp = v.X() + 15 * v.Y() + 3 * v.Z();
00228     double up = 4 * v.X() / tmp;
00229     double vp = 9 * v.Y() / tmp;
00230     double us = 13 * L * (up - unp);
00231     double vs = 13 * L * (vp - vnp);
00232     return Vec3Real64(L, us, vs);
00233 }
00234 
00235 
00236 // RGB - HSI
00237 #ifdef PI
00238 #undef PI
00239 #endif
00240 #define PI          3.1415926536
00241 #define TWO_PI      6.2831853072     /* PI * 2   */
00242 #define PI_3        1.0471975512     /* PI/3     */
00243 #define TWO_PI_3    2.0943951024     /* 2 * PI/3 */
00244 #define FOUR_PI_3   4.1887902048     /* 4 * PI/3 */
00245 #define FIVE_PI_3   5.2359877560     /* 5 * PI/3 */
00246 
00250 inline Vec3Real64
00251 ColRGB2HSI(const Vec3Real64& v)
00252 {
00253     double I = E1Sum(v) / 3.0;
00254     double S = (I == 0.0) ? 1.0 : 1.0 - (E1Min(v) / I);
00255     double H;
00256     if (v.X() == v.Y() && v.Y() == v.Z())
00257         H = 0.0;
00258     else {
00259         double tmp = acos((0.5*(v.X()-v.Y()+v.X()-v.Z())) / 
00260                 sqrt((v.X()-v.Y())*(v.X()-v.Y())+(v.X()-v.Z())*(v.Y()-v.Z())));
00261         H = (v.Y() > v.Z()) ? tmp : TWO_PI - tmp;
00262     }
00263     return Vec3Real64(H, S, I);
00264 }
00265 
00269 //michiel: huh? the range of this function seems tot be [0..3] for R, G and B... what does that mean?
00270 // does convert to normalised RGB? in that case why isn't RGB2rgb in chorus?
00271 inline Vec3Real64
00272 ColHSI2RGB(const Vec3Real64& v)
00273 {
00274     double H = v.X();
00275     double S = v.Y();
00276     double I = v.Z();
00277     double Htmp;
00278     double R,B,G;
00279     
00280     if (H == 0.0)
00281         R = G = B = I;
00282     else if (H > 0.0 && H < TWO_PI_3 ) {
00283         Htmp = 1 / sqrt(3.0) * tan(H - PI_3);
00284         B = (1.0 - S) * I;
00285         G = (1.5 + 1.5*Htmp ) * I - ((0.5 + 1.5*Htmp) * B);
00286         R = 3.0 * I - G - B;
00287     }
00288     else if (H >= TWO_PI_3 && H < FOUR_PI_3) {
00289         Htmp = 1 / sqrt(3.0) * tan(H - PI);
00290         R = (1.0 - S) * I;
00291         B = (1.5 + 1.5*Htmp ) * I - ((0.5 + 1.5*Htmp) * R);
00292         G = 3.0 * I - B - R;
00293     }
00294     else { 
00295         Htmp = 1 / sqrt(3.0) * tan(H - FIVE_PI_3);
00296         G = (1.0 - S) * I;
00297         R = (1.5 + 1.5*Htmp ) * I - ((0.5 + 1.5*Htmp) * G);
00298         B = 3.0 * I - R - G;
00299     }
00300     return Vec3Real64(R, G, B);
00301 }
00302 
00303 #undef PI
00304 #undef TWO_PI
00305 #undef PI_3
00306 #undef TWO_PI_3
00307 #undef FOUR_PI_3
00308 #undef FIVE_PI_3
00309 
00310 // XYZ 1931 - OOO (Geusebroek Thesis)
00311 
00316 inline Vec3Real64
00317 ColXYZ2OOO(const Vec3Real64& v)
00318 {
00319     double E   = v.X() *-0.004362 + v.Y() * 0.010954 + v.Z() * 0.003408;
00320     double El  = v.X() * 0.004055 + v.Y() * 0.001220 + v.Z() *-0.004120;
00321     double Ell = v.X() * 0.011328 + v.Y() *-0.011755 + v.Z() *-0.000664;
00322 
00323     return Vec3Real64(E, El, Ell);
00324 }
00325 
00326 // OOO - XYZ 1931 (Geusebroek Thesis)
00327 
00332 inline Vec3Real64
00333 ColOOO2XYZ(const Vec3Real64& v)
00334 {
00335     double X = v.X() * 103.337 + v.Y() * 68.824 + v.Z() * 103.435;
00336     double Y = v.X() * 92.297  + v.Y() * 74.949 + v.Z() * 8.714;
00337     double Z = v.X() * 129.034 + v.Y() * -152.804 + v.Z() * 104.383;
00338 
00339     return Vec3Real64(X, Y, Z);
00340 }
00341 
00342 // RGB - OOO through Rec709
00343 
00350 inline Vec3Real64
00351 ColRGB2OOO(const Vec3Real64& v)
00352 {
00353     double E   = v.X() * 0.000233846 + v.Y() * 0.00261968 + v.Z() * 0.00127135;
00354     double El  = v.X() * 0.000726333 + v.Y() * 0.000718106+ v.Z() * -0.00121377;
00355     double Ell = v.X() * 0.000846833 + v.Y() * -0.00173932+ v.Z() * 0.000221515;
00356 
00357     return Vec3Real64(E, El, Ell);
00358 }
00359 
00360 // OOO - RGB through Rec709
00361 
00368 inline Vec3Real64
00369 ColOOO2RGB(const Vec3Real64& v)
00370 {
00371     double R = v.X() * 328.084 + v.Y() * 469.182 + v.Z() * 687.853;
00372     double G = v.X() * 199.794 + v.Y() * 172.242 + v.Z() * -202.904;
00373     double B = v.X() * 314.533 + v.Y() * -441.212 + v.Z() * 291.574;
00374 
00375     return Vec3Real64(R, G, B);
00376 }
00377 
00378 
00379 // RGB - 24bit
00380 
00383 inline int
00384 ColRGB2int(const Vec3Real64& v)
00385 {
00386     int x = (int) (v.X());
00387     if (x < 0)
00388         x = 0;
00389     else {
00390         if (x > 255)
00391             x = 255;
00392     }
00393     int y = (int) (v.Y());
00394     if (y < 0)
00395         y = 0;
00396     else {
00397         if (y > 255)
00398             y = 255;
00399     }
00400     int z = (int) (v.Z());
00401     if (z < 0)
00402         z = 0;
00403     else {
00404         if (z > 255)
00405             z = 255;
00406     }
00407     return (255 << 24) | (x << 16) | (y << 8) | z;
00408 }
00409 
00412 inline int
00413 ColRGB2int(const Vec3Int32& v)
00414 {
00415     int x = v.X();
00416     if (x < 0)
00417         x = 0;
00418     else {
00419         if (x > 255)
00420             x = 255;
00421     }
00422     int y = v.Y();
00423     if (y < 0)
00424         y = 0;
00425     else {
00426         if (y > 255)
00427             y = 255;
00428     }
00429     int z = v.Z();
00430     if (z < 0)
00431         z = 0;
00432     else {
00433         if (z > 255)
00434             z = 255;
00435     }
00436     return (255 << 24) | (x << 16) | (y << 8) | z;
00437 }
00438 
00439 } // namespace Element
00440 } // namespace Array
00441 } // namespace Core
00442 } // namespace Impala
00443 
00444 #endif

Generated on Fri Mar 19 09:30:44 2010 for ImpalaSrc by  doxygen 1.5.1