Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

# Modules/ImageProcessor/ImageProcessorTools/ColorModelConversions.h

Go to the documentation of this file.

    00001 /**
    00002  * @file ColorModelConversions.h
    00003  *
    00004  * Declaration and implementation of class ColorModelConversions
    00005  */
    00006
    00007 #ifndef __ColorModelConversions_h_
    00008 #define __ColorModelConversions_h_
    00009
    00010 #include "Tools/Math/Common.h"
    00011
    00012 /**
    00013 * A class that defines static conversions between color models for single pixels.
    00014 */
    00015 class ColorModelConversions
    00016 {
    00017 public:
    00018   /** Converts an YCbCr pixel into an RGB pixel.
    00019    *  @param Y The Y channel of the source pixel.
    00020    *  @param Cb The Cb channel of the source pixel.
    00021    *  @param Cr The Cr channel of the source pixel.
    00022    *  @param R The R channel of the target pixel.
    00023    *  @param G The G channel of the target pixel.
    00024    *  @param B The B channel of the target pixel.
    00025    */
    00026   static void fromYCbCrToRGB(unsigned char Y,
    00027                              unsigned char Cb,
    00028                              unsigned char Cr,
    00029                              unsigned char& R,
    00030                              unsigned char& G,
    00031                              unsigned char& B)
    00032   {
    00033     int r = (int)(Y + 1.4021 * (Cb - 128)),
    00034         g = (int)(Y - 0.3456 * (Cr - 128) - 0.71448 * (Cb - 128)),
    00035         b = (int)(Y + 1.7710 * (Cr - 128));
    00036     if(r < 0) r = 0; else if(r > 255) r = 255;
    00037     if(g < 0) g = 0; else if(g > 255) g = 255;
    00038     if(b < 0) b = 0; else if(b > 255) b = 255;
    00039     R = (unsigned char) r;
    00040     G = (unsigned char) g;
    00041     B = (unsigned char) b;
    00042   }
    00043
    00044   /** Converts an RGB pixel into an YCbCr pixel.
    00045    *  @param R The R channel of the source pixel.
    00046    *  @param G The G channel of the source pixel.
    00047    *  @param B The B channel of the source pixel.
    00048    *  @param Y The Y channel of the target pixel.
    00049    *  @param Cb The Cb channel of the target pixel.
    00050    *  @param Cr The Cr channel of the target pixel.
    00051    */
    00052   static void fromRGBToYCbCr(unsigned char R,
    00053                              unsigned char G,
    00054                              unsigned char B,
    00055                              unsigned char& Y,
    00056                              unsigned char& Cb,
    00057                              unsigned char& Cr)
    00058   {
    00059     int y = (int)( 0.2990 * R + 0.5870 * G + 0.1140 * B),
    00060         cb = 127 + (int)(-0.1687 * R - 0.3313 * G + 0.5000 * B),
    00061         cr = 127 + (int)( 0.5000 * R - 0.4187 * G - 0.0813 * B);
    00062     if(y < 0) y = 0; else if(y > 255) y = 255;
    00063     if(cb < 0) cb = 0; else if(cb > 255) cb = 255;
    00064     if(cr < 0) cr = 0; else if(cr > 255) cr = 255;
    00065     Y = (unsigned char) y;
    00066     Cb = (unsigned char) cb;
    00067     Cr = (unsigned char) cr;
    00068   }
    00069
    00070   /** Converts an YCbCr pixel into an HSI pixel.
    00071    *  @param Y The Y channel of the source pixel.
    00072    *  @param Cb The Cb channel of the source pixel.
    00073    *  @param Cr The Cr channel of the source pixel.
    00074    *  @param H The H channel of the target pixel.
    00075    *  @param S The S channel of the target pixel.
    00076    *  @param I The I channel of the target pixel.
    00077    */
    00078   static void fromYCbCrToHSI(unsigned char Y,
    00079                              unsigned char Cb,
    00080                              unsigned char Cr,
    00081                              unsigned char& H,
    00082                              unsigned char& S,
    00083                              unsigned char& I)
    00084   {
    00085     const double sqrt3 = 1.732050808;
    00086     unsigned char R,
    00087                   G,
    00088                   B;
    00089     fromYCbCrToRGB(Y, Cb, Cr, R, G, B);
    00090     I = R;
    00091     if(G > I) I = G;
    00092     if(B > I) I = B;
    00093     if(I)
    00094     {
    00095       S = R;
    00096       if(G < S) S = G;
    00097       if(B < S) S = B;
    00098       S = (unsigned char) (255 - 255 * S / I);
    00099       if(S)
    00100       {
    00101         int h = int(atan2(sqrt3 * (G - B), 2 * R - G - B) / pi2 * 256);
    00102         if(h > 255) h -= 256;
    00103         else if(h < 0) h += 256;
    00104         H = (unsigned char) h;
    00105       }
    00106       else
    00107         H = 0;
    00108     }
    00109     else
    00110       S = H = 0;
    00111   }
    00112
    00113   /** Converts an HSI pixel into an YCbCr pixel.
    00114    *  @param H The H channel of the source pixel.
    00115    *  @param S The S channel of the source pixel.
    00116    *  @param I The I channel of the source pixel.
    00117    *  @param Y The Y channel of the target pixel.
    00118    *  @param Cb The Cb channel of the target pixel.
    00119    *  @param Cr The Cr channel of the target pixel.
    00120    */
    00121   static void fromHSIToYCbCr(unsigned char H,
    00122                              unsigned char S,
    00123                              unsigned char I,
    00124                              unsigned char& Y,
    00125                              unsigned char& Cb,
    00126                              unsigned char& Cr)
    00127   {
    00128     double h = 1.0 - H / 255.0,
    00129            s = S / 255.0,
    00130            r,
    00131            g,
    00132            b;
    00133
    00134     if(h < 1.0 / 3.0)
    00135     {
    00136       g = (1 - s) / 3;
    00137       b = (1 + s * cos(pi2 * h) / cos(pi2 * (1.0 / 6.0 - h))) / 3.0;
    00138       r = 1 - (g + b);
    00139     }
    00140     else if(h < 2.0 / 3.0)
    00141     {
    00142       h -= 1.0 / 3.0;
    00143       b = (1 - s) / 3;
    00144       r = (1 + s * cos(pi2 * h) / cos(pi2 * (1.0 / 6.0 - h))) / 3.0;
    00145       g = 1 - (b + r);
    00146     }
    00147     else
    00148     {
    00149       h -= 2.0 / 3.0;
    00150       r = (1 - s) / 3;
    00151       g = (1 + s * cos(pi2 * h) / cos(pi2 * (1.0 / 6.0 - h))) / 3.0;
    00152       b = 1 - (r + g);
    00153     }
    00154
    00155     r *= I * 3;
    00156     g *= I * 3;
    00157     b *= I * 3;
    00158     if(r > 255)
    00159       r = 255;
    00160     if(g > 255)
    00161       g = 255;
    00162     if(b > 255)
    00163       b = 255;
    00164
    00165     fromRGBToYCbCr((unsigned char) r,
    00166                    (unsigned char) g,
    00167                    (unsigned char) b,
    00168                    Y, Cb, Cr);
    00169   }
    00170
    00171   /** Converts an YCbCr pixel into a TSL pixel.
    00172    *  @param Y The Y channel of the source pixel.
    00173    *  @param Cb The Cb channel of the source pixel.
    00174    *  @param Cr The Cr channel of the source pixel.
    00175    *  @param T The T channel of the target pixel.
    00176    *  @param S The S channel of the target pixel.
    00177    *  @param L The L channel of the target pixel.
    00178    */
    00179   static void fromYCbCrToTSL(unsigned char Y,
    00180                              unsigned char Cb,
    00181                              unsigned char Cr,
    00182                              unsigned char& T,
    00183                              unsigned char& S,
    00184                              unsigned char& L)
    00185   {
    00186     const double pi2_div = 0.15915494309189533576888376337251;  /* 1.0 / (PI * 2.0) */
    00187
    00188     double cb = Cb - 128.0,
    00189            cr = Cr - 128.0,
    00190            tmp = 1.0 / (4.3403 * Y +  2.0 * cb + cr),
    00191            tmp_r = (-0.6697 * cb + 1.6959 * cr) * tmp,
    00192            tmp_g = (-1.168  * cb - 1.3626 * cr) * tmp,
    00193            tmp_b = ( 1.8613 * cb - 0.331  * cr) * tmp;
    00194     double t_out;
    00195     if(tmp_g > 0.0)
    00196       t_out = (atan2(tmp_r, tmp_g) * pi2_div + 0.25) * 255.0;
    00197     else if(tmp_g < 0.0)
    00198       t_out = (atan2(-tmp_r, -tmp_g) * pi2_div + 0.75) * 255.0;
    00199     else
    00200       t_out = 0.0;
    00201     double s_out = sqrt(1.8 * (tmp_r * tmp_r + tmp_g * tmp_g + tmp_b * tmp_b)) * 255.0;
    00202
    00203     if(t_out < 0.0)
    00204       t_out = 0.0;
    00205     else if(t_out > 255.0)
    00206       t_out = 255.0;
    00207     if(s_out < 0.0)
    00208       s_out = 0.0;
    00209     else if(s_out > 255.0)
    00210       s_out = 255.0;
    00211
    00212     T = (unsigned char) t_out;
    00213     S = (unsigned char) s_out;
    00214     L = Y;
    00215   }
    00216
    00217   /** Converts a TSL pixel into an YCbCr pixel.
    00218    *  @param T The T channel of the source pixel.
    00219    *  @param S The S channel of the source pixel.
    00220    *  @param L The L channel of the source pixel.
    00221    *  @param Y The Y channel of the target pixel.
    00222    *  @param Cb The Cr channel of the target pixel.
    00223    *  @param Cr The Cr channel of the target pixel.
    00224    */
    00225   static void fromTSLToYCbCr(unsigned char T,
    00226                              unsigned char S,
    00227                              unsigned char L,
    00228                              unsigned char& Y,
    00229                              unsigned char& Cb,
    00230                              unsigned char& Cr)
    00231   {
    00232     double rad = S * 0.555 / 255.0,
    00233            phi = (T * 2 / 255.0 + 0.25) * pi,
    00234            cr = 128 + rad * cos(phi) * 255.0,
    00235            cb = 128 - rad * sin(phi) * 255.0;
    00236     Y = L;
    00237
    00238     if(cb < 0)
    00239       cb = 0;
    00240     else if(cb > 255)
    00241       cb = 255;
    00242     if(cr < 0)
    00243       cr = 0;
    00244     else if(cr > 255)
    00245       cr = 255;
    00246     Cb = (unsigned char) cb;
    00247     Cr = (unsigned char) cr;
    00248   }
    00249
    00250   /** Converts a TSL pixel into an YCbCr pixel.
    00251    *  @param T The T channel of the source pixel.
    00252    *  @param S The S channel of the source pixel.
    00253    *  @param L The L channel of the source pixel.
    00254    *  @param Y The Y channel of the target pixel.
    00255    *  @param Cb The Cr channel of the target pixel.
    00256    *  @param Cr The Cr channel of the target pixel.
    00257    */
    00258   static void fromTSLToRGB(unsigned char t,
    00259                            unsigned char s,
    00260                            unsigned char l,
    00261                            unsigned char& r,
    00262                            unsigned char& g,
    00263                            unsigned char& b)
    00264   {
    00265     double y1, u1, v1, r1, g1, b1, rad, phi;
    00266
    00267     /* Convert TSL to YUV */
    00268     rad = (((double) s) * 0.555) / 255.0;
    00269     phi = (((double) t) * 2.0 * 3.14159) / 255.0;
    00270     phi += 0.25 * 3.14159;
    00271     y1 = (double) l;
    00272     u1 =  (rad * cos(phi)) * 255.0;
    00273     v1 = -(rad * sin(phi)) * 255.0;
    00274
    00275     /* Crop UV */
    00276     if (u1 < -128.0)
    00277     {
    00278       u1 = -128.0;
    00279     }
    00280     else if (u1 > 127.0)
    00281     {
    00282       u1 = 127.0;
    00283     }
    00284     if (v1 < -128.0)
    00285     {
    00286       v1 = -128.0;
    00287     }
    00288     else if (v1 > 127.0)
    00289     {
    00290       v1 = 127.0;
    00291     }
    00292
    00293     /* Convert YUV to RGB */
    00294     r1 = y1 + 1.371 * v1;
    00295     g1 = y1 - 0.336 * u1 - 0.698 * v1;
    00296     b1 = y1 + 1.732 * u1;
    00297
    00298     /* Crop RGB */
    00299     if (r1 < 0.0)
    00300     {
    00301       r1 = 0.0;
    00302     }
    00303     else if (r1 > 255.0)
    00304     {
    00305       r1 = 255.0;
    00306     }
    00307     if (g1 < 0.0)
    00308     {
    00309       g1 = 0.0;
    00310     }
    00311     else if (g1 > 255.0)
    00312     {
    00313       g1 = 255.0;
    00314     }
    00315     if (b1 < 0.0)
    00316     {
    00317       b1 = 0.0;
    00318     }
    00319     else if (b1 > 255.0)
    00320     {
    00321       b1 = 255.0;
    00322     }
    00323
    00324     /* Return values */
    00325     r = (unsigned char) r1;
    00326     g = (unsigned char) g1;
    00327     b = (unsigned char) b1;
    00328   }
    00329 };
    00330
    00331 #endif //__ColorModelConversions_h_