PixelsCommonDef.H

Go to the documentation of this file.
00001 /*!@file Image/PixelsCommonDef.H Basic pixel types version 2.0 */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: T. Nathan Mundhenk <mundhenk@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/PixelsCommonDef.H $
00035 // $Id: PixelsCommonDef.H 12962 2010-03-06 02:13:53Z irock $
00036 //
00037 
00038 #ifndef PIXELSCOMMONDEF_H_DEFINED
00039 #define PIXELSCOMMONDEF_H_DEFINED
00040 
00041 #include "Image/PixelsBase.H"
00042 
00043 // ######################################################################
00044 // ######################################################################
00045 // Commonly used conversion template defs
00046 //
00047 // Use this file to place pixels type conversions IFF you use them more
00048 // than once. For instance HSV and RGB conversions are used in several
00049 // places. So to reduce redundancy, they are placed here
00050 //
00051 // ######################################################################
00052 // ######################################################################
00053 
00054 // ######################################################################
00055 /*! RGB to HSV
00056 
00057    RGB is converted from HSV in a simple way
00058 
00059    I. Get some easy work done:
00060      (1) If Value V = 0, then we are done, color is black set R,G,B to 0
00061      (2) If Saturation S = 0, no color is dominant, set to some gray color
00062 
00063    II. Hue is valued from 0 to 360, we chunk the space into 60 degree
00064        increments. At each 60 degrees we use a slightly different formula.
00065        In general we will assign and set R,G and B exclusively as:
00066 
00067        (1) We set the most dominant color:
00068 
00069           (a) If H is 300 -> 60 , set R = V
00070           (b) If H is 60  -> 180, set G = V
00071           (c) If H is 180 -> 300, set B = V
00072 
00073        (2) The least dominant color is set as:
00074 
00075           pv = Value * ( 1 - Saturation )
00076 
00077        (3) The last remaining color is set as:
00078 
00079           Either:
00080 
00081           (a) qv = Value * ( 1 - Saturation * (Hue/60) - floor(Hue/60))
00082           (b) tv = Value * ( 1 - Saturation * ( 1 - ((Hue/60) - floor(Hue/60))))
00083 
00084   III. Clean up, here we allow for i to be -1 or 6 just in case we have a
00085        very small floating point error otherwise, we have an undefined input.
00086 
00087   IV. Normalize R,G and B from 0 to 255.
00088 
00089   Note: S and V should be normalized between 0 and 1 prior to using this
00090         template. H should be its normal 0 to 360. You can do this using
00091         the built in limit definitions:
00092 
00093         const double new_v = v / HSV_V_UPPER;  // Normalize from 0 to 1
00094         const double new_s = s / HSV_S_UPPER;  // Normalize from 0 to 1
00095 */
00096 // ######################################################################
00097 #define PIX_HSV_TO_RGB_COMMON(H,S,V,R,G,B)                          \
00098 if( V == 0 )                                                        \
00099 { R = 0; G = 0; B = 0; }                                            \
00100 else if( S == 0 )                                                   \
00101 {                                                                   \
00102   R = clamped_convert<T>(V);                                        \
00103   G = clamped_convert<T>(V);                                        \
00104   B = clamped_convert<T>(V);                                        \
00105 }                                                                   \
00106 else                                                                \
00107 {                                                                   \
00108   const double hf = H / 60.0;                                       \
00109   const int    i  = (int) floor( hf );                              \
00110   const double f  = hf - i;                                         \
00111   const double pv  = V * ( 1 - S );                                 \
00112   const double qv  = V * ( 1 - S * f );                             \
00113   const double tv  = V * ( 1 - S * ( 1 - f ) );                     \
00114   switch( i )                                                       \
00115     {                                                               \
00116     case 0:                                                         \
00117       R = clamped_convert<T>(V);                                    \
00118       G = clamped_convert<T>(tv);                                   \
00119       B = clamped_convert<T>(pv);                                   \
00120       break;                                                        \
00121     case 1:                                                         \
00122       R = clamped_convert<T>(qv);                                   \
00123       G = clamped_convert<T>(V);                                    \
00124       B = clamped_convert<T>(pv);                                   \
00125       break;                                                        \
00126     case 2:                                                         \
00127       R = clamped_convert<T>(pv);                                   \
00128       G = clamped_convert<T>(V);                                    \
00129       B = clamped_convert<T>(tv);                                   \
00130       break;                                                        \
00131     case 3:                                                         \
00132       R = clamped_convert<T>(pv);                                   \
00133       G = clamped_convert<T>(qv);                                   \
00134       B = clamped_convert<T>(V);                                    \
00135       break;                                                        \
00136     case 4:                                                         \
00137       R = clamped_convert<T>(tv);                                   \
00138       G = clamped_convert<T>(pv);                                   \
00139       B = clamped_convert<T>(V);                                    \
00140       break;                                                        \
00141     case 5:                                                         \
00142       R = clamped_convert<T>(V);                                    \
00143       G = clamped_convert<T>(pv);                                   \
00144       B = clamped_convert<T>(qv);                                   \
00145       break;                                                        \
00146     case 6:                                                         \
00147       R = clamped_convert<T>(V);                                    \
00148       G = clamped_convert<T>(tv);                                   \
00149       B = clamped_convert<T>(pv);                                   \
00150       break;                                                        \
00151     case -1:                                                        \
00152       R = clamped_convert<T>(V);                                    \
00153       G = clamped_convert<T>(pv);                                   \
00154       B = clamped_convert<T>(qv);                                   \
00155       break;                                                        \
00156     default:                                                        \
00157       LFATAL("i Value error in Pixel conversion, Value is %d",i);   \
00158       break;                                                        \
00159     }                                                               \
00160 }                                                                   \
00161 R *= RGB_R_UPPER;                                                   \
00162 G *= RGB_G_UPPER;                                                   \
00163 B *= RGB_B_UPPER;
00164 
00165 // ######################################################################
00166 /*! HSV to RGB
00167 
00168    HSV is converted from RGB in a simple way
00169 
00170    I. First compute the base H,S and V
00171 
00172      (1) H - Hue if Color1 is Max then H = ( Color2 - Color3 ) / ( Max - Min )
00173      (2) S - Saturation is S = Max - Min / Max;
00174      (3) V - Value is V = max of either R,G or B
00175 
00176    II. Normalize the values
00177 
00178      General H,S,V has ranges:
00179      0 < Hue < 360
00180      0 < Sat < 100
00181      0 < Val < 255
00182 
00183      (1) H - Hue:
00184              if Red           H *= 60
00185              if Green H += 2; H *= 60
00186              if Blue  H += 4; H *= 60
00187          In essence this forces the recognizable 0-360 value seen in hue
00188      (2) S - May be S *= 100 , I like in some cases to keep it from 0 to 1
00189      (3) V - is V *= 255
00190 
00191    there are some other bells and whistles to take care of divide by zero
00192    conditions and other such singularities. For instance if Max = Min then
00193    we need to fudge hue
00194 
00195    Note: Set NORM to true for normal HSV conversions. This will make the
00196          values use normal HSV range. Setting NORM to false forces H,S and V
00197          to range between 0 and 1. This is useful if next you will convert
00198          to H2SV color space.
00199 
00200          R, G and B are assumed to be between 0 and 255.
00201 */
00202 // ######################################################################
00203 #define PIX_RGB_TO_HSV_COMMON(R,G,B,H,S,V,NORM)                        \
00204 if((B > G) && (B > R))                                                 \
00205 {                                                                      \
00206   V = clamped_convert<T>(B);                                           \
00207   if(V != 0)                                                           \
00208   {                                                                    \
00209     double min;                                                        \
00210     if(R > G) min = G;                                                 \
00211     else      min = R;                                                 \
00212     const double delta = V - min;                                      \
00213     if(delta != 0)                                                     \
00214       { S = clamped_convert<T>(delta/V); H = 4 + (R - G) / delta; }    \
00215     else                                                               \
00216       { S = clamped_convert<T>(0.0);     H = 4 + (R - G); }            \
00217     H *=   60; if(H < 0) H += 360;                                     \
00218     if(!NORM) V = clamped_convert<T>(V/255);                           \
00219     else      S *= clamped_convert<T>(100);                            \
00220   }                                                                    \
00221   else                                                                 \
00222     { S = 0; H = 0;}                                                   \
00223 }                                                                      \
00224 else if(G > R)                                                         \
00225 {                                                                      \
00226   V = clamped_convert<T>(G);                                           \
00227   if(V != 0)                                                           \
00228   {                                                                    \
00229     double min;                                                        \
00230     if(R > B) min = B;                                                 \
00231     else      min = R;                                                 \
00232     const double delta = V - min;                                      \
00233     if(delta != 0)                                                     \
00234       { S = clamped_convert<T>(delta/V); H = 2 + (B - R) / delta; }    \
00235     else                                                               \
00236       { S = clamped_convert<T>(0.0);     H = 2 + (B - R); }            \
00237     H *=   60; if(H < 0) H += 360;                                     \
00238     if(!NORM) V = clamped_convert<T>(V/255);                           \
00239     else      S *= clamped_convert<T>(100);                            \
00240   }                                                                    \
00241   else                                                                 \
00242     { S = 0; H = 0;}                                                   \
00243 }                                                                      \
00244 else                                                                   \
00245 {                                                                      \
00246   V = clamped_convert<T>(R);                                           \
00247   if(V != 0)                                                           \
00248   {                                                                    \
00249     double min;                                                        \
00250     if(G > B) min = B;                                                 \
00251     else      min = G;                                                 \
00252     const double delta = V - min;                                      \
00253     if(delta != 0)                                                     \
00254       { S = clamped_convert<T>(delta/V); H = (G - B) / delta; }        \
00255     else                                                               \
00256       { S = clamped_convert<T>(0.0);     H = (G - B); }                \
00257     H *=   60; if(H < 0) H += 360;                                     \
00258     if(!NORM) V = clamped_convert<T>(V/255);                           \
00259     else      S *= clamped_convert<T>(100);                            \
00260   }                                                                    \
00261   else                                                                 \
00262     { S = 0; H = 0;}                                                   \
00263 }
00264 
00265 // ######################################################################
00266 /*! HSV to H2SV1
00267   We convert HSV to H2SV1 (or H2SV2 etc) by converting hue which is
00268   in radial coordinates 0 - 360 and converting it to cartesian coordinates
00269 
00270   The precise coordinate transform is flexable, so long as it is invertable
00271   here, we treat r (hue) as falling along a straight line. We could also in
00272   another method treat it as if it is on a circle.
00273 
00274   --> All final values normalize from 0 to 1
00275 */
00276 // ######################################################################
00277 #define PIX_HSV_TO_H2SV1_COMMON(H,S,H1,H2)                     \
00278 if(S == 0)                                                     \
00279 {                                                              \
00280   H1 = clamped_convert<T>(0.5);                                \
00281   H2 = clamped_convert<T>(0.5);                                \
00282 }                                                              \
00283 else                                                           \
00284 {                                                              \
00285   if(H > 180)                                                  \
00286   {                                                            \
00287     H2 = clamped_convert<T>((H - 180)/180);                    \
00288     if(H > 270) H1 = clamped_convert<T>((H - 270)/180);        \
00289     else        H1 = clamped_convert<T>(1 - (H - 90)/180);     \
00290   }                                                            \
00291   else                                                         \
00292   {                                                            \
00293     H2 = clamped_convert<T>(1 - H/180);                        \
00294     if(H > 90) H1 = clamped_convert<T>(1 - (H - 90)/180);      \
00295     else       H1 = clamped_convert<T>(0.5 + H/180);           \
00296   }                                                            \
00297 }
00298 
00299 // ######################################################################
00300 /*! HSV to H2SV2
00301   We convert HSV to H2SV1 (or H2SV2 etc) by converting hue which is
00302   in radial coordinates 0 - 360 and converting it to cartesian coordinates
00303 
00304   The precise coordinate transform is flexable, so long as it is invertable
00305   here, we treat r (hue) as falling along a straight line. We could also in
00306   another method treat it as if it is on a circle.
00307 
00308   This variant is designed to make H1 and H2 mimmic R/G B/Y opponencies
00309   Thus:
00310 
00311      (1) H1 is 0 at Blue and 1 at Yellow
00312      (2) H2 is 0 at Green and 1 at Red
00313 
00314   --> All final values normalize from 0 to 1
00315 
00316   Note: We can also use these templates on HSL color space since
00317         HSV and HSL have the exact same basis for hue.
00318 
00319 */
00320 // ######################################################################
00321 #define PIX_HSV_TO_H2SV2_COMMON(H,S,H1,H2)                                \
00322 if(S == 0)                                                                \
00323 {                                                                        \
00324   H1 = clamped_convert<T>(0.5);                                                                \
00325   H2 = clamped_convert<T>(0.5);                                                                \
00326 }                                                                        \
00327 else                                                                        \
00328 {                                                                        \
00329   if(H > 120)                                                                \
00330   {                                                                        \
00331     H2 = clamped_convert<T>((H - 120)/240);                                \
00332     if(H > 240) H1 = clamped_convert<T>((H - 240)/180);                        \
00333     else        H1 = clamped_convert<T>(1 - (H - 60)/180);                \
00334   }                                                                        \
00335   else                                                                        \
00336   {                                                                        \
00337     H2 = clamped_convert<T>(1 - H/120);                                        \
00338     if(H > 60) H1 = clamped_convert<T>(1 - (H - 60)/180);                \
00339     else       H1 = clamped_convert<T>((2.0/3.0) + H/180);                \
00340   }                                                                        \
00341 }
00342 
00343 // ######################################################################
00344 /*! H2SV1 to HSV NORMAL
00345     Convert H2SV1 to HSV using a simple quick method.
00346 */
00347 #define PIX_H2SV1_TO_HSV_SIMPLE_COMMON(H1,H2,H)           \
00348 if(H1 > 0.5)                                              \
00349   if(H2 > 0.5)  H = 180 * H1 - 90;                        \
00350   else          H = 90 + 180 * (1 - H1);                  \
00351 else                                                      \
00352   if(H2 <= 0.5) H = 90 + 180 * (1 - H1);                  \
00353   else          H = 270 + 180 * H1;
00354 
00355 
00356 // ######################################################################
00357 /*! H2SV2 to HSV NORMAL
00358     Convert H2SV2 to HSV using a simple quick method.
00359 */
00360 #define PIX_H2SV2_TO_HSV_SIMPLE_COMMON(H1,H2,H)           \
00361 if(H1 > 2.0/3.0)                                          \
00362   if(H2 > 0.5)  H = 180 * H1 - 120;                       \
00363   else          H = 60 + 180 * (1 - H1);                  \
00364 else                                                      \
00365   if(H2 <= 0.5) H = 60 + 180 * (1 - H1);                  \
00366   else          H = 240 + 180 * H1;
00367 
00368 
00369 // ######################################################################
00370 /*! H2SV2 to HSV ROBUST
00371     Convert H2SV2 to HSV using a robust method that allows us to deal with
00372     H1 and H2 being adjusted independantly. If they are never adjusted
00373     independantly, then use the simple version
00374 
00375     The main difference here from simple is that:
00376     (1) We compute xp and replace H1 with it
00377     (2) We compute a new saturation term S_NEW
00378 
00379     What makes this robust is that the H1 and H2 coordinates do not have to
00380     match up with the orignal unit coordinates. Instead we compute a slope
00381     term and figure out where it should intersect the original unit coordinates
00382 
00383     Saturation may be reduced if we are too far from a viable color coordinate
00384     and have to transform to much.
00385 
00386 
00387     General Computations:
00388     m:    The slope of the H1/H2 lines
00389     xp:   The Adjusted H1 (x value)
00390           - Useful if H1 was adjusted indepentant of H2
00391     yp:   The Adjusted H2 (y value)
00392     d:    The difference between the ideal (xp,yp) value and the real (H1,H2)
00393     ad:   The legth of (xp,yp) from the origen
00394     sfac: Adjustment to be applied to saturation if d is large
00395            - Useful if H1 and H2 are close to the origen, thus
00396              saturation should be reduced.
00397 */
00398 // ######################################################################
00399 
00400 #define PIX_H2SV2_TO_HSV_ROBUST_COMMON(H1,H2,S,H,S_NEW)         \
00401 double sfac    = 1;                                             \
00402 const double x = H1 - 2.0/3.0;                                  \
00403 if(x > 0)                                                       \
00404 {                                                               \
00405   const double y = H2 - 0.5;                                    \
00406   const double m = y/x;                                         \
00407   if(y > 0)                                                     \
00408   {                                                             \
00409     const double xp = 0.5/(m + 3.0/2.0);                        \
00410     if(xp > x)                                                  \
00411     {                                                           \
00412       const double yp = 0.5 - 0.5*xp/(1.0/3.0);                 \
00413       const double d  = sqrt(pow(xp - x,2) + pow(yp - y,2));    \
00414       const double ad = sqrt(pow(xp,2)     + pow(yp,2));        \
00415       sfac            = (ad - d)/ad;                            \
00416     }                                                           \
00417     H = 180 * (xp + 2.0/3.0) - 120;                             \
00418   }                                                             \
00419   else                                                          \
00420   {                                                             \
00421     const double xp = -0.5/(m - 3.0/2.0);                       \
00422     if(xp > x)                                                  \
00423     {                                                           \
00424       const double yp = -1.0 * (0.5 - 0.5*xp/(1.0/3.0));        \
00425       const double d  = sqrt(pow(xp - x,2) + pow(yp - y,2));    \
00426       const double ad = sqrt(pow(xp,2)     + pow(yp,2));        \
00427       sfac            = (ad - d)/ad;                            \
00428     }                                                           \
00429     H = 60 + 180 * (1 - (xp + 2.0/3.0));                        \
00430   }                                                             \
00431 }                                                               \
00432 else                                                            \
00433 {                                                               \
00434   if(x != 0)                                                    \
00435   {                                                             \
00436     const double y = H2 - 0.5;                                  \
00437     const double m = y/x;                                       \
00438     if(y <= 0)                                                  \
00439     {                                                           \
00440       const double xp = -0.5/(m + 0.5/(2.0/3.0));               \
00441       if(xp < x)                                                \
00442       {                                                         \
00443         const double yp = -1.0 * (0.5 + 0.5*xp/(2.0/3.0));      \
00444         const double d  = sqrt(pow(xp - x,2) + pow(yp - y,2));  \
00445         const double ad = sqrt(pow(xp,2)     + pow(yp,2));      \
00446         sfac            = (ad - d)/ad;                          \
00447       }                                                         \
00448       H = 60 + 180 * (1 - (xp + 2.0/3.0));                      \
00449     }                                                           \
00450     else                                                        \
00451     {                                                           \
00452       const double xp = 0.5/(m - 0.5/(2.0/3.0));                \
00453       if(xp < x)                                                \
00454       {                                                         \
00455         const double yp = 0.5 + 0.5*xp/(2.0/3.0);               \
00456         const double d  = sqrt(pow(xp - x,2) + pow(yp - y,2));  \
00457         const double ad = sqrt(pow(xp,2)     + pow(yp,2));      \
00458         sfac            = (ad - d)/ad;                          \
00459       }                                                         \
00460       H = 240 + 180 * (xp + 2.0/3.0);                           \
00461     }                                                           \
00462   }                                                             \
00463   else                                                          \
00464     H = 240;                                                    \
00465 }                                                               \
00466 S_NEW = S * sfac;
00467 
00468 
00469 
00470 // ######################################################################
00471 /*! RGB to OpenCV XYZ
00472 
00473   This is the XYZ Color space from CIE with the matrix used by OpenCV.
00474   It is very similar to the original one developed by CIE in 1931.
00475 
00476 */
00477 // ######################################################################
00478 #define PIX_RGB_TO_XYZ_OPENCV_COMMON(R,G,B,X,Y,Z)                 \
00479 X = R*0.412453F + G*0.357580F + B*0.180423F;                      \
00480 Y = R*0.212671F + G*0.715160F + B*0.072169F;                      \
00481 Z = R*0.019334F + G*0.119193F + B*0.950227F;
00482 
00483 // ######################################################################
00484 /*! RGB to CIE 1931 XYZ
00485 
00486   This is the original CIE XYZ colorspace developed in 1931.
00487 */
00488 // ######################################################################
00489 #define PIX_RGB_TO_XYZ_CIE1931_COMMON(R,G,B,X,Y,Z)                \
00490 X = R*0.49F   + G*0.31F   + B*0.2F;                               \
00491 Y = R*0.1769F + G*0.8124F + B*0.0107F;                            \
00492 Z = R*0.0F    + G*0.0099F + B*0.9901F;
00493 
00494 // ######################################################################
00495 /*! OpenCV XYZ to RGB
00496 
00497   This is the XYZ Color space from CIE with the matrix used by OpenCV.
00498   It is very similar to the original one developed by CIE in 1931.
00499 
00500 */
00501 // ######################################################################
00502 #define PIX_XYZ_TO_RGB_OPENCV_COMMON(X,Y,Z,R,G,B)                 \
00503 R =       X*3.240479F - Y*1.53715F  - Z*0.498535F;                \
00504 G = -1.0F*X*0.969256F + Y*1.875991F + Z*0.041556F;                \
00505 B =       X*0.055648F - Y*0.204043F + Z*1.057311F;
00506 
00507 // ######################################################################
00508 /*! XYZ to CIE Lab - OpenCV XYZ
00509 
00510   This is the Lab conversion using OpenCV XYZ color space as a basis.
00511   Use the OpenCV XYZ and Lab in conjunction to create the OpenCV version
00512   of Lab Color space.
00513 
00514   L - Is a chroma measure that encapsulates saturation and intensity.
00515   a - Is basically a Red/Green color opponent.
00516   b - Is basically a Blue/Yellow color opponent
00517 
00518 */
00519 #define A_GAMUT_RANGE  186.0F
00520 #define A_GAMUT_MIN   -87.0F
00521 #define B_GAMUT_RANGE  203.0F
00522 #define B_GAMUT_MIN   -108.0F
00523 
00524 // ######################################################################
00525 #define PIX_XYZ_TO_LAB_OPENCV_COMMON(X,Y,Z,L,A,B)                        \
00526 const double i  = 1.0F /3.0F;                                            \
00527 const double n  = 16.0F/116.0F;                                          \
00528 const double t  = 0.00885645F;                                           \
00529 const double s  = 7.78704F;                                              \
00530 const double Xn = 255.0F*0.412453F + 255.0F*0.357580F + 255.0F*0.180423F;\
00531 const double Yn = 255.0F*0.212671F + 255.0F*0.715160F + 255.0F*0.072169F;\
00532 const double Zn = 255.0F*0.019334F + 255.0F*0.119193F + 255.0F*0.950227F;\
00533 const double X1 = X/Xn;                                                  \
00534 const double Y1 = Y/Yn;                                                  \
00535 const double Z1 = Z/Zn;                                                  \
00536 double X2,Y2,Z2;                                                         \
00537 if(X1 > t) X2 = pow(X1,i);                                               \
00538 else       X2 = s*X1 + n;                                                \
00539 if(Y1 > t) Y2 = pow(Y1,i);                                               \
00540 else       Y2 = s*Y1 + n;                                                \
00541 if(Z1 > t) Z2 = pow(Z1,i);                                               \
00542 else       Z2 = s*Z1 + n;                                                \
00543 L = (116.0F * Y2 - 16.0F) * 255.0F/100.0F;                                 \
00544 A = ((500.0F * (X2 - Y2) - A_GAMUT_MIN)/A_GAMUT_RANGE)*255.0F;                 \
00545 B = ((200.0F * (Y2 - Z2) - B_GAMUT_MIN)/B_GAMUT_RANGE)*255.0F;
00546 
00547 // ######################################################################
00548 /*! XYZ to CIE Lab - CIE 1931
00549 
00550   This is the Lab conversion using CIE 1931 XYZ color space as a basis.
00551   Use the CIE 1931 XYZ and Lab in conjunction to create the basic CIE version
00552   of Lab Color space.
00553 
00554   L - Is intensity.
00555   a - Is basically a Red/Green color opponent.
00556   b - Is basically a Blue/Yellow color opponent
00557 */
00558 // ######################################################################
00559 #define PIX_XYZ_TO_LAB_CIE1931_COMMON(X,Y,Z,L,A,B)                         \
00560 const double i  = 1.0F /3.0F;                                            \
00561 const double n  = 16.0F/116.0F;                                          \
00562 const double t  = 0.00885645F;                                           \
00563 const double s  = 7.78704F;                                              \
00564 const double Xn = 255.0F*0.49F   + 255.0F*0.31F   + 255.0F*0.2F;         \
00565 const double Yn = 255.0F*0.1769F + 255.0F*0.8124F + 255.0F*0.0107F;      \
00566 const double Zn = 255.0F*0.0F    + 255.0F*0.0099F + 255.0F*0.9901F;      \
00567 const double X1 = X/Xn;                                                  \
00568 const double Y1 = Y/Yn;                                                  \
00569 const double Z1 = Z/Zn;                                                  \
00570 double X2,Y2,Z2;                                                         \
00571 if(X1 > t) X2 = pow(X1,i);                                               \
00572 else       X2 = s*X1 + n;                                                \
00573 if(Y1 > t) Y2 = pow(Y1,i);                                               \
00574 else       Y2 = s*Y1 + n;                                                \
00575 if(Z1 > t) Z2 = pow(Z1,i);                                               \
00576 else       Z2 = s*Z1 + n;                                                \
00577 L = (116.0F * Y2 - 16.0F) * 255.0F/100.0F;                                 \
00578 A = (500.0F * (X2 - Y2)) + 128.0F;                                         \
00579 B = (200.0F * (Y2 - Z2)) + 128.0F;
00580 // ######################################################################
00581 /*! XYZ to CIE Lab - Augmented to Favor Red (Experimental)
00582 
00583   This is the Lab conversion using OpenCV XYZ color space as a basis.
00584   Use the OpenCV XYZ and Lab in conjunction to create the OpenCV version
00585   of Lab Color space.
00586 
00587   L - Is a chroma measure that encapsulates saturation and intensity.
00588   a - Is basically a Red/Green color opponent.
00589   b - Is basically a Blue/Yellow color opponent
00590 
00591 */
00592 // ######################################################################
00593 #define PIX_XYZ_TO_LAB_AUGMENT_COMMON(X,Y,Z,L,A,B)                         \
00594 const double i  = 1.0F /3.0F;                                            \
00595 const double n  = 16.0F/116.0F;                                          \
00596 const double t  = 0.00885645F;                                           \
00597 const double s  = 7.78704F;                                              \
00598 const double Xn = 255.0F*0.412453F + 255.0F*0.357580F + 255.0F*0.180423F;\
00599 const double Yn = 255.0F*0.212671F + 255.0F*0.715160F + 255.0F*0.072169F;\
00600 const double Zn = 255.0F*0.019334F + 255.0F*0.119193F + 255.0F*0.950227F;\
00601 const double X1 = X/Xn;                                                  \
00602 const double Y1 = Y/Yn;                                                  \
00603 const double Z1 = Z/Zn;                                                  \
00604 double X2,Y2,Z2;                                                         \
00605 if(X1 > t) X2 = pow(X1,i);                                               \
00606 else       X2 = s*X1 + n;                                                \
00607 if(Y1 > t) Y2 = pow(Y1,i);                                               \
00608 else       Y2 = s*Y1 + n;                                                \
00609 if(Z1 > t) Z2 = pow(Z1,i);                                               \
00610 else       Z2 = s*Z1 + n;                                                \
00611 L = (116.0F * Y2 - 16.0F) * 255.0F/100.0F;                                 \
00612 if(Y2 > X2) A = (500.0F * (X2 - Y2)) + 128.0F;                                 \
00613 else        A = (500.0F * (X2 - Y2)) + 128.0F;                                 \
00614 B = (200.0F * (Y2 - Z2)) + 128.0F;
00615 
00616 // ######################################################################
00617 /*! Lab to CIE XYZ - OpenCV XYZ
00618 
00619   This is the Lab conversion using OpenCV XYZ color space as a basis.
00620   Use the OpenCV XYZ and Lab in conjunction to create the OpenCV version
00621   of Lab Color space.
00622 
00623   L - Is intensity.
00624   a - Is basically a Red/Green color opponent.
00625   b - Is basically a Blue/Yellow color opponent
00626 
00627 */
00628 // ######################################################################
00629 
00630 #define PIX_LAB_TO_XYZ_OPENCV_COMMON(L,A,B,X,Y,Z)                         \
00631 const double LL = L * 100.0F/255.0F;                                         \
00632 const double AA = ((A/255.0F) * A_GAMUT_RANGE + A_GAMUT_MIN);                 \
00633 const double BB = ((B/255.0F) * B_GAMUT_RANGE + B_GAMUT_MIN);                 \
00634 const double d  = 6.0F/29.0F;                                                 \
00635 const double ds = d*d;                                                         \
00636 const double n  = 16.0F/116.0F;                                          \
00637 const double Xn = 255.0F*0.412453F + 255.0F*0.357580F + 255.0F*0.180423F;\
00638 const double Yn = 255.0F*0.212671F + 255.0F*0.715160F + 255.0F*0.072169F;\
00639 const double Zn = 255.0F*0.019334F + 255.0F*0.119193F + 255.0F*0.950227F;\
00640 const double Fy = (LL + 16)/116;                                         \
00641 const double Fx = Fy + AA/500.0F;                                        \
00642 const double Fz = Fy - BB/200.0F;                                        \
00643 if(Fy > d) Y = Yn*pow(Fy,3);                                             \
00644 else       Y = (Fy - n)*3*ds*Yn;                                         \
00645 if(Fx > d) X = Xn*pow(Fx,3);                                             \
00646 else       X = (Fx - n)*3*ds*Xn;                                         \
00647 if(Fz > d) Z = Zn*pow(Fz,3);                                             \
00648 else       Z = (Fz - n)*3*ds*Zn;                                         \
00649 
00650 // ######################################################################
00651 /*! Lab to CIE XYZ - CIE XYZ
00652 
00653   This is the Lab conversion using OpenCV XYZ color space as a basis.
00654   Use the OpenCV XYZ and Lab in conjunction to create the OpenCV version
00655   of Lab Color space.
00656 
00657   L - Is intensity.
00658   a - Is basically a Red/Green color opponent.
00659   b - Is basically a Blue/Yellow color opponent
00660 
00661 */
00662 // ######################################################################
00663 #define PIX_LAB_TO_XYZ_CIE1931_COMMON(L,A,B,X,Y,Z)                       \
00664 const double LL  = L * 100.0F/255.0F;                                    \
00665 const double AA  = A - 128.0F;                                           \
00666 const double BB  = B - 128.0F;                                           \
00667 const double d  = 6.0F/29.0F;                                            \
00668 const double ds = d*d;                                                   \
00669 const double n  = 16.0F/116.0F;                                          \
00670 const double Xn = 255.0F*0.49F   + 255.0F*0.31F   + 255.0F*0.2F;         \
00671 const double Yn = 255.0F*0.1769F + 255.0F*0.8124F + 255.0F*0.0107F;      \
00672 const double Zn = 255.0F*0.0F    + 255.0F*0.0099F + 255.0F*0.9901F;      \
00673 const double Fy = (LL + 16)/116;                                         \
00674 const double Fx = Fy + AA/500.0F;                                        \
00675 const double Fz = Fy - BB/200.0F;                                        \
00676 if(Fy > d) Y = Yn*pow(Fy,3);                                             \
00677 else       Y = (Fy - n)*3*ds*Yn;                                         \
00678 if(Fx > d) X = Xn*pow(Fx,3);                                             \
00679 else       X = (Fx - n)*3*ds*Xn;                                         \
00680 if(Fz > d) Z = Zn*pow(Fz,3);                                             \
00681 else       Z = (Fz - n)*3*ds*Zn;                                         \
00682 
00683 #endif
Generated on Sun May 8 08:05:15 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3