latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2001, 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 Digital Image/Signal Processing Library 00026 * file .......: ltiCurvatureScaleSpace.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 24.6.2001 00030 * revisions ..: $Id: ltiCurvatureScaleSpace.h,v 1.8 2006/02/07 18:44:06 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_CURVATURE_SCALE_SPACE_H_ 00034 #define _LTI_CURVATURE_SCALE_SPACE_H_ 00035 00036 #include "ltiImage.h" 00037 #include "ltiVector.h" 00038 #include "ltiContour.h" 00039 #include "ltiLinearKernels.h" 00040 #include "ltiTransform.h" 00041 #include "ltiConvolution.h" 00042 #include "ltiGaussKernels.h" 00043 00044 namespace lti { 00045 00046 /** 00047 * Curvature Scale Space Representation (CSS) 00048 * 00049 * This functor extracts from a boundary (borderPoints) the CSS 00050 * representation as described in Mokhtarian, F. et. al "Robust and 00051 * efficient shape indexing through curvature scale space", British 00052 * Machine Vision Conference, 1996 00053 * 00054 * The apply methods will check if there are enough points in the 00055 * input parameters to compute the css. If there are not enough points, 00056 * nothing will be done (see the apply methods for more details). 00057 */ 00058 class curvatureScaleSpace : public transform { 00059 public: 00060 /** 00061 * the parameters for the class curvatureScaleSpace 00062 */ 00063 class parameters : public transform::parameters { 00064 public: 00065 /** 00066 * default constructor 00067 */ 00068 parameters(); 00069 00070 /** 00071 * copy constructor 00072 * @param other the parameters object to be copied 00073 */ 00074 parameters(const parameters& other); 00075 00076 /** 00077 * destructor 00078 */ 00079 ~parameters(); 00080 00081 /** 00082 * returns name of this type 00083 */ 00084 const char* getTypeName() const; 00085 00086 /** 00087 * copy the contents of a parameters object 00088 * @param other the parameters object to be copied 00089 * @return a reference to this parameters object 00090 */ 00091 parameters& copy(const parameters& other); 00092 00093 /** 00094 * copy the contents of a parameters object 00095 * @param other the parameters object to be copied 00096 * @return a reference to this parameters object 00097 */ 00098 parameters& operator=(const parameters& other); 00099 00100 00101 /** 00102 * returns a pointer to a clone of the parameters 00103 */ 00104 virtual functor::parameters* clone() const; 00105 00106 /** 00107 * write the parameters in the given ioHandler 00108 * @param handler the ioHandler to be used 00109 * @param complete if true (the default) the enclosing begin/end will 00110 * be also written, otherwise only the data block will be written. 00111 * @return true if write was successful 00112 */ 00113 virtual bool write(ioHandler& handler,const bool complete=true) const; 00114 00115 /** 00116 * read the parameters from the given ioHandler 00117 * @param handler the ioHandler to be used 00118 * @param complete if true (the default) the enclosing begin/end will 00119 * be also written, otherwise only the data block will be written. 00120 * @return true if write was successful 00121 */ 00122 virtual bool read(ioHandler& handler,const bool complete=true); 00123 00124 # ifdef _LTI_MSC_6 00125 /** 00126 * this function is required by MSVC only, as a workaround for a 00127 * very awful bug, which exists since MSVC V.4.0, and still by 00128 * V.6.0 with all bugfixes (so called "service packs") remains 00129 * there... This method is also public due to another bug, so please 00130 * NEVER EVER call this method directly: use read() instead 00131 */ 00132 bool readMS(ioHandler& handler,const bool complete=true); 00133 00134 /** 00135 * this function is required by MSVC only, as a workaround for a 00136 * very awful bug, which exists since MSVC V.4.0, and still by 00137 * V.6.0 with all bugfixes (so called "service packs") remains 00138 * there... This method is also public due to another bug, so please 00139 * NEVER EVER call this method directly: use write() instead 00140 */ 00141 bool writeMS(ioHandler& handler,const bool complete=true) const; 00142 # endif 00143 00144 // ------------------------------------------------ 00145 // the parameters 00146 // ------------------------------------------------ 00147 00148 /** 00149 * if geometricDelta is true, the sigma increments will be multiplicative 00150 * i.e. sigma(1) = deltaSigma*sigma(0). If false, arithmetical 00151 * increments will be done, (sigma(1) = deltaSigma + sigma(0) 00152 * Please note that for the geometricDelta, the deltaSigma should 00153 * be greater than one to get usefull results! 00154 * 00155 * Default value: false 00156 */ 00157 bool geometricDelta; 00158 00159 /** 00160 * Step for the std. deviation to generate the CSS-image. 00161 * This value will be added at each step to the previous sigma (if 00162 * geometricDelta is false) or will be multiplied with the last sigma 00163 * (if geometricDelta is true). For the last case please ensure that 00164 * this value is greater than one, otherwise the results will be 00165 * unpredictable. 00166 * 00167 * Default value: 0.1 00168 */ 00169 double deltaSigma; 00170 00171 /** 00172 * The first std. deviation for the gaussian kernel used. 00173 * 00174 * Default value: 1.0 00175 */ 00176 double startSigma; 00177 00178 /** 00179 * Size for the first kernel being used. Note that this is the 00180 * first kernel size. As the std. deviation increases, the size of 00181 * the kernel will be updated automatically. 00182 * Default value: 9 00183 */ 00184 int gaussianSize; 00185 00186 /** 00187 * Normalized length size. This will be the number of columns 00188 * of the resulting CSS image. If negative, the length will not be 00189 * normalized and the number of columns of the resulting image will be 00190 * equal to the number of elements of the borderPoint-list given in the 00191 * apply method. 00192 * 00193 * Default value: 128 00194 */ 00195 int normLength; 00196 00197 /** 00198 * The sigmaAxisBlock specifies how many sigma steps will have a 00199 * block. The result image will have an integer number of blocks, 00200 * which means, the number of rows of the resulting channel will be 00201 * a multiple of this value. 00202 * Default value: 128 00203 */ 00204 int sigmaAxisBlock; 00205 00206 /** 00207 * pixel value in the CSS image for a positive-negative zero 00208 * crossing. 00209 * 00210 * If you want to extract features, please ensure that this value is 00211 * different than negPosCross, otherwise the features could be wrong. 00212 * 00213 * (Default: 0) 00214 */ 00215 ubyte posNegCross; 00216 00217 /** 00218 * pixel value in the CSS image for a negative-positive zero 00219 * crossing. 00220 * 00221 * If you want to extract features, please ensure that this value is 00222 * different than posNegCross, otherwise the features could be wrong. 00223 * 00224 * (Default: 255) 00225 */ 00226 ubyte negPosCross; 00227 00228 /** 00229 * value for non-zero crossing (background of the CSS image) 00230 * (Default: 128) 00231 */ 00232 ubyte nonCross; 00233 00234 /** 00235 * If false, the CSS will be computed evolving the x and y components 00236 * of the border points using the derived gauss kernels. If true, 00237 * the components will be first low-pass filtered and after that the 00238 * resulting vectors will be derived. This second method is much faster 00239 * but for the geometricDelta mode and for small sigma regions it is 00240 * not precise. If you need this functor for feature extraction, the 00241 * fast method will provide you with the maxima of the CSS "blobs" with 00242 * enough precision. 00243 * (Default value: true) 00244 */ 00245 bool fastMethod; 00246 }; 00247 00248 /** 00249 * indices for the columns of the feature-vectors in the matrix 00250 */ 00251 enum eFeatureIndices { 00252 MaxY = 0, /**< maximum sigma value of the blob */ 00253 MaxX, /**< position x (length index) of the blob maximum */ 00254 Width, /**< average width of the blob */ 00255 Offset /**< diference between the average width position and the 00256 position x of the maximum */ 00257 }; 00258 00259 /** 00260 * default constructor 00261 */ 00262 curvatureScaleSpace(); 00263 00264 /** 00265 * copy constructor 00266 * @param other the object to be copied 00267 */ 00268 curvatureScaleSpace(const curvatureScaleSpace& other); 00269 00270 /** 00271 * destructor 00272 */ 00273 virtual ~curvatureScaleSpace(); 00274 00275 /** 00276 * returns the name of this type ("curvatureScaleSpace") 00277 */ 00278 virtual const char* getTypeName() const; 00279 00280 /** 00281 * operates on the given %parameter. 00282 * @param src list of boundary points. If this list has less than 9 00283 * points (the smallest "circle" has 8 points), false will 00284 * be returned with the respective message in the status string 00285 * @param dest the CSS image will be left here. 00286 * @param maxSigma the maximum sigma in the CSS image. 00287 * @param maxRow the row corresponding to the maximum sigma. 00288 * @return true if apply successful or false otherwise. 00289 */ 00290 bool apply(const borderPoints& src, 00291 channel8& dest, 00292 float& maxSigma, 00293 int& maxRow) const; 00294 00295 /** 00296 * operates on the given %parameter. 00297 * @param src list of boundary points. If this list has less than 9 00298 * points (the smallest "circle" has 8 points), false will 00299 * be returned with the respective message in the status string 00300 * @param dest the CSS image will be left here. 00301 * @param rows a list of points p, where p.x contains the number of 00302 * blobs crossing the row of \a dest with index p.y. 00303 * In a "clean" CSS representation the number of blobs has 00304 * to decrease or be equal with increasing index p.y. If you 00305 * detect here the opposite effect is because there is too much 00306 * noise in the high-resolution levels (small variance of 00307 * Gaussians). 00308 * @return true if apply successful or false otherwise. 00309 */ 00310 bool apply(const borderPoints& src, 00311 channel8& dest, 00312 pointList& rows) const; 00313 00314 00315 /** 00316 * operates on the given %parameter. 00317 * @param src list of boundary points. If this list has less than 9 00318 * points (the smallest "circle" has 8 points), false will 00319 * be returned with the respective message in the status string 00320 * @param dest the CSS image will be left here. 00321 * @return true if apply successful or false otherwise. 00322 */ 00323 bool apply(const borderPoints& src, 00324 channel8& dest) const; 00325 00326 /** 00327 * operates on the given %parameter. This member computes the CSS-image 00328 * and the feature vectors. Each row of the matrix will correspond to 00329 * a feature vector which contains: 00330 * - Column 0: (alias for 0: MaxY) the value of the maximum of the blob. 00331 * - Column 1: (alias for 1: MaxX) the x-position of maximum of the blob. 00332 * - Column 2: (alias for 2: Width) the average width 00333 * - Column 3: (alias for 3: Offset) the offset between the x-position of 00334 * the maximum of the blob and the center 00335 * of the average width. 00336 * 00337 * @param src list of boundary points. If this list has less than 9 00338 * points (the smallest "circle" has 8 points), false will 00339 * be returned with the respective message in the status string 00340 * @param css the CSS image will be left here. 00341 * @param vcts the feature vectors packed in a matrix. 00342 * @return true if apply successful or false otherwise. 00343 */ 00344 bool apply(const borderPoints& src, 00345 channel8& css, 00346 dmatrix& vcts) const; 00347 00348 /** 00349 * operates on the given %parameter. This member computes the CSS-image 00350 * and the feature vectors. Each row of the matrix will correspond to 00351 * a feature vector which contains: 00352 * - Column 0: (alias for 0: MaxY) the value of the maximum of the blob. 00353 * - Column 1: (alias for 1: MaxX) the x-position of maximum of the blob. 00354 * - Column 2: (alias for 2: Width) the average width 00355 * - Column 3: (alias for 3: Offset) the offset between the x-position of 00356 * the maximum of the blob and the center 00357 * of the average width. 00358 * 00359 * @param src list of boundary points. If this list has less than 9 00360 * points (the smallest "circle" has 8 points), false will 00361 * be returned with the respective message in the status string 00362 * @param css the CSS image will be left here. 00363 * @param vcts the feature vectors packed in a matrix. 00364 * @param rows a list of points p, where p.x contains the number of 00365 * blobs crossing the row of \a dest with index p.y. 00366 * In a "clean" CSS representation the number of blobs has 00367 * to decrease or be equal with increasing index p.y. If you 00368 * detect here the opposite effect is because there is too much 00369 * noise in the high-resolution levels (small variance of 00370 * Gaussians). 00371 * @return true if apply successful or false otherwise. 00372 */ 00373 bool apply(const borderPoints& src, 00374 channel8& css, 00375 dmatrix& vcts, 00376 pointList& rows) const; 00377 00378 /** 00379 * operates on the given %parameter. 00380 * This member computes the CSS-image and the feature vectors. 00381 * Each row of the matrix will correspond to a feature vector 00382 * which contains: 00383 * - Column 0: (alias for 0: MaxY) the value of the maximum of the blob. 00384 * - Column 1: (alias for 1: MaxX) the x-position of maximum of the blob. 00385 * - Column 2: (alias for 2: Width) the average width 00386 * - Column 3: (alias for 3: Offset) the offset between the x-position of 00387 * the maximum of the blob and the center 00388 * of the average width. 00389 * 00390 * @param src list of boundary points. If this list has less than 9 00391 * points (the smallest "circle" has 8 points), false will 00392 * be returned with the respective message in the status string 00393 * @param vcts feature vectors. Each row corresponds to a CSS "blob" 00394 * @return true if apply successful or false otherwise. 00395 */ 00396 bool apply(const borderPoints& src, 00397 dmatrix& vcts) const; 00398 00399 /** 00400 * copy data of "other" functor. 00401 * @param other the functor to be copied 00402 * @return a reference to this functor object 00403 */ 00404 curvatureScaleSpace& copy(const curvatureScaleSpace& other); 00405 00406 /** 00407 * returns a pointer to a clone of this functor. 00408 */ 00409 virtual functor* clone() const; 00410 00411 /** 00412 * returns used parameters 00413 */ 00414 const parameters& getParameters() const; 00415 00416 00417 00418 protected: 00419 00420 /** 00421 * extract the x and y components of the borderPoints object and 00422 * resize (normalize the length) of the vectors if required. 00423 */ 00424 bool borderToXY(const borderPoints& src, 00425 vector<float>& theX, 00426 vector<float>& theY) const; 00427 00428 00429 /** 00430 * calculate the gaussian first and second derivative kernels. 00431 * The size is calcultated considering the parameters object. 00432 */ 00433 void calcKernels(const float& sigma, 00434 kernel1D<float>& first, 00435 kernel1D<float>& second) const; 00436 00437 /** 00438 * calculate the curvature using the derivatives 00439 */ 00440 int curvature(const float& sigma, 00441 const vector<float>& theX, 00442 const vector<float>& theY, 00443 vector<float>& curv, 00444 vector<ubyte>& zeroCross) const; 00445 00446 /** 00447 * calculate the gaussian first and second derivative kernels. 00448 * The size of the kernel is recomputed considering the parameters object. 00449 * The sigma term will be updated to the new one. 00450 */ 00451 void calcKernels(float& sigma, 00452 gaussKernel1D<float>& gaussian) const; 00453 00454 /** 00455 * calculate the curvature using the derivatives 00456 */ 00457 int curvature(const gaussKernel1D<float>& gaussian, 00458 vector<float>& theX, 00459 vector<float>& theY, 00460 vector<float>& curv, 00461 vector<ubyte>& zeroCross, 00462 const int& lastZC) const; 00463 00464 /** 00465 * operates on the given %parameter. 00466 * @param src list of boundary points. 00467 * @param dest the CSS image will be left here. 00468 * @param maxSigma the maximum sigma in the CSS image. 00469 * @param maxRow the row corresponding to the maximum sigma. 00470 * @param rows a list of points, where x contains the number of 00471 * maxima of the row with the index given by y. 00472 * @return true if apply successful or false otherwise. 00473 */ 00474 bool cssOriginal(const borderPoints& src, 00475 channel8& dest, 00476 float& maxSigma, 00477 int& maxRow, 00478 pointList& rows) const; 00479 00480 /** 00481 * operates on the given %parameter. 00482 * @param src list of boundary points. 00483 * @param dest modified CSS image will be left here. 00484 * @param maxSigma the maximum sigma in the CSS image. 00485 * @param maxRow the row corresponding to the maximum sigma. 00486 * @param rows a list of points, where x contains the number of 00487 * maxima of the row with the index given in the point's y. 00488 * @return true if apply successful or false otherwise. 00489 */ 00490 bool cssFast(const borderPoints& src, 00491 channel8& dest, 00492 float& maxSigma, 00493 int& maxRow, 00494 pointList& rows) const; 00495 00496 void derive(const vector<float>& theX, 00497 vector<float>& xu, 00498 vector<float>& xuu) const; 00499 00500 00501 00502 /** 00503 * calculate the zero crossings. The output vector MUST have the 00504 * same size as the input vector. 00505 * 00506 * This member returns the number of zero crossings detected. 00507 */ 00508 int zeroCross(const vector<float>& curv, 00509 vector<ubyte>& dest, 00510 const ubyte& posNeg, 00511 const ubyte& negPos) const; 00512 00513 /** 00514 * extract the blobs from the css image (only the first 127 blobs will 00515 * be extracted) 00516 */ 00517 int extractBlobs(const channel8& css, 00518 const pointList& rows, 00519 matrix<int>& blobs, 00520 dmatrix& features) const; 00521 00522 }; 00523 } 00524 00525 #endif