latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 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 .......: ltiCWAGMSegmentation.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 30.6.2003 00030 * revisions ..: $Id: ltiCWAGMSegmentation.h,v 1.2 2006/02/07 18:33:41 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_CWAGM_SEGMENTATION_H_ 00034 #define _LTI_CWAGM_SEGMENTATION_H_ 00035 00036 #include "ltiMacroSymbols.h" 00037 00038 // only for compilers different than VC++ 6.0 available 00039 #ifdef _LTI_MSC_6 00040 00041 #pragma message("Insufficient C++ Template Support for lti::regionGraphMeans.") 00042 #pragma message("You need a newer compiler") 00043 00044 #else 00045 00046 00047 #include "ltiSegmentation.h" 00048 #include "ltiMedianFilter.h" 00049 #include "ltiColorContrastGradient.h" 00050 #include "ltiSplitImage.h" 00051 #include "ltiWatershedSegmentation.h" 00052 #include "ltiRegionGraphMeans.h" 00053 00054 #include <map> 00055 #include <vector> 00056 00057 #undef _LTI_DEBUG 00058 //#define _LTI_DEBUG 3 00059 #include "ltiDebug.h" 00060 00061 namespace lti { 00062 00063 // ------------------------------------------------------------------------ 00064 // 00065 // Color Watershed - Adjacency Graph Merge 00066 // 00067 // ------------------------------------------------------------------------ 00068 00069 00070 /** 00071 * CWAGM Segmentation 00072 * 00073 * CWAGM means Color Watershed - Adjacency Graph Merge. It is a 00074 * segmentation algortihms based on low level information introduced in 00075 * P. Alvarado "Segmentation of color images for interactive 3D object 00076 * retrieval". Ph.D. Thesis. RWTH-Aachen, 2004. 00077 * http://www.bth.rwth-aachen.de/job/disslist.pl 00078 * 00079 * This watershed-based concept is based on the ideas of Haris et.al. 00080 * for a segmentation concept of gray-valued image, extended to color images. 00081 * It uses (optionally) a median filtering to reduce the noise in each color 00082 * channel, computes an over-segmentation with the watershed transformation 00083 * and merge the regions to minimize the mean square error of a piece-wise 00084 * constant image approximation. 00085 */ 00086 class cwagmSegmentation : public segmentation { 00087 public: 00088 00089 /** 00090 * the parameters for the class cwagmSegmentation 00091 */ 00092 class parameters : public segmentation::parameters { 00093 public: 00094 /** 00095 * default constructor 00096 */ 00097 parameters(); 00098 00099 /** 00100 * copy constructor 00101 * @param other the parameters object to be copied 00102 */ 00103 parameters(const parameters& other); 00104 00105 /** 00106 * destructor 00107 */ 00108 ~parameters(); 00109 00110 /** 00111 * returns name of this type 00112 */ 00113 const char* getTypeName() const; 00114 00115 /** 00116 * copy the contents of a parameters object 00117 * @param other the parameters object to be copied 00118 * @return a reference to this parameters object 00119 */ 00120 parameters& copy(const parameters& other); 00121 00122 /** 00123 * copy the contents of a parameters object 00124 * @param other the parameters object to be copied 00125 * @return a reference to this parameters object 00126 */ 00127 parameters& operator=(const parameters& other); 00128 00129 /** 00130 * returns a pointer to a clone of the parameters 00131 */ 00132 virtual functor::parameters* clone() const; 00133 00134 /** 00135 * write the parameters in the given ioHandler 00136 * @param handler the ioHandler to be used 00137 * @param complete if true (the default) the enclosing begin/end will 00138 * be also written, otherwise only the data block will be written. 00139 * @return true if write was successful 00140 */ 00141 virtual bool write(ioHandler& handler,const bool complete=true) const; 00142 00143 /** 00144 * read the parameters from the given ioHandler 00145 * @param handler the ioHandler to be used 00146 * @param complete if true (the default) the enclosing begin/end will 00147 * be also written, otherwise only the data block will be written. 00148 * @return true if write was successful 00149 */ 00150 virtual bool read(ioHandler& handler,const bool complete=true); 00151 00152 // ------------------------------------------------ 00153 // the parameters 00154 // ------------------------------------------------ 00155 00156 /** 00157 * @name Preprocessing 00158 */ 00159 //@{ 00160 /** 00161 * A median filter with following parameters is used to denoise the image 00162 * 00163 * If you don't want any pre-smoothing, indicate a kernel size of 1 or 00164 * zero and nothing will be done. 00165 * 00166 * Default value: medianParam::kernelSize = 3; 00167 * medianParam::boundaryType = Constant; 00168 */ 00169 medianFilter::parameters medianParam; 00170 00171 /** 00172 * Enhance contrast 00173 * 00174 * If set to \a true, the dynamic range of the channels will be 00175 * optimized. 00176 * 00177 * Since the RGB channels will be linearly expanded to map 00178 * min(R,G,B)-max(R,G,B) to the 0-255 range, the colors of the image 00179 * will not be severely altered. 00180 * 00181 * Default value: true 00182 */ 00183 bool enhanceContrast; 00184 //@} 00185 00186 /** 00187 * @name Split-Stage with Watersheds 00188 */ 00189 //@{ 00190 /** 00191 * The colorSplitter specifies the name of the color space splitting 00192 * functor used to extract the color components of the image, which are 00193 * employed to analyze the edges of the image. 00194 * 00195 * Default value: "lti::splitImageToXYZ" 00196 */ 00197 std::string colorSplitter; 00198 00199 /** 00200 * Parameters for the computations of the color contrast gradient 00201 * 00202 * The result is also the input for the watershed algorithm. 00203 */ 00204 colorContrastGradient::parameters colorContrastParam; 00205 00206 /** 00207 * Watershed transform parameters. 00208 * 00209 * Default: Rainfall method is selected as default and a 8-Neighborhood. 00210 * The threshold is set to 255 to activate the automatic 00211 * threshold detection. 00212 */ 00213 watershedSegmentation::parameters watershedParam; 00214 00215 /** 00216 * To compute which threshold should be used in the watershed 00217 * segmentation, the accumulative histogram of gradient values will be 00218 * used as a probability distribution. It will be assumed that the 00219 * probability for a gradient value to be relevant must be greater 00220 * than the given value. 00221 * 00222 * If you set a value close to zero, almost any gradient value will be 00223 * detected as edge, and an oversegmentation will be produced. 00224 * 00225 * If you set a value close to one, then only very strong gradient 00226 * values will be considered, causing an undersegmentation. 00227 * 00228 * The automatic threshold computation will be done only if the user set 00229 * the watershedParam.threshold to 255. 00230 * 00231 * The value range must be between 0.0f and 1.0f 00232 * 00233 * Default value: 0.45f 00234 */ 00235 float minProbForWatershedThreshold; 00236 //@} 00237 00238 /** 00239 * Merging parameters for the graph representation. 00240 * 00241 * Watersheds over-segment images. The high number of regions detected 00242 * slows down the rest of the algorithms. Therefore a first "merging" 00243 * stage is done, using an adaption of the distance measure suggested by 00244 * Haris et.al. to also use color images. All adjacent regions with 00245 * distances under the given threshold will be merged. 00246 * 00247 * A mergeThreshold value close to zero means that only very similar 00248 * regions have to be merged, while a large value indicates to be much 00249 * more tolerant while merging and many regions will be merged. 00250 * 00251 * The threshold indicated within this parameter objects indicate a 00252 * square distance between mean values in the color space weighted by 00253 * the area of the regions, so that this value will be between 0 and 00254 * about 1000000, depending on the regions detected. You will usually 00255 * give values between 0 and 2000 00256 * 00257 * Default: harisRegionMergeParam::mergeThreshold = 1 00258 * harisRegionMergeParam::minRegionNumber = 10 00259 */ 00260 regionGraphColorHaris::parameters harisRegionMergeParam; 00261 }; 00262 00263 /** 00264 * default constructor 00265 */ 00266 cwagmSegmentation(); 00267 00268 /** 00269 * Construct a functor using the given parameters 00270 */ 00271 cwagmSegmentation(const parameters& par); 00272 00273 /** 00274 * copy constructor 00275 * @param other the object to be copied 00276 */ 00277 cwagmSegmentation(const cwagmSegmentation& other); 00278 00279 /** 00280 * destructor 00281 */ 00282 virtual ~cwagmSegmentation(); 00283 00284 /** 00285 * returns the name of this type ("cwagmSegmentation") 00286 */ 00287 virtual const char* getTypeName() const; 00288 00289 /** 00290 * operates on a copy of the given %parameters. 00291 * @param src image with the source data. 00292 * @param regions labeled mask as imatrix, where the result will be left. 00293 * @param regionSizes sizes of each region in the \a regions mask. 00294 * @return true if apply successful or false otherwise. 00295 */ 00296 bool apply(const image& src, 00297 imatrix& regions, 00298 ivector& regionSizes); 00299 00300 /** 00301 * operates on a copy of the given %parameters. 00302 * @param src image with the source data. 00303 * @param preproc preprocessed image. 00304 * @param regions labeled mask as imatrix, where the result will be left. 00305 * @param regionSizes sizes of each region in the \a regions mask. 00306 * @return true if apply successful or false otherwise. 00307 */ 00308 bool apply(const image& src, 00309 image& preproc, 00310 imatrix& regions, 00311 ivector& regionSizes); 00312 00313 00314 /** 00315 * Segmentate the image \a src and return many internal partial results 00316 * that can be used in further processing units. 00317 * 00318 * Note that there are several segmentation modes (like color ACA or 00319 * mean-shift segmentation) which do not require the gradient computation. 00320 * These modes will leave the given \a gradMag and \a gradArg untouched. 00321 * This way, the gradients won't be unnecessarily computed and you can 00322 * detect if they are computed or not: just give empty channels and if 00323 * they are still empty after calling this method, you will have to 00324 * compute them, if you need to. 00325 * 00326 * @param src image with the source data. 00327 * @param preproc resulting preprocessed image. 00328 * @param regions labeled mask as imatrix, where the result will be left. 00329 * @param regionSizes sizes of each region in the \a regions mask. 00330 * @param gradMag magnitude of the color gradient 00331 * @param gradArg orientation of the color gradient 00332 * @return true if apply successful or false otherwise. 00333 */ 00334 bool apply(const image& src, 00335 image& preproc, 00336 imatrix& regions, 00337 ivector& regionSizes, 00338 channel& gradMag, 00339 channel& gradArg); 00340 00341 /** 00342 * copy data of "other" functor. 00343 * @param other the functor to be copied 00344 * @return a reference to this functor object 00345 */ 00346 cwagmSegmentation& copy(const cwagmSegmentation& other); 00347 00348 /** 00349 * alias for copy member 00350 * @param other the functor to be copied 00351 * @return a reference to this functor object 00352 */ 00353 cwagmSegmentation& operator=(const cwagmSegmentation& other); 00354 00355 /** 00356 * returns a pointer to a clone of this functor. 00357 */ 00358 virtual functor* clone() const; 00359 00360 /** 00361 * returns used parameters 00362 */ 00363 const parameters& getParameters() const; 00364 00365 /** 00366 * Update functor's parameters. 00367 * 00368 * Update the internal state of the functor according to the parameters. 00369 * This special case the functor used to split the image into its color 00370 * componentes is initialized here. 00371 * 00372 * @return true if successful, false otherwise 00373 */ 00374 virtual bool updateParameters(); 00375 00376 protected: 00377 00378 /** 00379 * Preprocess 00380 * Denoise and Enhance Contrast 00381 */ 00382 bool preprocess(const image& src,image& dest) const; 00383 00384 /** 00385 * Split and merge with watersheds. 00386 * 00387 * @param orig original color image 00388 * @param preproc preprocessed image 00389 * @param regions labeld mask with initial partition 00390 * @param regionSizes number of pixels per region 00391 * @param gradM magnitude of the color gradient 00392 * @param gradA orientation of the color gradient 00393 * @param gradHisto histogram of the gradient values 00394 * @param maxGrad maximum gradient value which is also the last value in 00395 * the histogram. 00396 */ 00397 bool worker(const image& orig, 00398 const image& preproc, 00399 imatrix& regions, 00400 ivector& regionSizes, 00401 channel& gradM, 00402 channel& gradA, 00403 vector<float>& gradHisto, 00404 float& maxGrad); 00405 00406 /** 00407 * The simplest contrast enhancement consists in mapping the input value 00408 * range of each channel into 0 to 255, each channel independently of 00409 * the others. 00410 * 00411 * src MUST be connected. (see matrix<T>::mode()) 00412 */ 00413 bool enhanceContrast(image& src) const; 00414 00415 /** 00416 * @name local functors 00417 */ 00418 //@{ 00419 /** 00420 * median filter 00421 */ 00422 medianFilter median; 00423 00424 /** 00425 * Watershed segmentation functor 00426 */ 00427 watershedSegmentation watershed; 00428 00429 /** 00430 * pointer to splitter object 00431 */ 00432 splitImage* splitter; 00433 00434 /** 00435 * color contrast gradient functor used in edge detection 00436 */ 00437 colorContrastGradient colorContrast; 00438 00439 /** 00440 * Haris region merging method (well, my adaption of it) 00441 */ 00442 regionGraphColorHaris haris; 00443 //@} 00444 00445 }; 00446 } 00447 00448 #endif 00449 00450 #include "ltiUndebug.h" 00451 #endif