CVR-Lib last update 20 Sep 2009

cvrAffineTransformation2D.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008
00003  * Pablo Alvarado
00004  *
00005  * This file is part of the Computer Vision and Robotics Library (CVR-Lib )
00006  *
00007  * The CVR-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the BSD License.
00009  *
00010  * All rights reserved.
00011  *
00012  * Redistribution and use in source and binary forms, with or without
00013  * modification, are permitted provided that the following conditions are met:
00014  *
00015  * 1. Redistributions of source code must retain the above copyright notice,
00016  *    this list of conditions and the following disclaimer.
00017  *
00018  * 2. Redistributions in binary form must reproduce the above copyright notice,
00019  *    this list of conditions and the following disclaimer in the documentation
00020  *    and/or other materials provided with the distribution.
00021  *
00022  * 3. Neither the name of the authors nor the names of its contributors may be
00023  *    used to endorse or promote products derived from this software without
00024  *    specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 
00039 /**
00040  * \file   cvrAffineTransformation2D.h
00041  *         Contains the class cvr::affineTransformation2D,
00042  *         which is used to transform coordinate points in a planar
00043  *         transformation with only rotation and translation.
00044  *
00045  * \author Pablo Alvarado
00046  * \date   15.01.2008
00047  *
00048  * revisions ..: $Id: cvrAffineTransformation2D.h,v $
00049  */
00050 
00051 #ifndef _CVR_AFFINE_TRANSFORMATION2_D_H_
00052 #define _CVR_AFFINE_TRANSFORMATION2_D_H_
00053 
00054 
00055 #include "cvrLocation.h"
00056 #include "cvrVector.h"
00057 #include "cvrMatrix.h"
00058 #include "cvrFunctor.h"
00059 #include "cvrSinCos.h"
00060 #include "cvrLinearLeastSquares.h"
00061 #include <vector>
00062 #include <limits>
00063 
00064 namespace cvr {
00065 
00066   /**
00067    * Class affineTransformation2D
00068    *
00069    * The affine transformation for 2D spaces performs a planar
00070    * modification of points in which only rotation, translation, 
00071    * (anisotropic) scaling and sheer are applied.
00072    * 
00073    * With homogeneous coordinates, the affine transformation can be stated as
00074    * \f[
00075    * \begin{bmatrix}
00076    *   x'\\y'\\1
00077    * \end{bmatrix} 
00078    * =
00079    * \begin{bmatrix}
00080    *   a_{00} & a_{01} & t_x \\
00081    *   a_{10} & a_{11} & t_y \\
00082    *   0      & 0      & 1
00083    * \end{bmatrix}
00084    * \begin{bmatrix}
00085    *   x\\y\\1
00086    * \end{bmatrix} 
00087    * \f]
00088    *
00089    * This class transforms points only, and therefore is not intended for
00090    * images, in which case you should use cvr::matrixTransform.  You can
00091    * however obtain from this class the matrix used by
00092    * cvr::matrixTransform::parameters to generate the same results.
00093    *
00094    * Most apply methods are templates of a point type P, i.e. the type P is
00095    * usually a container that can be accessed with the operator[], like
00096    * the types cvr::point<T>, cvr::vector<T>.
00097    *
00098    * @see affineTransformation2D::parameters
00099    * @see euclideanTransformation2D
00100    * @see euclideanTransformation3D
00101    * @see affineTransformation2D
00102    * @see projectiveTransformation2D
00103    *
00104    * @ingroup gGeometricTrans
00105    */
00106   class affineTransformation2D : public functor {
00107   public:
00108     /**
00109      * The parameters for the class affineTransformation2D
00110      */
00111     class parameters : public functor::parameters {
00112     public:
00113       /**
00114        * Default constructor
00115        */
00116       parameters();
00117 
00118       /**
00119        * Copy constructor
00120        * @param other the parameters object to be copied
00121        */
00122       parameters(const parameters& other);
00123 
00124       /**
00125        * Destructor
00126        */
00127       ~parameters();
00128 
00129       /**
00130        * Copy the contents of a parameters object
00131        * @param other the parameters object to be copied
00132        * @return a reference to this parameters object
00133        */
00134       parameters& copy(const parameters& other);
00135 
00136       /**
00137        * Copy the contents of a parameters object
00138        * @param other the parameters object to be copied
00139        * @return a reference to this parameters object
00140        */
00141       parameters& operator=(const parameters& other);
00142 
00143       /**
00144        * Returns the complete name of the parameters class.
00145        */
00146       virtual const std::string& name() const;
00147 
00148       /**
00149        * Returns a pointer to a clone of the parameters.
00150        */
00151       virtual parameters* clone() const;
00152 
00153       /**
00154        * Returns a pointer to a new instance of the parameters.
00155        */
00156       virtual parameters* newInstance() const;
00157 
00158       /**
00159        * Write the parameters in the given ioHandler
00160        * @param handler the ioHandler to be used
00161        * @param complete if true (the default) the enclosing begin/end will
00162        *        be also written, otherwise only the data block will be written.
00163        * @return true if write was successful
00164        */
00165       virtual bool write(ioHandler& handler,const bool complete=true) const;
00166 
00167       /**
00168        * Read the parameters from the given ioHandler
00169        * @param handler the ioHandler to be used
00170        * @param complete if true (the default) the enclosing begin/end will
00171        *        be also written, otherwise only the data block will be written.
00172        * @return true if write was successful
00173        */
00174       virtual bool read(ioHandler& handler,const bool complete=true);
00175 
00176       // ------------------------------------------------
00177       // the parameters
00178       // ------------------------------------------------
00179 
00180       /**
00181        * Magnitude of the translation in x and y directions
00182        *
00183        * Default value: 0
00184        */
00185       fpoint translation;
00186 
00187       /**
00188        * First element of the 2x2 submatrix
00189        *
00190        * Default value: 1
00191        */
00192       float a00;
00193 
00194       /**
00195        * Second element of the 2x2 submatrix
00196        *
00197        * Default value: 0
00198        */
00199       float a01;
00200 
00201       /**
00202        * Third element of the 2x2 submatrix
00203        *
00204        * Default value: 0
00205        */
00206       float a10;
00207 
00208       /**
00209        * Fourth element of the 2x2 submatrix
00210        *
00211        * Default value: 1
00212        */
00213       float a11;
00214 
00215       /**
00216        * Parameters used in the linearLeastSquares functor for
00217        * the estimation tasks.
00218        *
00219        * Default value: default
00220        */
00221       linearLeastSquares::parameters llsParameters;
00222     };
00223 
00224     /**
00225      * Default constructor
00226      */
00227     affineTransformation2D();
00228 
00229     /**
00230      * Construct a functor using the given parameters
00231      */
00232     affineTransformation2D(const parameters& par);
00233 
00234     /**
00235      * Copy constructor
00236      * @param other the object to be copied
00237      */
00238     affineTransformation2D(const affineTransformation2D& other);
00239 
00240     /**
00241      * Destructor
00242      */
00243     virtual ~affineTransformation2D();
00244 
00245     /**
00246      * Transform the given point.
00247      *
00248      * @param srcdest point<T> with the source data. The result
00249      *                will be left here too.
00250      * @return true if apply successful or false otherwise.
00251      */
00252     template<class P>
00253     bool apply(P& srcdest) const;
00254 
00255     /**
00256      * Transform the point \a src and write the transformation on the \a dest
00257      * point.
00258      *
00259      * @param src point<T> with the source data.
00260      * @param dest point<T> where the result will be left.
00261      * @return true if apply successful or false otherwise.
00262      */
00263     template<class P>
00264     bool apply(const P& src, P& dest) const;
00265 
00266     /**
00267      * Estimate a transformation that maps the first set of points into
00268      * the second set of points.
00269      *
00270      * The resulting estimation is left in the parameters.
00271      *
00272      * This method assumes that the corresponding point to setA[idx] is
00273      * stored in setB[idx].
00274      *
00275      * Only the first \c dof()/2 correspondences will be used for the
00276      * estimation, and you need at least \c dof()/2 elements for the
00277      * transformation to be computed.
00278      */
00279     template<class P>
00280     bool estimate(const std::vector<P>& setA,
00281                   const std::vector<P>& setB);
00282 
00283 
00284     /**
00285      * Do a linear least squares error minimization for a transformation that
00286      * maps the first set of points into the second set of points.
00287      *
00288      * The resulting estimation is left in the parameters.
00289      *
00290      * This method assumes that the corresponding point to setA[idx] is
00291      * stored in setB[idx].
00292      *
00293      * For the LLS to be computed, more than \c dof()/2 correspondences are
00294      * necessary for the estimation.
00295      */
00296     template<class P>
00297     bool estimateLLS(const std::vector<P>& setA,
00298                      const std::vector<P>& setB);
00299 
00300 
00301     /**
00302      * Do a linear least squares error minimization for a transformation that
00303      * maps the first set of points into the second set of points.
00304      *
00305      * The resulting estimation is left in the parameters.
00306      *
00307      * This method assumes that the corresponding point to setA[idx] is
00308      * stored in setB[idx].
00309      *
00310      * For the LLS to be computed, more than \c dof()/2 correspondences are
00311      * necessary for the estimation.
00312      *
00313      * For the estimation, just the points with the indices specified in 
00314      * \c selection are given.
00315      *
00316      * @return true if successful, false otherwise
00317      */
00318     template<class P>
00319     bool estimateLLS(const ivector& selection,
00320                      const std::vector<P>& setA,
00321                      const std::vector<P>& setB);
00322 
00323     /**
00324      * Degrees of freedom of the transformation.
00325      *
00326      * Usually this means the minimal number of parameters with which the
00327      * transforamtion matrix can be generated.
00328      */
00329     int dof() const;
00330 
00331     /**
00332      * Generate the transformation matrix that would be required by
00333      * cvr::matrixTransform to generate the same coordinate transformation.
00334      * The result is, so to speak, the matrix representation of the parameters.
00335      *
00336      * This method is provided to keep consistency with other matrix
00337      * transformation functors, since in this case, the conversion between the
00338      * parameters and the matrix is completely straightforward.
00339      *
00340      * @param mat matrix container of the result.
00341      */
00342     void generateMatrix(fmatrix& mat) const;
00343 
00344     /**
00345      * Decompose matrix.
00346      *
00347      * This method decomposes the computed matrix as a series of simpler
00348      * processes.
00349      *
00350      * The affine transformation matrix H is interpreted as the 3x3 matrix
00351      *
00352      * \f[
00353      * H = \begin{bmatrix} A & t \\ 0^T & 1 \end{bmatrix} 
00354      * \f]
00355      *
00356      * where the 2x2 submatrix A can be decomposed as a series of pure
00357      * rotations, and asymmetrical scalations, as follow:
00358      * 
00359      * \f[
00360      * A = R(\theta) R(-\phi) D R(\phi)
00361      * \f]
00362      *
00363      * with
00364      *
00365      * \f[
00366      * D = \begin{bmatrix} \lambda_1 & 0 \\ 0 & \lambda_2 \end{bmatrix} 
00367      * \f]
00368      */
00369     void decompose(float& theta,
00370                    float& phi,
00371                    float& lambda1,
00372                    float& lambda2,
00373                    float& tx,
00374                    float& ty) const;
00375 
00376     /**
00377      * Generate the transformation matrix that would be required by
00378      * cvr::matrixTransform to generate the same coordinate transformation.
00379      * The result is, so to speak, the matrix representation of the parameters.
00380      */
00381     fmatrix generateMatrix() const;
00382 
00383     /**
00384      * Copy data of "other" functor.
00385      * @param other the functor to be copied
00386      * @return a reference to this functor object
00387      */
00388     affineTransformation2D& copy(const affineTransformation2D& other);
00389 
00390     /**
00391      * Alias for copy member
00392      * @param other the functor to be copied
00393      * @return a reference to this functor object
00394      */
00395     affineTransformation2D&
00396     operator=(const affineTransformation2D& other);
00397 
00398     /**
00399      * Returns the complete name of the functor class
00400      */
00401     virtual const std::string& name() const;
00402 
00403     /**
00404      * Returns a pointer to a clone of this functor.
00405      */
00406     virtual affineTransformation2D* clone() const;
00407 
00408     /**
00409      * Returns a pointer to a new instance of this functor.
00410      */
00411     virtual affineTransformation2D* newInstance() const;
00412 
00413     /**
00414      * Returns used parameters
00415      */
00416     const parameters& getParameters() const;
00417 
00418     /**
00419      * Update parameters
00420      */
00421     bool updateParameters();
00422 
00423   protected:
00424 
00425     /**
00426      * Returns used parameters
00427      */
00428     parameters& getRWParameters();
00429 
00430     /**
00431      * Shadow of the translation point
00432      */
00433     fpoint trans_;
00434 
00435     /**
00436      * Shadow of matrix element
00437      */
00438     float a00_;
00439 
00440     /**
00441      * Shadow of matrix element
00442      */
00443     float a01_;
00444 
00445     /**
00446      * Shadow of matrix element
00447      */
00448     float a10_;
00449 
00450     /**
00451      * Shadow of matrix element
00452      */
00453     float a11_;
00454 
00455     /**
00456      * Singular value decomposition
00457      *
00458      * Convenience method to avoid the SVD to be present in the template
00459      * implementation
00460      */
00461     linearLeastSquares lls_;
00462   };
00463 }
00464 
00465 #include "cvrAffineTransformation2D_template.h"
00466 
00467 #endif
00468 

Generated on Sun Sep 20 22:07:58 2009 for CVR-Lib by Doxygen 1.5.8