latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 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 .......: ltiHessianFunctor.h 00027 * authors ....: Peter Doerfler 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 12.3.2004 00030 * revisions ..: $Id: ltiHessianFunctor.h,v 1.7 2006/02/08 11:15:16 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_HESSIAN_FUNCTOR_H_ 00034 #define _LTI_HESSIAN_FUNCTOR_H_ 00035 00036 00037 00038 #include "ltiImage.h" 00039 #include "ltiConvolution.h" 00040 #include "ltiTransform.h" 00041 00042 namespace lti { 00043 /** 00044 * The hessianFunctor calculates three channels from an input channel L: 00045 * 00046 * Lxx, Lxy and Lyy which are the second derivative channels. 00047 * 00048 * The make up the Hessian of each pixel of L like this: 00049 * 00050 * / Lxx(i,j) Lxy(i,j) \ 00051 * H(i,j)= | | 00052 * \ Lxy(i,j) Lyy(i,j) / 00053 * 00054 * See parameters::eKernelType for available kernels. 00055 * 00056 * Corresponding gradient kernels can be found in ltiGradientKernels.h 00057 */ 00058 class hessianFunctor : public transform { 00059 public: 00060 /** 00061 * The parameters for the class hessianFunctor 00062 */ 00063 class parameters : public transform::parameters { 00064 public: 00065 00066 /** 00067 * Possible types of kernels for the computation of the second derivative 00068 */ 00069 enum eKernelType { 00070 Ando, /**< 00071 * convolution of the appropriate optimal gradient kernels 00072 * by Ando (see lti::andoKernelXX) 00073 */ 00074 00075 Sobel, /** 00076 * convolution of Sobel kernels leads to 5x5 00077 * separable kernels (see lti::sobleKernelXX): 00078 * - XX and YY: 00079 * /code 00080 * [ 1 0 -2 0 1] [ 1 4 6 4 1] 00081 * /endcode 00082 * - XY both: 00083 * /code 00084 * [ 1 2 0 -2 -1] 00085 * /endcode 00086 */ 00087 00088 Prewitt, /** 00089 * convolution of Prewitt kernels leads to 5x5 00090 * separable kernels (see lti::prewittKernelXX): 00091 * - XX and YY: 00092 * /code 00093 * [ 1 0 -2 0 1] [ 1 2 3 2 1] 00094 * /endcode 00095 * - XY both: 00096 * /code 00097 * [ 1 1 0 -1 -1] 00098 * /endcode 00099 */ 00100 00101 Harris, /** 00102 * Harris has 1D kernels of length nine for XX and 00103 * YY and a separable 5x5 kernel for XY (see 00104 * lti::harrisKernelXX): 00105 * - XX and YY: 00106 * /code 00107 * [ 4 4 1 -4 -10 -4 1 4 4] [] 00108 * /endcode 00109 * - XY both: 00110 * /code 00111 * [-2 -1 0 1 2] 00112 * /endcode 00113 */ 00114 00115 Robinson, /** 00116 * convolution of Robinson kernels leads to 5x5 00117 * NON-separable kernels (see lti::robinsonKernelXX): 00118 * - XX and YY: 00119 * /code 00120 * +- -+ 00121 * | 1 2 -1 -2 1 | 00122 * | 2 -2 -8 2 2 | 00123 * | 3 0 0 0 3 | 00124 * | 2 -2 -8 2 2 | 00125 * | 1 2 -1 -2 1 | 00126 * +- -+ 00127 * /endcode 00128 * - XY: 00129 * /code 00130 * +- -+ 00131 * | 1 2 1 0 -1 | 00132 * | 2 -2 -4 0 -2 | 00133 * | 1 -4 4 0 -1 | 00134 * | 0 0 0 6 0 | 00135 * | -1 -2 -1 0 -1 | 00136 * +- -+ 00137 * /endcode 00138 */ 00139 00140 Kirsch, /** 00141 * convolution of Kirsch kernels leads to 5x5 00142 * NON-separable kernels (see lti::kirschKernelXX): 00143 * - XX and YY: 00144 * /code 00145 * +- -+ 00146 * | 9 18 -21 -30 25 | 00147 * | 18 18 -51 -30 50 | 00148 * | 27 36 -72 -60 75 | 00149 * | 18 18 -51 -30 50 | 00150 * | 9 18 -21 -30 25 | 00151 * +- -+ 00152 * /endcode 00153 * - XY: 00154 * /code 00155 * +- -+ 00156 * | 9 18 3 -6 -15 | 00157 * | 18 18 -12 -6 -30 | 00158 * | 3 -12 -8 4 -5 | 00159 * | -6 -6 4 34 10 | 00160 * | -15 -30 -5 10 25 | 00161 * +- -+ 00162 * /endcode 00163 */ 00164 00165 OGD2, /** 00166 * Oriented Gaussian Derivative Kernels order 2. See 00167 * lti::ogd2Kernel for description. Remember to set 00168 * kernelSize and kernelVariance appropriately. 00169 */ 00170 00171 Hessian, /** 00172 * Kernels developed by Pablo Alvarado. See 00173 * lti::hessianKernelXX for details. 00174 */ 00175 00176 Classic /** 00177 * Classic kernels for second derivatives. Note that 00178 * no actual kernels but a much faster manual 00179 * implementation is used. The same is used for the 00180 * XY direction of Hessian since the kernel is 00181 * equal. Further, the 'same' kernels are obtained 00182 * by convolution of lti::robertsKernelX and Y and a 00183 * rotation of \f$\pi/4\f$. These are the kernels: 00184 * - XX and YY are 1D: 00185 * /code 00186 * [1 -2 1] 00187 * /endcode 00188 * - XY is 3x3 separable: 00189 * /code 00190 * +- -+ 00191 * | 1 0 -1 | 00192 * | 0 0 0 | 00193 * | -1 0 1 | 00194 * +- -+ 00195 * /endcode 00196 */ 00197 }; 00198 00199 /** 00200 * Default constructor 00201 */ 00202 parameters(); 00203 00204 /** 00205 * Copy constructor 00206 * @param other the parameters object to be copied 00207 */ 00208 parameters(const parameters& other); 00209 00210 /** 00211 * Destructor 00212 */ 00213 ~parameters(); 00214 00215 /** 00216 * Returns name of this type 00217 */ 00218 const char* getTypeName() const; 00219 00220 /** 00221 * Copy the contents of a parameters object 00222 * @param other the parameters object to be copied 00223 * @return a reference to this parameters object 00224 */ 00225 parameters& copy(const parameters& other); 00226 00227 /** 00228 * Copy the contents of a parameters object 00229 * @param other the parameters object to be copied 00230 * @return a reference to this parameters object 00231 */ 00232 parameters& operator=(const parameters& other); 00233 00234 00235 /** 00236 * Returns a pointer to a clone of the parameters 00237 */ 00238 virtual functor::parameters* clone() const; 00239 00240 /** 00241 * Write the parameters in the given ioHandler 00242 * @param handler the ioHandler to be used 00243 * @param complete if true (the default) the enclosing begin/end will 00244 * be also written, otherwise only the data block will be written. 00245 * @return true if write was successful 00246 */ 00247 virtual bool write(ioHandler& handler,const bool complete=true) const; 00248 00249 /** 00250 * Read the parameters from the given ioHandler 00251 * @param handler the ioHandler to be used 00252 * @param complete if true (the default) the enclosing begin/end will 00253 * be also written, otherwise only the data block will be written. 00254 * @return true if write was successful 00255 */ 00256 virtual bool read(ioHandler& handler,const bool complete=true); 00257 00258 # ifdef _LTI_MSC_6 00259 /** 00260 * This function is required by MSVC only, as a workaround for a 00261 * very awful bug, which exists since MSVC V.4.0, and still by 00262 * V.6.0 with all bugfixes (so called "service packs") remains 00263 * there... This method is also public due to another bug, so please 00264 * NEVER EVER call this method directly: use read() instead 00265 */ 00266 bool readMS(ioHandler& handler,const bool complete=true); 00267 00268 /** 00269 * This function is required by MSVC only, as a workaround for a 00270 * very awful bug, which exists since MSVC V.4.0, and still by 00271 * V.6.0 with all bugfixes (so called "service packs") remains 00272 * there... This method is also public due to another bug, so please 00273 * NEVER EVER call this method directly: use write() instead 00274 */ 00275 bool writeMS(ioHandler& handler,const bool complete=true) const; 00276 # endif 00277 00278 // ------------------------------------------------ 00279 // the parameters 00280 // ------------------------------------------------ 00281 00282 /** 00283 * Sets the kernel type used to calculate the second 00284 * derivatives. Most kernels can be found in 00285 * ltiSecondDerivativeKernels.h 00286 */ 00287 eKernelType kernelType; 00288 00289 /** 00290 * This parameter sets the size of the kernel for: 00291 * - the andoKernels (see andoKernelXX). Possible values are 5, 00292 * 7, and 9. 00293 * - ogd2Kernel, any value is possible 00294 * 00295 * Default: 5 00296 */ 00297 int kernelSize; 00298 00299 /** 00300 * The variance for kernels that use the Gaussian. Value -1 sets 00301 * the variance appropriately for the given kernelSize. (see 00302 * e.g. ogd2Kernels) 00303 * 00304 * Default: -1 00305 */ 00306 float kernelVariance; 00307 00308 }; 00309 00310 /** 00311 * Default constructor 00312 */ 00313 hessianFunctor(); 00314 00315 /** 00316 * Construct a functor using the given parameters 00317 */ 00318 hessianFunctor(const parameters& par); 00319 00320 /** 00321 * Copy constructor 00322 * @param other the object to be copied 00323 */ 00324 hessianFunctor(const hessianFunctor& other); 00325 00326 /** 00327 * Destructor 00328 */ 00329 virtual ~hessianFunctor(); 00330 00331 /** 00332 * Returns the name of this type ("hessianFunctor") 00333 */ 00334 virtual const char* getTypeName() const; 00335 00336 /** 00337 * Calculated the second derivatives of the given channel which 00338 * together form the components of the Hessian matrix of each 00339 * pixel. 00340 * 00341 * @param src channel with the source data. 00342 * @param xx second derivative in xx direction. 00343 * @param xy second derivative in xy direction. 00344 * @param yy second derivative in yy direction. 00345 * @return true if apply successful or false otherwise. 00346 */ 00347 bool apply(const channel& src, 00348 channel& xx, channel& xy, channel& yy) const; 00349 00350 /** 00351 * Calculated the second derivatives of the given channel8 which 00352 * together form the components of the Hessian matrix of each 00353 * pixel. \b Note that the channel8 is converted to a channel 00354 * before calculation. 00355 * 00356 * @param src channel8 with the source data. 00357 * @param xx second derivative in xx direction. 00358 * @param xy second derivative in xy direction. 00359 * @param yy second derivative in yy direction. 00360 * @return true if apply successful or false otherwise. 00361 */ 00362 bool apply(const channel8& src, 00363 channel& xx, channel& xy, channel& yy) const; 00364 00365 /** 00366 * Copy data of "other" functor. 00367 * @param other the functor to be copied 00368 * @return a reference to this functor object 00369 */ 00370 hessianFunctor& copy(const hessianFunctor& other); 00371 00372 /** 00373 * Alias for copy member 00374 * @param other the functor to be copied 00375 * @return a reference to this functor object 00376 */ 00377 hessianFunctor& operator=(const hessianFunctor& other); 00378 00379 /** 00380 * Returns a pointer to a clone of this functor. 00381 */ 00382 virtual functor* clone() const; 00383 00384 /** 00385 * Returns used parameters 00386 */ 00387 const parameters& getParameters() const; 00388 00389 /** 00390 * Set parameters. Especially, set the correct kernels. 00391 */ 00392 virtual bool updateParameters(); 00393 00394 protected: 00395 00396 /** 00397 * Used for convolution in x or xx direction 00398 */ 00399 convolution convXX; 00400 00401 /** 00402 * Used for convolution in y or yy direction 00403 */ 00404 convolution convYY; 00405 00406 /** 00407 * Used for convolution in xy direction 00408 */ 00409 convolution convXY; 00410 00411 /** 00412 * Fast calculation of the Hessian with classic kernels [1 -2 1] 00413 * for XX and YY and [1 0 -1; 0 0 0; -1 0 1] for XY. 00414 */ 00415 bool classicHessian(const channel& src, 00416 channel& xx, channel& xy, channel& yy) const; 00417 00418 /** 00419 * Fast computation of the second derivative in XY direction using 00420 * the kernel: 00421 * \code 00422 * 1 0 -1 00423 * 0 0 0 00424 * -1 0 1 00425 * \endcode 00426 * This is used for parameters::Hessian since it is much faster 00427 * than convolution with a very sparse kernel. 00428 */ 00429 bool classicXY(const channel& src, channel& xy) const; 00430 00431 }; 00432 } 00433 00434 #endif