ColorOps.H

Go to the documentation of this file.
00001 /*!@file Image/ColorOps.H Color operations on Image
00002  */
00003 
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00006 // University of Southern California (USC) and the iLab at USC.         //
00007 // See http://iLab.usc.edu for information about this project.          //
00008 // //////////////////////////////////////////////////////////////////// //
00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00011 // in Visual Environments, and Applications'' by Christof Koch and      //
00012 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00013 // pending; application number 09/912,225 filed July 23, 2001; see      //
00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00015 // //////////////////////////////////////////////////////////////////// //
00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00017 //                                                                      //
00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00019 // redistribute it and/or modify it under the terms of the GNU General  //
00020 // Public License as published by the Free Software Foundation; either  //
00021 // version 2 of the License, or (at your option) any later version.     //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00026 // PURPOSE.  See the GNU General Public License for more details.       //
00027 //                                                                      //
00028 // You should have received a copy of the GNU General Public License    //
00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00031 // Boston, MA 02111-1307 USA.                                           //
00032 // //////////////////////////////////////////////////////////////////// //
00033 //
00034 // Primary maintainer for this file: Rob Peters <rjpeters@klab.caltech.edu>
00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/ColorOps.H $
00036 // $Id: ColorOps.H 14762 2011-05-03 01:13:16Z siagian $
00037 //
00038 
00039 // The fromXXX() code here is somewhat inspired from the
00040 // grab_gray_image.c example code provided with the libdc1394
00041 // distribution by Gord Peters, and from the Coriander source code.
00042 
00043 #ifndef IMAGE_COLOROPS_H_DEFINED
00044 #define IMAGE_COLOROPS_H_DEFINED
00045 
00046 #include "Image/Image.H"
00047 #include "Util/Assert.H"
00048 #include "Util/Promotions.H"
00049 
00050 class Dims;
00051 template <class T> class Image;
00052 template <class T> class PixRGB;
00053 class ColorMap;
00054 
00055 //! Set the red, green and blue components from 3 monochromatic images
00056 template <class T>
00057 Image<PixRGB<T> > makeRGB(const Image<T>& red,
00058                           const Image<T>& green,
00059                           const Image<T>& blue);
00060 
00061 //! Colorize a greyscale byte image using a colormap
00062 /*! Note that this will throw a fatal error if the colormap does not
00063   have exactly 256 entries. */
00064 Image< PixRGB<byte> > colorize(const Image<byte>& img, const ColorMap& cmap);
00065 
00066 //! Add color speckle noise to array; faster version, draws 'num' dots
00067 void inplaceColorSpeckleNoise(Image< PixRGB<byte> >& dest, const int num);
00068 
00069 //! Get the red, green and blue components as 3 monochromatic images
00070 template <class T>
00071 void getComponents(const Image<PixRGB<T> >& src,
00072                    Image<T>& red, Image<T>& green, Image<T>& blue);
00073 
00074 //! Split out a single pixel component image from a multispectral pixel input image
00075 template <class PixT>
00076 inline Image<typename PixT::ScalarType>
00077 getPixelComponentImage(const Image<PixT>& in, const size_t i)
00078 {
00079   typedef typename PixT::ScalarType T;
00080 
00081   Image<T> result(in.getDims(), NO_INIT);
00082 
00083   typename Image<PixT>::const_iterator sptr = in.begin();
00084   typename Image<T>::iterator dptr = result.beginw();
00085   typename Image<T>::iterator stop = result.endw();
00086 
00087   ASSERT(i < PixT::myDim);
00088 
00089   while (dptr != stop)
00090     {
00091       *dptr = sptr->p[i];
00092       ++dptr; ++sptr;
00093     }
00094 
00095   return result;
00096 }
00097 
00098 /*! This method will normalize an image based upon the maximum value
00099   provided to it. This is either max or the absolute value of min.
00100   It then creates an image where all negative values are assigned a red
00101   pixel value while all postive numbers are assigned a green pixel value
00102   @param max The maximum pixel value
00103   @param min The minimum pixel value
00104   @param image The image of values (positive and negative) to be processed
00105 */
00106 Image<PixRGB<float> > normalizeRGPolar(const Image<float>& src,
00107                                        const float max,
00108                                        const float min);
00109 /*! This method will normalize an image based upon the maximum value
00110   provided to it. This is either max or the absolute value of min.
00111   It then creates an image where all negative values are assigned a red
00112   pixel value while all postive numbers are assigned a green pixel value.
00113   This version will autmatically determine min and max and then normalize
00114   between 0 and 255 for red and green
00115   @param image The image of values (positive and negative) to be processed
00116 */
00117 Image<PixRGB<float> > normalizeRGPolarAuto(const Image<float>& src);
00118 //! Normalize a grey scale image, with some idea for scale
00119 /*! nromalize a grey scale image, but to give an idea of the actual scale,
00120     we leave one channel as the orignal value and set the other the new
00121     value. This way, the intensity is still normalized over once channel
00122     so that you can make out the image features, but the hue change lets
00123     you know that the real intensity was very high.
00124 
00125     Note: the output baseColor and normColor should be 1,2 or 3. They should
00126     also not be equal. These are which channel is set as the base and
00127     normalized channel representations.
00128 
00129     Also Note: The base color will be clamped to between 0 and clamp so
00130     that it can still be displayed
00131 
00132     @param src The orignal grey scale image
00133     @param min The low bound on the normalization, for instance 0
00134     @param max The high bound on the normalization, for instance 255
00135     @param clamp clamp the baseColor to no more than this value
00136     @param baseColor, 1,2,3 ; R,G,B : which channel to not normalize out
00137     @param normColor, 1,2,3 ; R,G,B : which channel to normalize out
00138 */
00139 Image<PixRGB<float> > normalizeWithScale(const Image<float>& src,
00140                                          const float min,
00141                                          const float max,
00142                                          const float clamp,
00143                                          const char baseColor,
00144                                          const char normColor);
00145 
00146 //! Normalize a grey scale image, with some idea for scale
00147 /*! Here we normalize the image using translation between RGB and HSV
00148     what we do is set the intensity as the basic normalized value
00149     of the original gray scale image. However, we use hue as the
00150     absolute scale. Saturation is constant at 100 (full).
00151 */
00152 Image<PixRGB<float> > normalizeScaleRainbow(const Image<float>& src,
00153                                             const float min,
00154                                             const float max);
00155 //! Create a color image by staining a monochrome image.
00156 /*! Each pixel in the result is given by the stain color multiplied by
00157     the corresponding pixel in the monochrome source image. This is
00158     entirely equivalent to, but more efficient than, creating a color
00159     image from the monochrome image, then multiplying the color image
00160     by the stain color.*/
00161 template <class T>
00162 Image<PixRGB<T> > stain(const Image<T>& src, PixRGB<float> color);
00163 
00164 //! Create a color image from src by tinting positive and negative values
00165 /*! For each pixel x in the input image, we compute ratio=x/maxval;
00166     then if the ratio is positive, the output value is ratio*pos_stain
00167     + (1-ratio)*background, and if the ratio is negative, then the
00168     output value is (-ratio)*neg_stain + (1-(-ratio))*background. */
00169 Image<PixRGB<float> > stainPosNeg(const Image<float>& src,
00170                                   const float maxval,
00171                                   const PixRGB<float>& background,
00172                                   const PixRGB<float>& pos_stain,
00173                                   const PixRGB<float>& neg_stain);
00174 
00175 //! Overlay an image over another, however, stain the top image
00176 /*! This method works almost exactly like overlay except that the
00177     bottom image is stained (colored) red green or blue depending on
00178     whether char channel is set to r,g, or b */
00179 Image<PixRGB<float> > overlayStain(const Image<float>& top,
00180                                    const Image<float>& bottom,
00181                                    const float trans, const char channel);
00182 
00183 //! Get min and max of the components
00184 template <class T>
00185 void getMinMaxC(const Image<PixRGB<T> >& src, T& mi, T& ma);
00186 
00187 //! Get the mean RGB of an Image
00188 template <class T>
00189 PixRGB<float> meanRGB(const Image<PixRGB<T> >& src);
00190 
00191 //! Normalize values between nmin and nmax
00192 template <class T, class T2>
00193 inline void normalizeC(Image<PixRGB<T> >& src, const T2 nmin, const T2 nmax)
00194 {
00195   ASSERT(src.initialized());
00196   T mi, ma; getMinMaxC(src, mi, ma);
00197   const float mif = float(mi);
00198   const float maf = float(ma);
00199   const float scale = maf - mif;
00200   if (scale > -1.0e-20 && scale < 1.0e-20) return;  // no need to rescale...
00201   const float nscale = (float(nmax) - float(nmin)) / scale;
00202 
00203   typename Image<PixRGB<T> >::iterator aptr = src.beginw();
00204   typename Image<PixRGB<T> >::iterator stop = src.endw();
00205 
00206   while (aptr != stop)
00207     {
00208       aptr->setRed  (nmin+(T2)(((float(aptr->red()))-mif)*nscale));
00209       aptr->setGreen(nmin+(T2)(((float(aptr->green()))-mif)*nscale));
00210       aptr->setBlue (nmin+(T2)(((float(aptr->blue()))-mif)*nscale));
00211       ++aptr;
00212     }
00213 }
00214 
00215 //! Compute luminance of a color image
00216 template <class T>
00217 Image<T> luminance(const Image<PixRGB<T> >& src);
00218 
00219 //! Compute luminance of a greyscale image (no-op)
00220 /*! This no-op overload is provided so that luminance() can be applied
00221     to template images where it is not known whether the template
00222     argument is scalar or PixRGB. */
00223 template <class T>
00224 Image<T> luminance(const Image<T>& src);
00225 
00226 //! Compute luminance in NTSC coordinates
00227 /*! This version performs the same function as rgb2gray() in matlab */
00228 template <class T>
00229 Image<T> luminanceNTSC(const Image<PixRGB<T> >& src);
00230 
00231 //! Convert grayscale image to RGB
00232 template <class T>
00233 Image< PixRGB<T> > toRGB(const Image<T>& src);
00234 
00235 //! Convert RGB image to RGB (no-op)
00236 /*! This no-op function is provided so that toRGB() can be applied to
00237   template images where it is not known whether the template argument
00238   is scalar or PixRGB. */
00239 template <class T>
00240 Image< PixRGB<T> > toRGB(const Image< PixRGB<T> >& src);
00241 
00242 //! Compute color information measure based in infoFFT
00243 template <class T>
00244 Image<float> infoMeasure(const Image<PixRGB<T> >& src,
00245                          const float eps, const int size);
00246 
00247 //! Get YIQ color components
00248 template <class T>
00249 void getYIQ(const Image<PixRGB<T> >& src,
00250             Image<T>& y, Image<T>& i, Image<T>& q);
00251 
00252 //! Get YUV color components from an RGB image
00253 template <class T>
00254 void getJpegYUV(const Image<PixRGB<T> >& src,
00255                 Image<T>& y, Image<T>& u, Image<T>& v);
00256 
00257 //! Normalize my values by those in the lum image
00258 template <class T>
00259 Image<PixRGB<T> > luminanceNormalize(const Image<PixRGB<T> >& src,
00260                                      const T thresh);
00261 
00262 //! Compute R/G and B/Y channels from a luminanceNormalized color image
00263 /*! This version does automatic promotion on the results, so that
00264     negative values can be represented even if the input is of type
00265     PixRGB<byte> */
00266 template <class T>
00267 void getRGBY(const Image<PixRGB<T> >& src,
00268              Image<typename promote_trait<T, float>::TP>& rg,
00269              Image<typename promote_trait<T, float>::TP>& by,
00270              const typename promote_trait<T, float>::TP thresh);
00271 
00272 //! Compute R/G and B/Y channels in a simpler way
00273 /*! Params are as in getRGBY. The computation for the RG and BY maps
00274     is: RG = (R-G)/max(R,G,B); BY = (B-min(R,G))/max(R,G,B).*/
00275 template <class T>
00276 void getRGBYsimple(const Image<PixRGB<T> >& src,
00277                    Image<typename promote_trait<T, float>::TP>& rg,
00278                    Image<typename promote_trait<T, float>::TP>& by,
00279                    const typename promote_trait<T, float>::TP thresh);
00280 
00281 //! Compute R, G, B, Y channels from a luminanceNormalized color image
00282 /*! This version keeps the four channels separate so that correct
00283     results can be obtained without requiring promotion even if the
00284     input is of type PixRGB<byte> */
00285 template <class T>
00286 void getRGBY(const Image<PixRGB<T> >& src, Image<T>& r, Image<T>& g,
00287              Image<T>& b, Image<T>& y, const T thresh);
00288 
00289 //! Compute R/G and B/Y via computation of H2SV2 color space
00290 /*! In addition to returning R/G and B/Y this basically returns the
00291     full H2SV color space. the original RGB can be obtained later
00292     via conversion of rg,by, sat and val using a PixH2SV2 to RGB
00293 */
00294 template <class T>
00295 void getRGBY(const Image<PixRGB<T> >& src, Image<T>& rg,  Image<T>& by,
00296              Image<T>& sat, Image<T>& val, const ushort H2SVtype = 2);
00297 
00298 //! Compute D, K, L color components from an RGB image
00299 /*! The DKL color space is motivated by the neurobiology of early
00300     vision in primates. D is roughly like luminance (with some neutral
00301     grey (RGB=[161 159 154]) at zero, white around 1.0, and black
00302     around -1.0), K roughly like Red-Green, and L roughly like
00303     Blue-Yellow. The images returned here have signed float values
00304     roughly in [-1,1] (but they sometimes are slightly larger that exactly
00305     that, so be sure to clamp if you ar egoing to convert). */
00306 template <class T>
00307 void getDKL(const Image<PixRGB<T> >& src,
00308             Image<typename promote_trait<T, float>::TP>& dimg,
00309             Image<typename promote_trait<T, float>::TP>& kimg,
00310             Image<typename promote_trait<T, float>::TP>& limg);
00311 
00312 //! Compute L, A, B color components from an RGB image
00313 /*! Derived from By Mark Ruzon from C code by Yossi Rubner, 23 September 1997 
00314  * A Lab color space is a color-opponent space with dimension L for lightness and
00315  * a and b for the color-opponent dimensions, based on nonlinearly compressed CIE
00316  * XYZ color space coordinates. Lab color is designed to approximate human vision.
00317  * It aspires to perceptual uniformity, and its L  component closely matches human
00318  * perception of lightness. It can thus be used to make accurate color balance corrections
00319  * by modifying output curves in the a and b components, or to adjust the lightness
00320  * contrast using the L  component. In RGB or CMYK spaces, which model the output of
00321  * physical devices rather than human visual perception, these transformations can
00322  * only be done with the help of appropriate blend modes in the editing application.
00323  */
00324 template <class T>
00325 void getLAB(const Image<PixRGB<T> >& src,
00326             Image<typename promote_trait<T, float>::TP>& limg,
00327             Image<typename promote_trait<T, float>::TP>& aimg,
00328             Image<typename promote_trait<T, float>::TP>& bimg);
00329 
00330 //! normalize the LAB color space to lie in [0.0, 1.0]
00331 //! this is more complex than just calling inplaceNormalize
00332 //! NOTE: we assume that this is called right getLAB 
00333 //!       separate calls usually are done if user wants both
00334 //!       normalized and unnormalized value of the LAB color space
00335 void normalizeLAB(Image<float>& limg,
00336                   Image<float>& aimg,
00337                   Image<float>& bimg);
00338 
00339 //! just call getLAB and normalizeLAB
00340 template <class T>
00341 void getNormalizedLAB(const Image<PixRGB<T> >& src,
00342                       Image<typename promote_trait<T, float>::TP>& limg,
00343                       Image<typename promote_trait<T, float>::TP>& aimg,
00344                       Image<typename promote_trait<T, float>::TP>& bimg);
00345 
00346 //! contrast-modulate an RGB image with a mask
00347 Image< PixRGB<byte> > contrastModulate(const Image< PixRGB<byte> >& img,
00348                                        const Image<float>& mask,
00349                                        float baseContrast = 0.05,
00350                                        byte baseBright = 255);
00351 
00352 //! Compute peak signal-to-noise ratio between two color images
00353 /*! For color images, pSNR computed from the average
00354     mean-squared-error from the red, green and blue channels */
00355 template <class T>
00356 double pSNRcolor(const Image< PixRGB<T> >& img1,
00357                  const Image< PixRGB<T> >& img2);
00358 
00359 //! Compute weighted peak signal-to-noise ratio between two color images
00360 /*! This is like the other pSNRcolor() except that it uses the
00361     weighted version of distance() internally */
00362 template <class T>
00363 double pSNRcolor(const Image< PixRGB<T> >& img1,
00364                  const Image< PixRGB<T> >& img2,
00365                  const Image<float>& weight);
00366 
00367 //! Normalize each component of the RGB image separately
00368 /*! Normalize the red component with min.red() and max.red() etc.*/
00369 template <class T>
00370 Image< PixRGB<T> > normalizeRGB(const Image< PixRGB<T> >& img,
00371                                 PixRGB<T> min,
00372                                 PixRGB<T> max);
00373 
00374 //! Return the pixel-wise maximum of the r, g and b component
00375 template <class T>
00376 Image<T> maxRGB(const Image< PixRGB<T> >& img);
00377 
00378 //! Stain a black and white image with a color
00379 /*! @param src the black and white image to be stained
00380     @param min This value will be converted to 0 (black)
00381     @param max This value will be converted to color
00382     @param color The color used for staining */
00383 template <class T>
00384 Image< PixRGB<T> > colorStain (const Image<T>& src,
00385                                const T& min, const T& max,
00386                                const PixRGB<T>& color);
00387 
00388 //! convert RGB color values into C.I.E. coordinates
00389 /*! @param rgbColor the color to convert from
00390     @param cr returns the R/I value
00391     @param cg returns the G/I value
00392     @param intens returns the intensity */
00393 void RGBtoCIE(const PixRGB<byte>& rgbColor,
00394               float& cr, float& cg, float& intens);
00395 
00396 //! distance between hue of image pixels and a given hue
00397 /*! @param img The color image to compare
00398     @param muR the R/I coordinate of the target hue in the C.I.E. color space
00399     @param muG the G/I coordinate in C.I.E.
00400     @param sigR the standard deviation of a 2D Gaussian in R/I direction
00401     @param sigG the standard deviation of a 2D Gaussian in G/I direction
00402     @param rho the correlation between the R/I and G/I directions
00403     @return a float image coding for how close the hue in img is
00404     to the target hue - 1 for right on the mark, 0 for very different */
00405 Image<float> hueDistance(const Image< PixRGB<byte> >& img,
00406                          float muR, float muG,
00407                          float sigR, float sigG, float rho);
00408 
00409 
00410 // ######################################################################
00411 /* So things look consistent in everyone's emacs... */
00412 /* Local Variables: */
00413 /* indent-tabs-mode: nil */
00414 /* End: */
00415 
00416 #endif // !IMAGE_COLOROPS_H_DEFINED
Generated on Sun May 8 08:40:49 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3