CVR-Lib last update 20 Sep 2009

cvrHistogramEqualization.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998-2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  *
00006  * This file is part of the Computer Vision and Robotics Library (CVR-Lib)
00007  *
00008  * The CVR-Lib is free software; you can redistribute it and/or
00009  * modify it under the terms of the BSD License.
00010  *
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. Neither the name of the authors nor the names of its contributors may be
00024  *    used to endorse or promote products derived from this software without
00025  *    specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 
00041 /**
00042  * \file   cvrHistogramEqualization.h
00043  *         Contains a class for histogram equalization of different types of
00044  *         matrices
00045  * \author Thomas Erger
00046  * \author Pablo Alvarado
00047  * \date   14.04.1999 (CVR-Lib 1)
00048  * \date   06.01.2006 (CVR-Lib )
00049  *
00050  * $Id: cvrHistogramEqualization.h,v 1.6 2007/10/18 18:57:26 alvarado Exp $
00051  */
00052 
00053 #ifndef _CVR_HISTOGRAM_EQUALIZATION_H_
00054 #define _CVR_HISTOGRAM_EQUALIZATION_H_
00055 
00056 #include "cvrFunctor.h"
00057 #include "cvrGenericMatrix.h"
00058 #include "cvrMatrixProcessingInterface.h"
00059 #include "cvrContrastEnhancement.h"
00060 
00061 namespace cvr {
00062   /**
00063    * Histogram equalization.
00064    *
00065    * cvr::histogramEqualization equalizes the values of the given matrices or
00066    * vector within a specific input range, which at the same time is mapped to
00067    * a given output range.
00068    *
00069    * The number of "bins" or "cells" in the histogram can be defined by the
00070    * user.
00071    *
00072    * The algorithm used can be found in Sonka et. al "Image Processing,
00073    * Analysis and Machine Vision" 2nd Edition, PWS Publishing, pp. 60-61
00074    *
00075    * The parameters to indicate value ranges of input and output are always
00076    * expected in a normalized form, i.e. in an interval from 0.0 to 1.0, where
00077    * the normalization norm is obtained with typeInfo<T>::suggestedNorm().
00078    *
00079    * Example using cvr::histogramEqualization
00080    * \code
00081    *  // The channel to be equalized and the result channel
00082    *  cvr::channel src,dest;
00083    *
00084    *  // ... initialize channel src here ...
00085    *
00086    *  // set parameters and construct the functor
00087    *  cvr::histogramEqualization::parameters param;  // parameters
00088    *  param.cells = 256;           // number of histogram bins
00089    *  param.lowerInputLimit=0.0;   // equalizes the dark values
00090    *  param.upperInputLimit=0.2;   //
00091    *  param.lowerOutputLimit=0.6;  // renders the equalized values lighter
00092    *  param.upperOutputLimit=1.0;  //
00093    *  cvr::histogramEqualization equalizer(param);          // functor
00094    *
00095    *  // equalizes the values within input range, maps them to the output range
00096    *  // and returns the partly equalized channel in dest.
00097    *  equalizer.apply(src,dest);
00098    * \endcode
00099    *
00100    * @ingroup gContrastEnhancement
00101    */
00102   class histogramEqualization : public contrastEnhancement,
00103                                 public matrixProcessingInterface<ubyte>,
00104                                 public matrixProcessingInterface<float> {
00105   public:
00106     /**
00107      * The parameters for the class cvr::histogramEqualization
00108      */
00109     class parameters : public contrastEnhancement::parameters {
00110     public:
00111       /**
00112        * Default constructor
00113        */
00114       parameters();
00115 
00116       /**
00117        * Copy constructor
00118        * @param other the parameters object to be copied
00119        */
00120       parameters(const parameters& other);
00121 
00122       /**
00123        * Destructor
00124        */
00125       ~parameters();
00126 
00127       /**
00128        * Returns the name of this type
00129        */
00130       virtual const std::string& name() const;
00131 
00132       /**
00133        * Returns a pointer to a clone of the parameters
00134        */
00135       virtual parameters* clone() const;
00136 
00137       /**
00138        * Returns a pointer to a new instance of the parameters
00139        */
00140       virtual parameters* newInstance() const;
00141 
00142       /**
00143        * Copy the other instance.here.
00144        */
00145       parameters& copy(const parameters& other);
00146 
00147       /**
00148        * Copy the contents of a parameters object.
00149        *
00150        * @param other the parameters object to be copied
00151        * @return a reference to this parameters object
00152        */
00153       parameters& operator=(const parameters& other);
00154 
00155       /**
00156        * Write the parameters in the given ioHandler.
00157        *
00158        * @param handler the ioHandler to be used
00159        * @param complete if true (the default) the enclosing begin/end will
00160        *        be also written, otherwise only the data block will be written.
00161        * @return true if write was successful
00162        */
00163       virtual bool write(ioHandler& handler,const bool complete=true) const;
00164 
00165       /**
00166        * Write the parameters in the given ioHandler.
00167        *
00168        * @param handler the ioHandler to be used
00169        * @param complete if true (the default) the enclosing begin/end will
00170        *        be also written, otherwise only the data block will be written.
00171        * @return true if write was successful
00172        */
00173       virtual bool read(ioHandler& handler,const bool complete=true);
00174 
00175       // ------------------------------------------------
00176       // the parameters
00177       // ------------------------------------------------
00178 
00179       /**
00180        * The least normalized value equalized.
00181        *
00182        * Use always values in the range between 0.0 and 1.0.
00183        *
00184        * Depending on the matrix type used, the values will be de-normalized
00185        * using the typeInfo<T>::suggestedNorm().
00186        *
00187        * Default 0.0
00188        */
00189       float lowerInputLimit;
00190 
00191       /**
00192        * The least value the equalized values are mapped to.
00193        *
00194        * Use always values in the range between 0.0 and 1.0.
00195        *
00196        * Depending on the matrix type used, the values will be de-normalized
00197        * using the typeInfo<T>::suggestedNorm().
00198        *
00199        * Default 0.0
00200        */
00201       float lowerOutputLimit;
00202 
00203       /**
00204        * The number of cells, the histogram uses for equalization
00205        *
00206        * Default 256
00207        */
00208       int cells;
00209 
00210       /**
00211        * The highest value equalized
00212        *
00213        * Use always values in the range between 0.0 and 1.0.
00214        *
00215        * Depending on the matrix type used, the values will be de-normalized
00216        * using the typeInfo<T>::suggestedNorm().
00217        *
00218        * Default 1.0
00219        */
00220       float upperInputLimit;
00221 
00222       /**
00223        * The highest value the equalized values are mapped to.
00224        *
00225        * Use always values in the range between 0.0 and 1.0.
00226        *
00227        * Depending on the matrix type used, the values will be de-normalized
00228        * using the typeInfo<T>::suggestedNorm().
00229        *
00230        * Default 1.0
00231        */
00232       float upperOutputLimit;
00233     };
00234 
00235     /**
00236      * Default constructor.
00237      */
00238     histogramEqualization();
00239 
00240     /**
00241      * Default constructor with parameters.
00242      */
00243     histogramEqualization(const parameters& params);
00244 
00245     /**
00246      * Copy constructor.
00247      *
00248      * @param other the object to be copied
00249      */
00250     histogramEqualization(const histogramEqualization& other);
00251 
00252     /**
00253      * Destructor
00254      */
00255     virtual ~histogramEqualization();
00256 
00257     /**
00258      * Returns the name of this type.
00259      */
00260     virtual const std::string& name() const;
00261 
00262     /**
00263      * Copy data of "other" functor.
00264      *
00265      * @param other the functor to be copied
00266      * @return a reference to this functor object
00267      */
00268     histogramEqualization& copy(const histogramEqualization& other);
00269 
00270     /**
00271      * Returns a pointer to a clone of this functor.
00272      */
00273     virtual histogramEqualization* clone() const;
00274 
00275     /**
00276      * Returns a pointer to a clone of this functor.
00277      */
00278     virtual histogramEqualization* newInstance() const;
00279 
00280     /**
00281      * Returns used parameters
00282      */
00283     const parameters& getParameters() const;
00284 
00285     /**
00286      * Initialize some frequently used constants
00287      */
00288     virtual bool updateParameters();
00289 
00290     /**
00291      * @name Matrix processing interface
00292      */
00293     //@{
00294     /**
00295      * Equalizes the values of the given matrix of floats (channels).
00296      *
00297      * @param srcdest Source image and result holder
00298      * @return true if ok, false otherwise.
00299 
00300      */
00301     bool apply(matrix<float>& srcdest) const;
00302 
00303     /**
00304      * Equalizes the values of the given matrix of ubytes (channel8s).
00305      *
00306      * @param srcdest Source image and result holder
00307      * @return true if ok, false otherwise.
00308      */
00309     bool apply(matrix<ubyte>& srcdest) const;
00310 
00311     /**
00312      * Equalize src and leave the result in dest.
00313      * @param src the input data
00314      * @param dest the channel where the result will be left
00315      * @return true if ok, false otherwise.
00316      */
00317     bool apply(const matrix<float>& src,
00318                      matrix<float>& dest) const;
00319 
00320     /**
00321      * Equalize src and leave the result in dest.
00322      * @param src the input data
00323      * @param dest the channel8 where the result will be left
00324      * @return true if ok, false otherwise.
00325      */
00326     bool apply(const matrix<ubyte>& src,
00327                      matrix<ubyte>& dest) const;
00328 
00329     //@}
00330 
00331     /**
00332      * Equalizes the values of the given vector of floats
00333      * @return true if ok, false otherwise.
00334      */
00335     bool apply(vector<float>& srcdest) const;
00336 
00337     /**
00338      * Equalizes the values of the given vector of ubytes
00339      * @return true if ok, false otherwise.
00340      */
00341     bool apply(vector<ubyte>& srcdest) const;
00342 
00343     /**
00344      * Generates the vector dest as the histogram equalization of the values
00345      * in the vector src.
00346      *
00347      * @param src the input data
00348      * @param dest the fvector where the result will be left
00349      * @return true if ok, false otherwise.
00350      */
00351     bool apply(const vector<float>& src,
00352                      vector<float>& dest) const;
00353 
00354     /**
00355      * Generates the vector dest as the histogram equalization of the values
00356      * in the vector src.
00357      *
00358      * @param src the input data
00359      * @param dest the vector where the result will be left
00360      * @return true if ok, false otherwise.
00361      */
00362     bool apply(const vector<ubyte>& src,
00363                      vector<ubyte>& dest) const;
00364 
00365     /**
00366      * @name Contrast enhancement interface
00367      */
00368     //@{
00369     /**
00370      * Equalizes the values of the given matrix of floats (channels).
00371      * @return true if ok, false otherwise.
00372      */
00373     bool apply(channel& srcdest) const;
00374 
00375     /**
00376      * Equalizes the values of the given matrix of ubytes (channel8s).
00377      * @return true if ok, false otherwise.
00378      */
00379     bool apply(channel8& srcdest) const;
00380 
00381     /**
00382      * Equalize src and leave the result in dest.
00383      * @param src the input data
00384      * @param dest the channel where the result will be left
00385      * @return true if ok, false otherwise.
00386      */
00387     bool apply(const channel& src,
00388                      channel& dest) const;
00389 
00390     /**
00391      * Equalize src and leave the result in dest.
00392      * @param src the input data
00393      * @param dest the channel8 where the result will be left
00394      * @return true if ok, false otherwise.
00395      */
00396     bool apply(const channel8& src,
00397                      channel8& dest) const;
00398 
00399     //@}
00400 
00401     /**
00402      * @name Partial computations
00403      *
00404      * Following methods are public since there are applicactions that need to
00405      * compute the statistics once (which are relatively expensive), and apply
00406      * them at different times.  The apply() methods are implemented using
00407      * these ones in the way indicated.
00408      */
00409     //@{
00410     /**
00411      * Inline method to compute from a pixel value the index of
00412      * the LUT obtained with the method computeLUT().
00413      */
00414     inline float getEqualized(const float p,const vector<float>& lut) const;
00415 
00416     /**
00417      * Compute LUT
00418      *
00419      * This method computes the LUT used to equalize the histogram of
00420      * a given floating-point channel.
00421      *
00422      * If you want to compute the final value q of a pixel p, then you can use
00423      * something like:
00424      *
00425      * \code
00426      *   channel chnl; // your channel
00427      *   // initialize chnl here
00428      *   ...
00429      *   // compute a Look-Up Table (LUT)
00430      *   vector<float> lut;
00431      *   histogramEqualization histEq;
00432      *   histEq.computeLUT(chnl,lut);
00433      *
00434      *   q = histEq.getEqualized(p,lut);
00435      * \endcode
00436      */
00437     bool computeLUT(const matrix<float>& chnl,
00438                     vector<float>& lut) const;
00439 
00440     /**
00441      * Compute LUT
00442      *
00443      * This method computes the LUT used to equalize the histogram of
00444      * a given channel8.
00445      *
00446      * If you want to compute the final value q of a pixel p, then you can use
00447      * something like:
00448      *
00449      * \code
00450      *   channel8 chnl; // your channel
00451      *   // initialize chnl here
00452      *   ...
00453      *   // compute a Look-Up Table (LUT)
00454      *   vector<ubyte> lut;
00455      *   histogramEqualization histEq;
00456      *   histEq.computeLUT(chnl,lut);
00457      *
00458      *   q = lut.at(p);
00459      * \endcode
00460      */
00461     bool computeLUT(const matrix<ubyte>& chnl,
00462                     vector<ubyte>& lut) const;
00463     //@}
00464 
00465 
00466   protected:
00467     /**
00468      * Shadow of parameters lowerInputLimit
00469      */
00470     float lower_;
00471 
00472     /**
00473      * Shadow of parameters upperInputLimit
00474      */
00475     float upper_;
00476 
00477     /**
00478      * Precomputed constant cst = (par.cells-1)/(upper-lower);
00479      */
00480     float cst_;
00481 
00482     /**
00483      * Shadow of parameters lowerInputLimit scaled by a norm of 255
00484      */
00485     int loweru_;
00486 
00487     /**
00488      * Shadow of parameters upperInputLimit scaled by a norm of 255
00489      */
00490     int upperu_;
00491 
00492   };
00493 
00494   // some inline methods
00495 
00496   inline float
00497   histogramEqualization::getEqualized(const float p,
00498                                       const vector<float>& lut) const {
00499     return
00500       ((p>=lower_) && (p<=upper_)) ?
00501       lut.at(static_cast<int>( 0.5f+ (p-lower_)*cst_ )) : p;
00502   }
00503 
00504 }
00505 
00506 #endif
00507 

Generated on Sun Sep 20 22:07:59 2009 for CVR-Lib by Doxygen 1.5.8