LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiHomography8DofEstimator.h

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

Generated on Sat Apr 10 15:25:39 2010 for LTI-Lib by Doxygen 1.6.1