latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2002, 2003, 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*-------------------------------------------------------------------- 00025 * project ....: LTI-Lib: Image Processing and Computer Vision Library 00026 * file .......: ltiWhiteningSegmentation.h 00027 * authors ....: Axel Berner 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 14.2.2002 00030 * revisions ..: $Id: ltiWhiteningSegmentation.h,v 1.8 2006/02/08 11:59:50 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_WHITENING_SEGMENTATION_H_ 00034 #define _LTI_WHITENING_SEGMENTATION_H_ 00035 00036 #include "ltiImage.h" 00037 #include "ltiPCA.h" 00038 #include "ltiSegmentation.h" 00039 #include "ltiKMeansSegmentation.h" 00040 #include "ltiPointList.h" 00041 00042 namespace lti { 00043 /** 00044 * The whitening segmentation is an extention of the k-Means based 00045 * segmentation (see lti::kMeansSegmentation). Internally, it 00046 * computes the k-Means segmentation of the given image, and the 00047 * k-Means segmentation of an image resulting from mapping linearly 00048 * each RGB pixel in the original image into another color space 00049 * determined by the given pca transformation functor. The mapping is 00050 * clipped using a sigmoid function to keep all values in the valid 00051 * RGB space (0..255 for each component). The last stage removes the 00052 * smallest regions assigning their pixels to the neighbor most similar ones. 00053 * 00054 * The PCA can be obtained using from example the 00055 * lti::colorModelSelector, which is usually configured to returned 00056 * a skin color model. The PCA is used to make a "color zoom" into 00057 * the skin color to detect the borders between skin colored objects 00058 * and real skin. 00059 * 00060 * The two color quantization results are combined into the final one, 00061 * multiplying the labels of the second segmentation by the number of 00062 * labels of the first quantization, and adding the first quantization. 00063 * 00064 * \warning The RGB color space used is the unit cube (red, green 00065 * and blue components between zero and one) and not the 8-bit based 00066 * color cube, so, if you use lti::colorModelEstimator or 00067 * lti::computePalette to compute a statistic color model be sure 00068 * that you norm the estimated mean and covariance accordingly: 00069 * mean.divide(255) and covariance.divide(255*255)! For an example 00070 * see transformImage() 00071 */ 00072 class whiteningSegmentation : public segmentation { 00073 public: 00074 /** 00075 * the parameters for the class whiteningSegmentation 00076 */ 00077 class parameters : public segmentation::parameters { 00078 public: 00079 /** 00080 * default constructor 00081 */ 00082 parameters(); 00083 00084 /** 00085 * copy constructor 00086 * @param other the parameters object to be copied 00087 */ 00088 parameters(const parameters& other); 00089 00090 /** 00091 * destructor 00092 */ 00093 ~parameters(); 00094 00095 /** 00096 * returns name of this type 00097 */ 00098 const char* getTypeName() const; 00099 00100 /** 00101 * copy the contents of a parameters object 00102 * @param other the parameters object to be copied 00103 * @return a reference to this parameters object 00104 */ 00105 parameters& copy(const parameters& other); 00106 00107 /** 00108 * copy the contents of a parameters object 00109 * @param other the parameters object to be copied 00110 * @return a reference to this parameters object 00111 */ 00112 parameters& operator=(const parameters& other); 00113 00114 /** 00115 * returns a pointer to a clone of the parameters 00116 */ 00117 virtual functor::parameters* clone() const; 00118 00119 /** 00120 * write the parameters in the given ioHandler 00121 * @param handler the ioHandler to be used 00122 * @param complete if true (the default) the enclosing begin/end will 00123 * be also written, otherwise only the data block will be written. 00124 * @return true if write was succe quantColorsTransformed = 15; 00125 ssful 00126 */ 00127 virtual bool write(ioHandler& handler,const bool complete=true) const; 00128 00129 /** 00130 * read the parameters from the given ioHandler 00131 * @param handler the ioHandler to be used 00132 * @param complete if true (the default) the enclosing begin/end will 00133 * be also written, otherwise only the data block will be written. 00134 * @return true if write was successful 00135 */ 00136 virtual bool read(ioHandler& handler,const bool complete=true); 00137 00138 # ifdef _LTI_MSC_6 00139 /** 00140 * this function is required by MSVC only, as a workaround for a 00141 * very awful bug, which exists since MSVC V.4.0, and still by 00142 * V.6.0 with all bugfixes (so called "service packs") remains 00143 * there... This method is also public due to another bug, so please 00144 * NEVER EVER call this method directly: use read() instead 00145 */ 00146 bool readMS(ioHandler& handler,const bool complete=true); 00147 00148 /** 00149 * this function is required by MSVC only, as a workaround for a 00150 * very awful bug, which exists since MSVC V.4.0, and still by 00151 * V.6.0 with all bugfixes (so called "service packs") remains 00152 * there... This method is also public due to another bug, so please 00153 * NEVER EVER call this method directly: use write() instead 00154 */ 00155 bool writeMS(ioHandler& handler,const bool complete=true) const; 00156 # endif 00157 00158 // ------------------------------------------------ 00159 // the parameters 00160 // ------------------------------------------------ 00161 00162 /** 00163 * parameters for the color quantization of the original image 00164 * 00165 * Default value: kernelSize=5, quantColors=16, smoothFilter=KNearest 00166 */ 00167 kMeansSegmentation::parameters quantNormal; 00168 00169 /** 00170 * parameters for the color quantization of the transformed 00171 * (color zoomed) image. 00172 * 00173 * Default value: kernelSize=5, quantColors=15, smoothFilter=KNearest 00174 */ 00175 kMeansSegmentation::parameters quantTransformed; 00176 00177 /** 00178 * minimum number of pixel for a region. 00179 * 00180 * Default value: 12 00181 */ 00182 int minRegionSize; 00183 00184 }; 00185 00186 /** 00187 * default constructor 00188 */ 00189 whiteningSegmentation(); 00190 00191 /** 00192 * copy constructor 00193 * @param other the object to be copied 00194 */ 00195 whiteningSegmentation(const whiteningSegmentation& other); 00196 00197 /** 00198 * destructor 00199 */ 00200 virtual ~whiteningSegmentation(); 00201 00202 /** 00203 * returns the name of this type ("whiteningSegmentation") 00204 */ 00205 virtual const char* getTypeName() const; 00206 00207 /** 00208 * attaches all pixel given by the freePoints list 00209 * to a neighbour region (same label) by checking the 00210 * color distances (freePoint to all its neighbours) 00211 * @param src original image 00212 * @param freePoints list of points to be reassigned 00213 * @param imgMap the image regions map 00214 */ 00215 void attachPoints(const image& src, 00216 pointList& freePoints, 00217 imatrix& imgMap) const; 00218 00219 /** 00220 * removes small regions from label image imgMap. 00221 * All pixels belong to a region which consist less than 00222 * thresh pixels are attached to a neighbour region. 00223 * @param src original image 00224 * @param thresh minimal valid value for the size of a region 00225 * @param imgMap the image regions map 00226 */ 00227 void removeSmallRegions(const image& src, 00228 const int& thresh, 00229 imatrix& imgMap) const; 00230 00231 /** 00232 * whitening transformation of the src image in the dest image 00233 * using the given pca transformation functor. 00234 * 00235 * A sigmoid clipping will be taken to limit the result to valid 00236 * values in the RGB color space. This operation can be considered 00237 * as color zooming. 00238 * 00239 * For the given pca functor, it will be expected that the color 00240 * axes have been normalized from 0 to 1 (instead of 0 to 255). 00241 * 00242 * @see transformImage(const drgbPixel&,const dmatrix&,const image&,image&) 00243 * 00244 * @param pca functor with the linear transformation matrix (pca). 00245 * @param src image 00246 * @param dest color zoomed image 00247 * 00248 * Example: 00249 * \code 00250 * 00251 * // Example for color zoom 00252 * 00253 * lti::image img; // original color imaged 00254 * lti::image zoomed; // color zoomed image 00255 * lti::imatrix mask; // labeled mask, result of a segmentation algorithm 00256 * 00257 * ... // get the image and the mask with any algorithm... 00258 * 00259 * lti::computePalette compPal; // functor used to get a complete palette 00260 * // or just a palette entry of an image 00261 * // given a mask. 00262 * lti::fmatrix covariance; // covariance matrix of the color 00263 * lti::fvector mean; // mean color 00264 * int n; // how many pixels were considered in the 00265 * // computation of mean and covariance. 00266 * 00267 * // compute mean color and covariance matrix for the pixels with 00268 * // label "0" (usually background) 00269 * compPal.apply(img,mask,0,mean,covariance,n); 00270 * 00271 * // for the color zooming, the mean and covariance need to be 00272 * // given for the unit cube color space, instead of the 8-bit valued 00273 * // color space. 00274 * mean.divide(255); 00275 * covariance.divide(255*255); 00276 * 00277 * // principal components functor used to transform the pixel colors 00278 * lti::principalComponents<float> pca; 00279 * lti::principalComponents<float>::parameters pcaPar; 00280 * 00281 * pcaPar.whitening = true; // whitening transform is a requirement! 00282 * pcaPar.resultDim = 3; // after the transform, each pixel must 00283 * // still have three dimensions! 00284 * pcaPar.autoDim = false; // do not try to reduce the dimensionality 00285 * 00286 * pca.setParameters(pcaPar); // specify to use the given parameters 00287 * pca.setCovarianceAndMean(covariance,mean); // and the computed stats. 00288 * 00289 * // compute the color zoomed image 00290 * lti::whiteningSegmentation wseg; 00291 * wseg.transformImage(pca,img,zoomed); 00292 * 00293 * \endcode 00294 */ 00295 bool transformImage(const principalComponents<float>& pca, 00296 const image& src, 00297 image& dest) const; 00298 00299 00300 /** 00301 * whitening transformation of the src image in the dest image 00302 * using the given statistical parameter to create a pca-whitening 00303 * transformation. 00304 * 00305 * A sigmoid clipping will be taken to limit the result to valid 00306 * values in the RGB color space. This operation can be considered 00307 * as color zooming. 00308 * 00309 * The given parameters of mean and covariance can be computed 00310 * directly with functors like the colorModelEstimator and 00311 * computePalette (for this last one some type conversions would 00312 * be required) 00313 * 00314 * @see transformImage(const principalComponents<float>&,const image&, 00315 * image&) 00316 * 00317 * @param mean drgbPixel with the mean color, that will be 00318 * projected into rgbPixel(128,128,128). The coordinates of 00319 * the mean should be between 0 and 255. 00320 * @param covar a 3x3 dmatrix with the covariance matrix of the colors. 00321 * @param src source image 00322 * @param dest color zoomed image 00323 * 00324 * Example: 00325 * \code 00326 * 00327 * // Example for color zoom 00328 * 00329 * lti::image img; // original color imaged 00330 * lti::image zoomed; // color zoomed image 00331 * 00332 * ... // get the image and the mask with any algorithm... 00333 * 00334 * lti::colorModelEstimator colEst; // functor used to get a color model 00335 * lti::dmatrix covariance; // covariance matrix of the color 00336 * lti::drgbPixel mean; // mean color 00337 * 00338 * // compute mean color and covariance matrix for the pixels in the given 00339 * // image. 00340 * colEst.consider(img); 00341 * colEst.apply(mean,covariance); 00342 * 00343 * // compute the color zoomed image 00344 * lti::whiteningSegmentation wseg; 00345 * wseg.transformImage(mean,covariance,img,zoomed); 00346 * 00347 * \endcode 00348 */ 00349 bool transformImage(const drgbPixel& mean, 00350 const dmatrix& covar, 00351 const image& src, 00352 image& dest) const; 00353 00354 00355 /** 00356 * operates on a copy of the given %parameters. 00357 * @param src image with the source data. 00358 * @param pca functor responsible for the color zooming 00359 * @param dest image where the result will be left. 00360 * @return true if apply successful or false otherwise. 00361 */ 00362 bool apply(const image& src, 00363 const principalComponents<float>& pca, 00364 imatrix& dest) const; 00365 00366 /** 00367 * operates on a copy of the given %parameters. You can get the 00368 * mean and covariance matrix (which should be computed in a RGB 00369 * color space with each color between 0 and 255) using the 00370 * lti::colorModelEstimator functor. 00371 * 00372 * @param src image with the source data. 00373 * @param mean mean color used for the pca/whitening transformation 00374 * @param covar covariance matrix used for the pca/whitening transformation 00375 * @param dest image where the result will be left. 00376 * @return true if apply successful or false otherwise. 00377 */ 00378 bool apply(const image& src, 00379 const drgbPixel& mean, 00380 const dmatrix& covar, 00381 imatrix& dest) const; 00382 00383 /** 00384 * copy data of "other" functor. 00385 * @param other the functor to be copied 00386 * @return a reference to this functor object 00387 */ 00388 whiteningSegmentation& copy(const whiteningSegmentation& other); 00389 00390 /** 00391 * alias for copy member 00392 * @param other the functor to be copied 00393 * @return a reference to this functor object 00394 */ 00395 whiteningSegmentation& operator=(const whiteningSegmentation& other); 00396 00397 /** 00398 * returns a pointer to a clone of this functor. 00399 */ 00400 virtual functor* clone() const; 00401 00402 /** 00403 * returns used parameters 00404 */ 00405 const parameters& getParameters() const; 00406 00407 //TODO: comment the attributes of your functor 00408 // If you add more attributes manually, do not forget to do following: 00409 // 1. indicate in the default constructor the default values 00410 // 2. make sure that the copy member also copy your new attributes, or 00411 // to ensure there, that these attributes are properly initialized. 00412 00413 }; 00414 } 00415 00416 #endif