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 .......: ltiHarrisCorners.h 00027 * authors ....: Pablo Alvarado 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 31.10.2002 00030 * revisions ..: $Id: ltiHarrisCorners.h,v 1.12 2006/02/08 11:14:54 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_HARRIS_CORNERS_H_ 00034 #define _LTI_HARRIS_CORNERS_H_ 00035 00036 #include "ltiCornerDetector.h" 00037 #include "ltiPointList.h" 00038 #include "ltiLocalMaxima.h" 00039 #include "ltiGradientFunctor.h" 00040 00041 namespace lti { 00042 /** 00043 * Harris Corner Detector. 00044 * 00045 * The Harris corner detector is based on 00046 * 00047 * C. Harris and M. Stephens, "A Combined Corner and Edge Detector", 00048 * in Proc. 4th Alvey Vision Conference, pp. 147-151, 1988 00049 * 00050 * It uses a matrix \e A that averages element-wise products of the 00051 * gradients \e Ix and \e Iy over a Gaussian window \e W: 00052 * 00053 * \f[ A(x,y) = \begin{bmatrix} \sum_W I_x^2 & \sum_W I_xI_y \\ 00054 * \sum_W I_xI_y & \sum_W I_y^2 \end{bmatrix} \f] 00055 * 00056 * The corners are defined as the local maxima of a cornerness 00057 * channel. The cornerness \a c(x,y) of a channel \a f(x,y) is 00058 * defined as: 00059 * 00060 * \f[ c(x,y)= \det(A(x,y)) - s \cdot\mathrm{tr}(A(x,y))^2 \f] 00061 * 00062 * Remember that the product of the eigenvalues equals the 00063 * determinant of the matrix and the sum of eigenvalues equals its 00064 * trace. 00065 * 00066 * Slight modifications are used in order to increase the quality of 00067 * the detection. 00068 * 00069 * The default paramters use the Harris Kernel (see harrisKernelX) 00070 * as gradient. However, you can choose freely from all available 00071 * gradient kernels. Most notably, by using 00072 * gradientFunctor::parameters::OGD, the harrisCorners %functor 00073 * should behave similarly to the improved Harris introduced by 00074 * Schmid et al. 00075 */ 00076 class harrisCorners : public cornerDetector { 00077 public: 00078 /** 00079 * the parameters for the class harrisCorners 00080 */ 00081 class parameters : public cornerDetector::parameters { 00082 public: 00083 /** 00084 * default constructor 00085 */ 00086 parameters(); 00087 00088 /** 00089 * copy constructor 00090 * @param other the parameters object to be copied 00091 */ 00092 parameters(const parameters& other); 00093 00094 /** 00095 * destructor 00096 */ 00097 ~parameters(); 00098 00099 /** 00100 * returns name of this type 00101 */ 00102 const char* getTypeName() const; 00103 00104 /** 00105 * copy the contents of a parameters object 00106 * @param other the parameters object to be copied 00107 * @return a reference to this parameters object 00108 */ 00109 parameters& copy(const parameters& other); 00110 00111 /** 00112 * copy the contents of a parameters object 00113 * @param other the parameters object to be copied 00114 * @return a reference to this parameters object 00115 */ 00116 parameters& operator=(const parameters& other); 00117 00118 00119 /** 00120 * returns a pointer to a clone of the parameters 00121 */ 00122 virtual functor::parameters* clone() const; 00123 00124 /** 00125 * write the parameters in the given ioHandler 00126 * @param handler the ioHandler to be used 00127 * @param complete if true (the default) the enclosing begin/end will 00128 * be also written, otherwise only the data block will be written. 00129 * @return true if write was successful 00130 */ 00131 virtual bool write(ioHandler& handler,const bool complete=true) const; 00132 00133 /** 00134 * read the parameters from the given ioHandler 00135 * @param handler the ioHandler to be used 00136 * @param complete if true (the default) the enclosing begin/end will 00137 * be also written, otherwise only the data block will be written. 00138 * @return true if write was successful 00139 */ 00140 virtual bool read(ioHandler& handler,const bool complete=true); 00141 00142 # ifdef _LTI_MSC_6 00143 /** 00144 * this function is required by MSVC only, as a workaround for a 00145 * very awful bug, which exists since MSVC V.4.0, and still by 00146 * V.6.0 with all bugfixes (so called "service packs") remains 00147 * there... This method is also public due to another bug, so please 00148 * NEVER EVER call this method directly: use read() instead 00149 */ 00150 bool readMS(ioHandler& handler,const bool complete=true); 00151 00152 /** 00153 * this function is required by MSVC only, as a workaround for a 00154 * very awful bug, which exists since MSVC V.4.0, and still by 00155 * V.6.0 with all bugfixes (so called "service packs") remains 00156 * there... This method is also public due to another bug, so please 00157 * NEVER EVER call this method directly: use write() instead 00158 */ 00159 bool writeMS(ioHandler& handler,const bool complete=true) const; 00160 # endif 00161 00162 // ------------------------------------------------ 00163 // the parameters 00164 // ------------------------------------------------ 00165 00166 /** 00167 * Variance used for the Gaussian kernel used as window for the 00168 * autocorrelation. 00169 * 00170 * Default value : -1 (see lti::gaussKernel1D<float>::generate() for 00171 * the meaning of this) 00172 */ 00173 float variance; 00174 00175 /** 00176 * size of the Gaussian kernel used as window for the autocorrelation 00177 * 00178 * Default value: 7 00179 */ 00180 int kernelSize; 00181 00182 /** 00183 * Maximum number of corners to be detected. 00184 * 00185 * Default value: 300 00186 */ 00187 int maximumCorners; 00188 00189 /** 00190 * Scale factor in Harris auto-correlation 00191 * 00192 * Default value: 0.04f 00193 */ 00194 float scale; 00195 00196 /** 00197 * A localMaxima<float> %functor is used to detect the corners. 00198 * The parameters for it can be given here. 00199 * 00200 * Default value: localMaxima<float>::parameters() 00201 */ 00202 localMaxima<float>::parameters localMaximaParameters; 00203 00204 /** 00205 * In the original work by Harris and Stephens the kernel [-2 -1 00206 * 0 1 2] was used to calculate the gradients in x and y 00207 * directions. However, recently Schmid et al. have found that 00208 * other kernels e.g. derivatives of gaussians can give superior 00209 * results (use OGD for that). To provide maximum flexibility 00210 * the general gradientFunctor is used here. 00211 * 00212 * The gradientFunctor::parameters::format \b must always be set 00213 * to \a Cartesic. This is also default here. 00214 * 00215 * Default gradient type is gradientFunctor::parameters::Harris. 00216 * 00217 * Other values are the default values specified in 00218 * gradientFunctor::parameters. 00219 * 00220 * See also: harrisKernelX 00221 */ 00222 gradientFunctor::parameters gradientFunctorParameters; 00223 }; 00224 00225 /** 00226 * default constructor 00227 */ 00228 harrisCorners(); 00229 00230 /** 00231 * Construct a functor using the given parameters 00232 */ 00233 harrisCorners(const parameters& par); 00234 00235 /** 00236 * copy constructor 00237 * @param other the object to be copied 00238 */ 00239 harrisCorners(const harrisCorners& other); 00240 00241 /** 00242 * destructor 00243 */ 00244 virtual ~harrisCorners(); 00245 00246 /** 00247 * returns the name of this type ("harrisCorners") 00248 */ 00249 virtual const char* getTypeName() const; 00250 00251 /** 00252 * set functor's parameters. 00253 * 00254 * The gradientFunctorParameters are checked for compliancy with 00255 * the definitions above. See 00256 * parameters::gradientFunctorParameters. 00257 * 00258 * This member makes a copy of <em>theParam</em>: the functor 00259 * will keep its own copy of the parameters! 00260 * @return true if successful, false otherwise 00261 */ 00262 virtual bool updateParameters(); 00263 00264 /** 00265 * Read the functor from the given ioHandler. Also sets the 00266 * gradientFunctor parameters. 00267 * 00268 * @param handler the ioHandler to be used 00269 * @param complete if true (the default) the enclosing begin/end will 00270 * be also written, otherwise only the data block will be written. 00271 * @return true if write was successful 00272 */ 00273 virtual bool read(ioHandler& handler,const bool complete=true); 00274 00275 /** 00276 * Extract the corners in srcdest and leave the result there too. 00277 * 00278 * The result is a mask containing only the corners. The background 00279 * will be marked using parameters::noCornerValue and the corners will 00280 * have the value parameters::cornerValue (these are inherited from 00281 * the parent class). 00282 * 00283 * @param srcdest channel8 with the source data. The result 00284 * will be left here too. 00285 * @return true if apply successful or false otherwise. 00286 */ 00287 virtual bool apply(channel8& srcdest) const; 00288 00289 /** 00290 * Extract the corners in srcdest and leave the result there too. 00291 * 00292 * The result is a mask containing only the corners. The background 00293 * will be marked using parameters::noCornerValue/255 and the corners will 00294 * have the value parameters::cornerValue/255 (these are inherited from 00295 * the parent class). 00296 * 00297 * @param srcdest channel with the source data. The result 00298 * will be left here too. 00299 * @return true if apply successful or false otherwise. 00300 */ 00301 virtual bool apply(channel& srcdest) const; 00302 00303 /** 00304 * Extract the corners in src and leave the result in dest. 00305 * 00306 * The result is a mask containing only the corners. The background 00307 * will be marked using parameters::noCornerValue and the corners will 00308 * have the value parameters::cornerValue (these are inherited from 00309 * the parent class). 00310 * 00311 * @param src channel8 with the source data. 00312 * @param dest channel8 where the result will be left. 00313 * @return true if apply successful or false otherwise. 00314 */ 00315 virtual bool apply(const channel8& src,channel8& dest) const; 00316 00317 /** 00318 * Extract the corners in src and leave the result in dest. 00319 * 00320 * The result is a mask containing only the corners. The background 00321 * will be marked using parameters::noCornerValue/255 and the corners will 00322 * have the value parameters::cornerValue/255 (these are inherited from 00323 * the parent class). 00324 * 00325 * @param src channel with the source data. 00326 * @param dest channel where the result will be left. 00327 * @return true if apply successful or false otherwise. 00328 */ 00329 virtual bool apply(const channel& src,channel& dest) const; 00330 00331 /** 00332 * Extract the corners in src and leave them in dest. 00333 * 00334 * @param src channel8 with the source data. 00335 * @param dest list of corners 00336 * @return true if apply successful or false otherwise. 00337 */ 00338 virtual bool apply(const channel8& src,pointList& dest) const; 00339 00340 /** 00341 * Extract the corners in src and leave them in dest. 00342 * 00343 * @param src channel with the source data. 00344 * @param dest list of corners 00345 * @return true if apply successful or false otherwise. 00346 */ 00347 virtual bool apply(const channel& src,pointList& dest) const; 00348 00349 /** 00350 * Extract the cornerness channel belonging to src. 00351 * 00352 * Note that the cornerness is in principle a partial result. 00353 * 00354 * @param src channel with the source data. 00355 * @param cornerness channel containing the cornerness of the source data. 00356 * @param maxCornerness maximum value found in cornerness. 00357 * @param dest list containing the position of all detected corners. 00358 * @return true if apply successful or false otherwise. 00359 */ 00360 virtual bool apply(const channel& src, 00361 channel& cornerness, 00362 float& maxCornerness, 00363 pointList& dest) const; 00364 00365 /** 00366 * Extract the cornerness channel belonging to src. 00367 * 00368 * Note that this is in principle a partial result. It would require 00369 * further processing to get the corners, but some other functors could 00370 * make use of this. 00371 * 00372 * @param src channel with the source data. 00373 * @param cornerness channel containing the cornerness of the source data. 00374 * @param maxCornerness maximum value found in cornerness. 00375 * @return true if apply successful or false otherwise. 00376 */ 00377 virtual bool apply(const channel& src, 00378 channel& cornerness, 00379 float& maxCornerness) const; 00380 00381 /** 00382 * copy data of "other" functor. 00383 * @param other the functor to be copied 00384 * @return a reference to this functor object 00385 */ 00386 harrisCorners& copy(const harrisCorners& other); 00387 00388 /** 00389 * alias for copy member 00390 * @param other the functor to be copied 00391 * @return a reference to this functor object 00392 */ 00393 harrisCorners& operator=(const harrisCorners& other); 00394 00395 /** 00396 * returns a pointer to a clone of this functor. 00397 */ 00398 virtual functor* clone() const; 00399 00400 /** 00401 * returns used parameters 00402 */ 00403 const parameters& getParameters() const; 00404 00405 protected: 00406 00407 /** 00408 * compute the second order. 00409 * 00410 * @param gx contains the gradient in x direction as input and the 00411 * second derivative fxx as output. 00412 * @param gy contains the gradient in y direction as input and the 00413 * second derivative fyy as output. 00414 * @param fxy contains the mixed second derivative as output. 00415 */ 00416 bool getSecondOrder(channel& gx, 00417 channel& gy, 00418 channel& fxy) const; 00419 00420 /** 00421 * compute cornerness 00422 */ 00423 bool getCornerness(const channel& fxx, 00424 const channel& fxy, 00425 const channel& fyy, 00426 const float scale, 00427 channel& cornerness, 00428 float& maxCornerness) const; 00429 00430 /** 00431 * find corners with maximal cornerness 00432 */ 00433 bool findCornerMaxima(const channel& cornerness, 00434 channel& cornersOnly, 00435 pointList& cornerMax) const; 00436 00437 00438 /** 00439 * gradientFunctor used to calculate x and y gradients. 00440 */ 00441 gradientFunctor gradient; 00442 }; 00443 } 00444 00445 #endif