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_

Generated on Mon Mar 20 21:59:49 2006 for GT2005 by doxygen 1.3.6