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 .......: ltiHomography9DofEstimator.h 00027 * authors ....: Claudia Goenner 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 14.4.2004 00030 * revisions ..: $Id: ltiHomography9DofEstimator.h,v 1.7 2007/01/10 02:25:57 alvarado Exp $ 00031 */ 00032 00033 #ifndef _LTI_HOMOGRAPHY9_DOF_ESTIMATOR_H_ 00034 #define _LTI_HOMOGRAPHY9_DOF_ESTIMATOR_H_ 00035 00036 #include "ltiHomographyEstimatorBase.h" 00037 #include "ltiHTypes.h" 00038 00039 namespace lti { 00040 00041 /** 00042 * This class computes the parameters of the perspective transformation 00043 * between two images using an homogenous approach and least squares. It 00044 * estimates all 9 parameters of the homography by a svd-composition. 00045 */ 00046 class homography9DofEstimator : public homographyEstimatorBase { 00047 public: 00048 /** 00049 * The parameters for the class homography9DofEstimator 00050 */ 00051 class parameters : public homographyEstimatorBase::parameters { 00052 public: 00053 /** 00054 * Default constructor 00055 */ 00056 parameters(); 00057 00058 /** 00059 * Copy constructor 00060 * @param other the parameters object to be copied 00061 */ 00062 parameters(const parameters& other); 00063 00064 /** 00065 * Destructor 00066 */ 00067 ~parameters(); 00068 00069 /** 00070 * Returns name of this type 00071 */ 00072 const char* getTypeName() const; 00073 00074 /** 00075 * Copy the contents of a parameters object 00076 * @param other the parameters object to be copied 00077 * @return a reference to this parameters object 00078 */ 00079 parameters& copy(const parameters& other); 00080 00081 /** 00082 * Copy the contents of a parameters object 00083 * @param other the parameters object to be copied 00084 * @return a reference to this parameters object 00085 */ 00086 parameters& operator=(const parameters& other); 00087 00088 00089 /** 00090 * Returns a pointer to a clone of the parameters 00091 */ 00092 virtual functor::parameters* clone() const; 00093 00094 /** 00095 * Write the parameters in the given ioHandler 00096 * @param handler the ioHandler to be used 00097 * @param complete if true (the default) the enclosing begin/end will 00098 * be also written, otherwise only the data block will be written. 00099 * @return true if write was successful 00100 */ 00101 virtual bool write(ioHandler& handler,const bool complete=true) const; 00102 00103 /** 00104 * Read the parameters from the given ioHandler 00105 * @param handler the ioHandler to be used 00106 * @param complete if true (the default) the enclosing begin/end will 00107 * be also written, otherwise only the data block will be written. 00108 * @return true if write was successful 00109 */ 00110 virtual bool read(ioHandler& handler,const bool complete=true); 00111 00112 # ifdef _LTI_MSC_6 00113 /** 00114 * This function is required by MSVC only, as a workaround for a 00115 * very awful bug, which exists since MSVC V.4.0, and still by 00116 * V.6.0 with all bugfixes (so called "service packs") remains 00117 * there... This method is also public due to another bug, so please 00118 * NEVER EVER call this method directly: use read() instead 00119 */ 00120 bool readMS(ioHandler& handler,const bool complete=true); 00121 00122 /** 00123 * This function is required by MSVC only, as a workaround for a 00124 * very awful bug, which exists since MSVC V.4.0, and still by 00125 * V.6.0 with all bugfixes (so called "service packs") remains 00126 * there... This method is also public due to another bug, so please 00127 * NEVER EVER call this method directly: use write() instead 00128 */ 00129 bool writeMS(ioHandler& handler,const bool complete=true) const; 00130 # endif 00131 00132 // ------------------------------------------------ 00133 // the parameters 00134 // ------------------------------------------------ 00135 00136 }; 00137 00138 /** 00139 * Default constructor 00140 */ 00141 homography9DofEstimator(); 00142 00143 /** 00144 * Construct a functor using the given parameters 00145 */ 00146 homography9DofEstimator(const parameters& par); 00147 00148 /** 00149 * Copy constructor 00150 * @param other the object to be copied 00151 */ 00152 homography9DofEstimator(const homography9DofEstimator& other); 00153 00154 /** 00155 * Destructor 00156 */ 00157 virtual ~homography9DofEstimator(); 00158 00159 /** 00160 * Returns the name of this type ("homography9DofEstimator") 00161 */ 00162 virtual const char* getTypeName() const; 00163 00164 /** 00165 * Estimates a transform from the supplied point sets, where all 00166 * points are considered. Please implement efficient code using 00167 * iterators here. Not all robust estimators use a random sampling 00168 * approach. Some estimators consider all input points and weight them 00169 * according to their deviation from the transform computed at the prior 00170 * iteration. 00171 * 00172 * All points of one point set give a matrix row, whereas all elements 00173 * of a specifec correspondence stand in a matrix column. 00174 * 00175 * @param src matrix<ipoint> with the point sets. All points of the same 00176 * image stand in a row. The correspondences in another image stand in 00177 * the according columns. 00178 * @param dest fvector the estimated transform. 00179 * @return true if apply successful or false otherwise. 00180 */ 00181 virtual bool apply(const matrix<ipoint>& src, 00182 fvector& dest) const; 00183 00184 /** 00185 * Estimates a transform from the supplied point sets, where all 00186 * points are considered. Usually this method calls the apply without 00187 * the residual first, and then computes the residual. 00188 * 00189 * All points of one point set give a matrix row, whereas all elements 00190 * of a specifec correspondence stand in a matrix column. 00191 * 00192 * @param src matrix<ipoint> with the point sets. All points of the same 00193 * image stand in a row. The correspondences in another image stand in 00194 * the according columns. 00195 * @param dest fvector the estimated transform. 00196 * @param error fvector containing the deviation of each point from the 00197 * estimated transform. Usually this is the residual or 00198 * elementwise squared residual. 00199 * @return true if apply successful or false otherwise. 00200 */ 00201 virtual bool apply(const matrix<ipoint>& src, 00202 fvector& dest, fvector& error) const; 00203 00204 /** 00205 * Estimates a transform from the supplied point sets, whereby only 00206 * the points specified in the index vector are considered. This method 00207 * is used by robost estimators using a monte carlo approach. 00208 * 00209 * All points of one point set give a matrix row, whereas all elements 00210 * of a specifec correspondence stand in a matrix column. 00211 * 00212 * @param src matrix<ipoint> with the point sets. All points of the same 00213 * image stand in a row. The correspondences in another image stand in 00214 * the according columns. 00215 * @param dest fvector the estimated transform. 00216 * @param indices ivector with the indices of the relevant points. 00217 * @param numCorrespondences the first numCorrespondences indices are 00218 * considered. 00219 * @return true if apply successful or false otherwise. 00220 */ 00221 virtual bool apply(const matrix<ipoint>& src, 00222 fvector& dest, 00223 const ivector& indices, 00224 int numCorrespondences) const; 00225 00226 /** 00227 * Estimates a transform from the supplied point sets, whereby only 00228 * the points specified in the index vector are considered. Usually this 00229 * method calls the apply without the residual first, and then computes 00230 * the residual. 00231 * 00232 * All points of one point set give a matrix row, whereas all elements 00233 * of a specifec correspondence stand in a matrix column. 00234 * 00235 * @param src matrix<ipoint> with the point sets. All points of the same 00236 * image stand in a row. The correspondences in another image stand in 00237 * the according columns. 00238 * @param dest fvector the estimated transform. 00239 * @param error fvector containing the deviation of each point from the 00240 * estimated transform. Usually this is the residual or 00241 * elementwise squared residual. 00242 * @param indices ivector with the indices of the relevant points. 00243 * @param numCorrespondences the first numCorrespondences indices are 00244 * considered. 00245 * @return true if apply successful or false otherwise. 00246 */ 00247 virtual bool apply(const matrix<ipoint>& src, 00248 fvector& dest, fvector& error, 00249 const ivector& indices, 00250 int numCorrespondences) const; 00251 00252 /** 00253 * Estimates a transform from the supplied point sets, where all 00254 * points are considered. Please implement efficient code using 00255 * iterators here. Not all robust estimators use a random sampling 00256 * approach. Some estimators consider all input points and weight them 00257 * according to their deviation from the transform computed at the prior 00258 * iteration. 00259 * 00260 * All points of one point set give a matrix row, whereas all elements 00261 * of a specifec correspondence stand in a matrix column. 00262 * 00263 * @param src matrix<fpoint> with the point sets. All points of the same 00264 * image stand in a row. The correspondences in another image stand in 00265 * the according columns. 00266 * @param dest fvector the estimated transform. 00267 * @return true if apply successful or false otherwise. 00268 */ 00269 virtual bool apply(const matrix<fpoint>& src, 00270 fvector& dest) const; 00271 00272 /** 00273 * Estimates a transform from the supplied point sets, where all 00274 * points are considered. Usually this method calls the apply without 00275 * the residual first, and then computes the residual. 00276 * 00277 * All points of one point set give a matrix row, whereas all elements 00278 * of a specifec correspondence stand in a matrix column. 00279 * 00280 * @param src matrix<fpoint> with the point sets. All points of the same 00281 * image stand in a row. The correspondences in another image stand in 00282 * the according columns. 00283 * @param dest fvector the estimated transform. 00284 * @param error fvector containing the deviation of each point from the 00285 * estimated transform. Usually this is the residual or 00286 * elementwise squared residual. 00287 * @return true if apply successful or false otherwise. 00288 */ 00289 virtual bool apply(const matrix<fpoint>& src, 00290 fvector& dest, fvector& error) const; 00291 00292 /** 00293 * Estimates a transform from the supplied point sets, whereby only 00294 * the points specified in the index vector are considered. This method 00295 * is used by robost estimators using a monte carlo approach. 00296 * 00297 * All points of one point set give a matrix row, whereas all elements 00298 * of a specifec correspondence stand in a matrix column. 00299 * 00300 * @param src matrix<fpoint> with the point sets. All points of the same 00301 * image stand in a row. The correspondences in another image stand in 00302 * the according columns. 00303 * @param dest fvector the estimated transform. 00304 * @param indices ivector with the indices of the relevant points. 00305 * @param numCorrespondences the first numCorrespondences indices are 00306 * considered. 00307 * @return true if apply successful or false otherwise. 00308 */ 00309 virtual bool apply(const matrix<fpoint>& src, 00310 fvector& dest, 00311 const ivector& indices, 00312 int numCorrespondences) const; 00313 00314 /** 00315 * Estimates a transform from the supplied point sets, whereby only 00316 * the points specified in the index vector are considered. Usually this 00317 * method calls the apply without the residual first, and then computes 00318 * the residual. 00319 * 00320 * All points of one point set give a matrix row, whereas all elements 00321 * of a specifec correspondence stand in a matrix column. 00322 * 00323 * @param src matrix<fpoint> with the point sets. All points of the same 00324 * image stand in a row. The correspondences in another image stand in 00325 * the according columns. 00326 * @param dest fvector the estimated transform. 00327 * @param error fvector containing the deviation of each point from the 00328 * estimated transform. Usually this is the residual or 00329 * elementwise squared residual. 00330 * @param indices ivector with the indices of the relevant points. 00331 * @param numCorrespondences the first numCorrespondences indices are 00332 * considered. 00333 * @return true if apply successful or false otherwise. 00334 */ 00335 virtual bool apply(const matrix<fpoint>& src, 00336 fvector& dest, fvector& error, 00337 const ivector& indices, 00338 int numCorrespondences) const; 00339 00340 /** 00341 * Estimates a transform from the supplied point sets, where all 00342 * points are considered. Please implement efficient code using 00343 * iterators here. Not all robust estimators use a random sampling 00344 * approach. Some estimators consider all input points and weight them 00345 * according to their deviation from the transform computed at the prior 00346 * iteration. 00347 * 00348 * All points of one point set give a matrix row, whereas all elements 00349 * of a specifec correspondence stand in a matrix column. 00350 * 00351 * @param src matrix<dpoint> with the point sets. All points of the same 00352 * image stand in a row. The correspondences in another image stand in 00353 * the according columns. 00354 * @param dest dvector the estimated transform. 00355 * @return true if apply successful or false otherwise. 00356 */ 00357 virtual bool apply(const matrix<dpoint>& src, 00358 dvector& dest) const; 00359 00360 /** 00361 * Estimates a transform from the supplied point sets, where all 00362 * points are considered. Usually this method calls the apply without 00363 * the residual first, and then computes the residual. 00364 * 00365 * All points of one point set give a matrix row, whereas all elements 00366 * of a specifec correspondence stand in a matrix column. 00367 * 00368 * @param src matrix<dpoint> with the point sets. All points of the same 00369 * image stand in a row. The correspondences in another image stand in 00370 * the according columns. 00371 * @param dest dvector the estimated transform. 00372 * @param error dvector containing the deviation of each point from the 00373 * estimated transform. Usually this is the residual or 00374 * elementwise squared residual. 00375 * @return true if apply successful or false otherwise. 00376 */ 00377 virtual bool apply(const matrix<dpoint>& src, 00378 dvector& dest, dvector& error) const; 00379 00380 /** 00381 * Estimates a transform from the supplied point sets, whereby only 00382 * the points specified in the index vector are considered. This method 00383 * is used by robost estimators using a monte carlo approach. 00384 * 00385 * All points of one point set give a matrix row, whereas all elements 00386 * of a specifec correspondence stand in a matrix column. 00387 * 00388 * @param src matrix<dpoint> with the point sets. All points of the same 00389 * image stand in a row. The correspondences in another image stand in 00390 * the according columns. 00391 * @param dest dvector the estimated transform. 00392 * @param indices ivector with the indices of the relevant points. 00393 * @param numCorrespondences the first numCorrespondences indices are 00394 * considered. 00395 * @return true if apply successful or false otherwise. 00396 */ 00397 virtual bool apply(const matrix<dpoint>& src, 00398 dvector& dest, 00399 const ivector& indices, 00400 int numCorrespondences) const; 00401 00402 /** 00403 * Estimates a transform from the supplied point sets, whereby only 00404 * the points specified in the index vector are considered. Usually this 00405 * method calls the apply without the residual first, and then computes 00406 * the residual. 00407 * 00408 * All points of one point set give a matrix row, whereas all elements 00409 * of a specifec correspondence stand in a matrix column. 00410 * 00411 * @param src matrix<dpoint> with the point sets. All points of the same 00412 * image stand in a row. The correspondences in another image stand in 00413 * the according columns. 00414 * @param dest dvector the estimated transform. 00415 * @param error dvector containing the deviation of each point from the 00416 * estimated transform. Usually this is the residual or 00417 * elementwise squared residual. 00418 * @param indices ivector with the indices of the relevant points. 00419 * @param numCorrespondences the first numCorrespondences indices are 00420 * considered. 00421 * @return true if apply successful or false otherwise. 00422 */ 00423 virtual bool apply(const matrix<dpoint>& src, 00424 dvector& dest, dvector& error, 00425 const ivector& indices, 00426 int numCorrespondences) const; 00427 00428 /** 00429 * Compute the residual for the given correspondences and transformation 00430 * vector. 00431 * @param src matrix<fpoint> with the point sets. All points of the same 00432 * image stand in a row. The correspondences in another image stand in 00433 * the according columns. 00434 * @param transform fvector with the transformation 00435 * @param dest fvector with the residual 00436 * @return true on success and false otherwise. 00437 */ 00438 virtual bool computeResidual(const matrix<fpoint >& src, 00439 const fvector& transform, 00440 fvector& dest) const; 00441 00442 /** 00443 * Compute the residual for the given correspondences and transformation 00444 * vector. 00445 * @param src matrix<dpoint> with the point sets. All points of the same 00446 * image stand in a row. The correspondences in another image stand in 00447 * the according columns. 00448 * @param transform dvector with the transformation 00449 * @param dest dvector with the residual 00450 * @return true on success and false otherwise. 00451 */ 00452 virtual bool computeResidual(const matrix<dpoint >& src, 00453 const dvector& transform, 00454 dvector& dest) const; 00455 00456 /** 00457 * Returns the minimum number of correspondences required to estimate 00458 * the transform. 00459 */ 00460 virtual int minNumberCorrespondences() const; 00461 00462 /** 00463 * Returns the mininum dimension of a correspondence, 00464 * e.g. the minimum dimension of a correspondence pair is 2. 00465 * Each derived transform estimator only works on correspondences of 00466 * priori defined dimensions. 00467 */ 00468 virtual int minCorrespondenceDimension() const; 00469 00470 /** 00471 * Returns the maximum dimension of a correspondence, 00472 * e.g. the maximum dimension of a correspondence pair is 2, whereas 00473 * transformEstimator running on n-tuples may allow an infinite number. 00474 * Each derived transform estimator only works on correspondences of 00475 * priori defined dimensions. 00476 */ 00477 virtual int maxCorrespondenceDimension() const; 00478 00479 /** 00480 * A transform estimated on normalized data usually differs from 00481 * the transform of the original data. Considering the normalization 00482 * performed this methods computes the transform which applies to the 00483 * original data. 00484 * @param srcdest the normalized transform. The result will be left here 00485 * too. 00486 * @param scale a vector containing the scale applied to each point set. 00487 * @param shift a vector containing the shift of each scaled point set. 00488 */ 00489 bool denormalize(fvector& srcdest, 00490 const vector<fpoint>& scale, 00491 const vector<fpoint>& shift) const; 00492 00493 /** 00494 * A transform estimated on normalized data usually differs from 00495 * the transform of the original data. Considering the normalization 00496 * performed this methods computes the transform which applies to the 00497 * original data. 00498 * @param srcdest the normalized transform. The result will be left here 00499 * too. 00500 * @param scale a vector containing the scale applied to each point set. 00501 * @param shift a vector containing the shift of each scaled point set. 00502 */ 00503 bool denormalize(dvector& srcdest, 00504 const vector<dpoint>& scale, 00505 const vector<dpoint>& shift) const; 00506 00507 /** 00508 * Converts the estimated vector into a hMatrix3D<float>, which is e.g. 00509 * used by geometricTransform. 00510 * @param src fvector the estimated transform. 00511 * @param dest hMatrix3D<float> the estimated transform as a hMatrix3D. 00512 * 00513 * @return true if successful or false otherwise. 00514 */ 00515 bool convert(const fvector& src, hMatrix3D<float>& dest) const; 00516 00517 /** 00518 * Converts the estimated vector into a hMatrix3D<float>, which is e.g. 00519 * used by geometricTransform. 00520 * @param src dvector the estimated transform. 00521 * @param dest hMatrix3D<float> the estimated transform as a hMatrix3D. 00522 * 00523 * @return true if successful or false otherwise. 00524 */ 00525 bool convert(const dvector& src, hMatrix3D<float>& dest) const; 00526 00527 /** 00528 * Converts the estimated vector into a 3x3 matrix. 00529 * 00530 * @param src fvector the estimated transform. 00531 * @param dest fmatrix the estimated transform as a matrix. 00532 * 00533 * @return true if successful or false otherwise. 00534 */ 00535 bool convert(const fvector& src, fmatrix& dest) const; 00536 00537 /** 00538 * Converts the estimated vector into a 3x3 matrix. 00539 * 00540 * @param src dvector the estimated transform. 00541 * @param dest dmatrix the estimated transform as a matrix. 00542 * 00543 * @return true if successful or false otherwise. 00544 */ 00545 bool convert(const dvector& src, dmatrix& dest) const; 00546 00547 /** 00548 * This is a fast short cut used by the special robust estimator 00549 * homographyVerification in the main loop. 00550 * @param pt fpoint the point to be transformed 00551 * @param transf fvector with the transformation, which e.g. was computed 00552 * by an apply. 00553 * @return the transformed point 00554 */ 00555 fpoint transform(const fpoint& pt, 00556 const fvector& transf) const; 00557 00558 /** 00559 * This is a fast short cut used in the special robust estimator 00560 * homographyVerification in the main loop. 00561 * @param pt fpoint the point to be transformed 00562 * @param transf fvector with the transformation, which e.g. was computed 00563 * by an apply. 00564 * @return the transformed point 00565 */ 00566 dpoint transform(const dpoint& pt, 00567 const dvector& transf) const; 00568 00569 /** 00570 * Copy data of "other" functor. 00571 * @param other the functor to be copied 00572 * @return a reference to this functor object 00573 */ 00574 homography9DofEstimator& copy(const homography9DofEstimator& other); 00575 00576 /** 00577 * Alias for copy member 00578 * @param other the functor to be copied 00579 * @return a reference to this functor object 00580 */ 00581 homography9DofEstimator& operator=(const homography9DofEstimator& other); 00582 00583 /** 00584 * Returns a pointer to a clone of this functor. 00585 */ 00586 virtual functor* clone() const; 00587 00588 /** 00589 * Returns used parameters 00590 */ 00591 const parameters& getParameters() const; 00592 00593 }; 00594 00595 // ------------------------------------------------------------------- 00596 // The transform-methods! no t-helper due to efficiency here 00597 // ------------------------------------------------------------------- 00598 00599 inline fpoint homography9DofEstimator 00600 ::transform(const fpoint& pt, const fvector& transf) const { 00601 00602 fpoint res; 00603 // fvector::const_iterator it ( transf.begin() ); 00604 // res.x = *it * pt.x + *(++it) * pt.y + *(++it); 00605 // res.y = *(++it) * pt.x + *(++it) * pt.y + *(++it); 00606 res.x = transf.at(0) * pt.x + transf.at(1) * pt.y + transf.at(2); 00607 res.y = transf.at(3) * pt.x + transf.at(4) * pt.y + transf.at(5); 00608 00609 // const float denom ( *(++it) * pt.x + *(++it) * pt.y + *(++it) ); 00610 const float denom (transf.at(6)*pt.x + transf.at(7)*pt.y + transf.at(8)); 00611 res.x /= denom; 00612 res.y /= denom; 00613 00614 return res; 00615 } 00616 00617 inline dpoint homography9DofEstimator 00618 ::transform(const dpoint& pt, const dvector& transf) const { 00619 00620 dpoint res; 00621 // dvector::const_iterator it ( transf.begin() ); 00622 // res.x = *it * pt.x + *(++it) * pt.y + *(++it); 00623 // res.y = *(++it) * pt.x + *(++it) * pt.y + *(++it); 00624 res.x = transf.at(0) * pt.x + transf.at(1) * pt.y + transf.at(2); 00625 res.y = transf.at(3) * pt.x + transf.at(4) * pt.y + transf.at(5); 00626 00627 // const double denom ( *(++it) * pt.x + *(++it) * pt.y + *(++it) ); 00628 const double denom (transf.at(6)*pt.x + transf.at(7)*pt.y + transf.at(8)); 00629 res.x /= denom; 00630 res.y /= denom; 00631 00632 return res; 00633 } 00634 } 00635 00636 #endif