CVR-Lib last update 20 Sep 2009

cvrMatrixTransform.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007
00003  * Pablo Alvarado
00004  *
00005  *
00006  * This file is part of the Computer Vision and Robotics Library (CVR-Lib)
00007  *
00008  * The CVR-Lib is free software; you can redistribute it and/or
00009  * modify it under the terms of the BSD License.
00010  *
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. Neither the name of the authors nor the names of its contributors may be
00024  *    used to endorse or promote products derived from this software without
00025  *    specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 
00041 /**
00042  * \file   cvrMatrixTransform.h
00043  *         Contains the geometric transformation class cvr::matrixTransform<T>
00044  *         which is the more generic linear transformation matrix.
00045  * \author Pablo Alvarado
00046  * \date   08.09.2007
00047  *
00048  * revisions ..: $Id: cvrMatrixTransform.h,v 1.5 2008/01/16 21:52:27 alvarado Exp $
00049  */
00050 
00051 #ifndef _CVR_MATRIX_TRANSFORM_H_
00052 #define _CVR_MATRIX_TRANSFORM_H_
00053 
00054 #include "cvrMatrix.h"
00055 #include "cvrPoint3D.h"
00056 #include "cvrGeometricTransform.h"
00057 
00058 namespace cvr {
00059 
00060   /**
00061    * Global scope function to create a rotation homogeneous matrix for
00062    * 3D spaces, which is always a 4x4 matrix.
00063    *
00064    * The template parameter T represents the type of the matrix entries, which
00065    * has to be a floating point type like double or float.
00066    *
00067    * @ingroup gGeometricTrans
00068    *
00069    * @param center Point in the space that is kept constant
00070    * @param axis Rotation axis.
00071    * @param angle Magnitude of the angle of the rotation
00072    * @return The 4x4 homogeneous matrix representing a 3D rotation.
00073    */
00074   template<typename T>
00075   matrix<T> rotation(const point3D<T>& center,
00076                      const point3D<T>& axis,
00077                      const T& angle);
00078 
00079   /**
00080    * Global scope function to create a rotation homogeneous matrix for
00081    * 2D spaces, which is always a 3x3 matrix.
00082    *
00083    * The template parameter T represents the type of the matrix entries, which
00084    * has to be a floating point type like double or float.
00085    *
00086    * @ingroup gGeometricTrans
00087    *
00088    * @param center Point in the space that is kept constant
00089    * @param angle Magnitude of the angle of the rotation
00090    * @return The 3x3 homogeneous matrix representing a 2D rotation.
00091    */
00092   template<typename T>
00093   matrix<T> rotation(const point<T>& center,
00094                      const T& angle);
00095 
00096   /**
00097    * Global scope function to create a shift homogeneous matrix in a
00098    * 3D space, which is always 4x4.
00099    *
00100    * The matrix created has the form
00101    *
00102    * \f[
00103    * \begin{bmatrix}
00104    *   1 & 0 & 0   & s_x \\
00105    *   0 & 1 & 0   & s_y \\
00106    *   0 & 0 & 1   & s_z \\
00107    *   0 & 0 & 0   & 1
00108    * \end{bmatrix}
00109    * \f]
00110    *
00111    * The template parameter T represents the type of the matrix entries, which
00112    * has to be a floating point type like double or float.
00113    *
00114    * @ingroup gGeometricTrans
00115    *
00116    * @param s Shift amount.
00117    * @return The 4x4 homogeneous matrix representing a 3D shift.
00118    */
00119   template<typename T>
00120   matrix<T> translation(const point3D<T>& s);
00121 
00122   /**
00123    * Global scope function to create a shift homogeneous matrix for
00124    * 2D spaces, which is always a 3x3 matrix.
00125    *
00126    * The matrix created has the form
00127    *
00128    * \f[
00129    * \begin{bmatrix}
00130    *   1 & 0 & s_x \\
00131    *   0 & 1 & s_y \\
00132    *   0 & 0 & 1 \\
00133    * \end{bmatrix}
00134    * \f]
00135    *
00136    * The template parameter T represents the type of the matrix entries, which
00137    * has to be a floating point type like double or float.
00138    *
00139    * @ingroup gGeometricTrans
00140    *
00141    * @param s Shift amount.
00142    * @return The 3x3 homogeneous matrix representing a 2D shift.
00143    */
00144   template<typename T>
00145   matrix<T> translation(const point<T>& s);
00146 
00147   /**
00148    * Global scope function to create a homogeneous matrix for scaling in
00149    * 3D spaces.
00150    *
00151    * The matrix created has the form
00152    *
00153    * \f[
00154    * \begin{bmatrix}
00155    *   s_x & 0 & 0   & 0 \\
00156    *   0 & s_y & 0   & 0 \\
00157    *   0 & 0   & s_z & 0 \\
00158    *   0 & 0   & 0   & 1
00159    * \end{bmatrix}
00160    * \f]
00161    *
00162    * The template parameter T represents the type of the matrix entries, which
00163    * has to be a floating point type like double or float.
00164    *
00165    * @ingroup gGeometricTrans
00166    *
00167    * @param s Scale amount in each axis.
00168    * @return The 4x4 homogeneous matrix representing a 3D scale
00169    */
00170   template<typename T>
00171   matrix<T> scaling(const point3D<T>& s);
00172 
00173   /**
00174    * Global scope function to create a homogeneous matrix for scaling in
00175    * 2D spaces.
00176    *
00177    * The matrix created has the form
00178    *
00179    * \f[
00180    * \begin{bmatrix}
00181    *   s_x & 0   & 0 \\
00182    *   0   & s_y & 0 \\
00183    *   0   & 0   & 1
00184    * \end{bmatrix}
00185    * \f]
00186    *
00187    * The template parameter T represents the type of the matrix entries, which
00188    * has to be a floating point type like double or float.
00189    *
00190    * @ingroup gGeometricTrans
00191    *
00192    * @param s Scale amount in each axis.
00193    * @return The 3x3 homogeneous matrix representing a 2D scale
00194    */
00195   template<typename T>
00196   matrix<T> scaling(const point<T>& s);
00197 
00198   /**
00199    * Global scope function to create a homogeneous projection matrix, with
00200    * a focal distance f.
00201    *
00202    * The matrix created has the form
00203    *
00204    * \f[
00205    * \begin{bmatrix}
00206    *   1 & 0 & 0   & 0 \\
00207    *   0 & 1 & 0   & 0 \\
00208    *   0 & 0 & 1   & 0 \\
00209    *   0 & 0 & 1/f & 1
00210    * \end{bmatrix}
00211    * \f]
00212    *
00213    * The template parameter T represents the type of the matrix entries, which
00214    * has to be a floating point type like double or float.
00215    *
00216    * @ingroup gGeometricTrans
00217    *
00218    * @param f focal distance.
00219    * @return The 4x4 homogeneous matrix representing a 3D scale
00220    */
00221   template<typename T>
00222   matrix<T> projection(const T& f);
00223 
00224   /**
00225    * Class matrixTransform.
00226    *
00227    * This is a template class, used to geometrically transform an image using a
00228    * linear transformation expressed through a matrix.
00229    *
00230    * \section suptrans Supported transformations.
00231    *
00232    * The transformation matrix is provided in the parameters.  It has to be
00233    * invertible, and has to have a size of 2x2, 2x3, 3x3, 4x4 or 4x3.
00234    *
00235    * \subsection m2x2 Simple 2x2 transformation matrix
00236    *
00237    * The 2x2 transformation matrix transforms a pixel at \f$(x,y)\f$
00238    * into a pixel \f$(x',y')\f$ with the following convention:
00239    * \f[
00240    *   \begin{bmatrix}
00241    *     x' \\ y'
00242    *   \end{bmatrix}
00243    *   =
00244    *   \begin{bmatrix}
00245    *     m_{0,0} & m_{0,1} \\
00246    *     m_{1,0} & m_{1,1}
00247    *   \end{bmatrix}
00248    *   \begin{bmatrix}
00249    *     x \\ y
00250    *   \end{bmatrix}
00251    *   =
00252    *   \begin{bmatrix}
00253    *     m_{0,0}x + m_{0,1}y \\
00254    *     m_{1,0}x + m_{1,1}y
00255    *   \end{bmatrix}
00256    * \f]
00257    *
00258    * It is usefull for rotation and scaling operations.
00259    *
00260    * \subsection m2x3 2x3 transformation matrix
00261    *
00262    * The 2x3 transformation matrix uses homogeneous coordinates to
00263    * transform a pixel at \f$(x,y)\f$ into a pixel \f$(x',y')\f$ with
00264    * the following convention:
00265    * \f[
00266    *   \begin{bmatrix}
00267    *     x' \\ y'
00268    *   \end{bmatrix}
00269    *   =
00270    *   \begin{bmatrix}
00271    *     m_{0,0} & m_{0,1} & m_{0,2}\\
00272    *     m_{1,0} & m_{1,1} & m_{1,2}
00273    *   \end{bmatrix}
00274    *   \begin{bmatrix}
00275    *     x \\ y \\ 1
00276    *   \end{bmatrix}
00277    *   =
00278    *   \begin{bmatrix}
00279    *     m_{0,0}x + m_{0,1}y + m_{0,2} \\
00280    *     m_{1,0}x + m_{1,1}y + m_{1,2}
00281    *   \end{bmatrix}
00282    * \f]
00283    *
00284    * It is usefull for rotation, scaling and translation operations.
00285    *
00286    * \subsection m3x3 3x3 transformation matrix
00287    *
00288    * The 3x3 transformation matrix uses homogeneous coordinates to
00289    * transform a pixel at \f$(x,y)\f$ into a pixel \f$(x',y')\f$ with
00290    * the following convention:
00291    * \f[
00292    *   \begin{bmatrix}
00293    *     x'' \\ y'' \\ \alpha
00294    *   \end{bmatrix}
00295    *   =
00296    *   \begin{bmatrix}
00297    *     m_{0,0} & m_{0,1} & m_{0,2}\\
00298    *     m_{1,0} & m_{1,1} & m_{1,2}\\
00299    *     m_{2,0} & m_{2,1} & m_{2,2}
00300    *   \end{bmatrix}
00301    *   \begin{bmatrix}
00302    *     x \\ y \\ 1
00303    *   \end{bmatrix}
00304    *   =
00305    *   \begin{bmatrix}
00306    *     m_{0,0}x + m_{0,1}y + m_{0,2} \\
00307    *     m_{1,0}x + m_{1,1}y + m_{1,2} \\
00308    *     m_{2,0}x + m_{2,1}y + m_{2,2}
00309    *   \end{bmatrix}
00310    * \f]
00311    *
00312    * The point \f$(x',y')\f$ is obtained with
00313    * \f$(x',y') = (x''/\alpha,y''/\alpha)\f$
00314    *
00315    * It can be used for rotation, scaling and translation operations, but using
00316    * the third line, more interesting mappings can be achieved.
00317    *
00318    * \subsection m3x4 3x4 transformation matrix
00319    *
00320    * The 3x4 transformation matrix uses homogeneous coordinates to
00321    * transform a pixel at \f$(x,y)\f$ into a pixel \f$(x',y')\f$ with
00322    * the following convention:
00323    * \f[
00324    *   \begin{bmatrix}
00325    *     x'' \\ y'' \\ \alpha
00326    *   \end{bmatrix}
00327    *   =
00328    *   \begin{bmatrix}
00329    *     m_{0,0} & m_{0,1} & m_{0,2} & m_{0,3}\\
00330    *     m_{1,0} & m_{1,1} & m_{1,2} & m_{1,3}\\
00331    *     m_{2,0} & m_{2,1} & m_{2,2} & m_{2,3}
00332    *   \end{bmatrix}
00333    *   \begin{bmatrix}
00334    *     x \\ y \\ 0 \\ 1
00335    *   \end{bmatrix}
00336    *   =
00337    *   \begin{bmatrix}
00338    *     m_{0,0}x + m_{0,1}y + m_{0,3} \\
00339    *     m_{1,0}x + m_{1,1}y + m_{1,3} \\
00340    *     m_{2,0}x + m_{2,1}y + m_{2,3}
00341    *   \end{bmatrix}
00342    * \f]
00343    *
00344    * The point \f$(x',y')\f$ is obtained with
00345    * \f$(x',y') = (x''/\alpha,y''/\alpha)\f$.
00346    *
00347    * It can be used for rotation, scaling and translation operations, but using
00348    * the third line, more interesting mappings can be achieved.
00349    *
00350    * Please note that this configuration is in principle equivalent to
00351    * a 3x3 matrix, as the third column is "absorved" by the z=0
00352    * assumption for the pixel positions on the image plane.
00353    *
00354    * \subsection m4x4 4x4 transformation matrix
00355    *
00356    * The 4x4 transformation matrix uses homogeneous coordinates to
00357    * transform a pixel at \f$(x,y)\f$ into a pixel \f$(x',y')\f$ with
00358    * the following convention:
00359    * \f[
00360    *   \begin{bmatrix}
00361    *     x'' \\ y'' \\ z'' \\ \alpha
00362    *   \end{bmatrix}
00363    *   =
00364    *   \begin{bmatrix}
00365    *     m_{0,0} & m_{0,1} & m_{0,2} & m_{0,3}\\
00366    *     m_{1,0} & m_{1,1} & m_{1,2} & m_{1,3}\\
00367    *     m_{2,0} & m_{2,1} & m_{2,2} & m_{2,3}\\
00368    *     m_{3,0} & m_{3,1} & m_{3,2} & m_{3,3}
00369    *   \end{bmatrix}
00370    *   \begin{bmatrix}
00371    *     x \\ y \\ 0 \\ 1
00372    *   \end{bmatrix}
00373    *   =
00374    *   \begin{bmatrix}
00375    *     m_{0,0}x + m_{0,1}y + m_{0,3} \\
00376    *     m_{1,0}x + m_{1,1}y + m_{1,3} \\
00377    *     m_{2,0}x + m_{2,1}y + m_{2,3} \\
00378    *     m_{3,0}x + m_{3,1}y + m_{3,3} \\
00379    *   \end{bmatrix}
00380    * \f]
00381    *
00382    * The point \f$(x',y')\f$ is obtained with
00383    * \f$(x',y') = (x''/\alpha,y''/\alpha)\f$.
00384    *
00385    * It can be used for rotation, scaling and translation operations,
00386    * but using the z coordinates, more interesting mappings can be
00387    * achieved, like perspective projections.
00388    *
00389    * \subsection m4x3 4x3 transformation matrix
00390    *
00391    * The 4x3 transformation matrix uses homogeneous coordinates to
00392    * transform a pixel at \f$(x,y)\f$ into a pixel \f$(x',y')\f$ with
00393    * the following convention:
00394    * \f[
00395    *   \begin{bmatrix}
00396    *     x'' \\ y'' \\ z'' \\ \alpha
00397    *   \end{bmatrix}
00398    *   =
00399    *   \begin{bmatrix}
00400    *     m_{0,0} & m_{0,1} & m_{0,2}\\
00401    *     m_{1,0} & m_{1,1} & m_{1,2}\\
00402    *     m_{2,0} & m_{2,1} & m_{2,2}\\
00403    *     m_{3,0} & m_{3,1} & m_{3,2}
00404    *   \end{bmatrix}
00405    *   \begin{bmatrix}
00406    *     x \\ y \\ 1
00407    *   \end{bmatrix}
00408    *   =
00409    *   \begin{bmatrix}
00410    *     m_{0,0}x + m_{0,1}y + m_{0,2} \\
00411    *     m_{1,0}x + m_{1,1}y + m_{1,2} \\
00412    *     m_{2,0}x + m_{2,1}y + m_{2,2} \\
00413    *     m_{3,0}x + m_{3,1}y + m_{3,2} \\
00414    *   \end{bmatrix}
00415    * \f]
00416    *
00417    * The point \f$(x',y')\f$ is obtained with
00418    * \f$(x',y') = (x''/\alpha,y''/\alpha)\f$.
00419    *
00420    * It can be used for rotation, scaling and translation operations,
00421    * but using the z coordinates, more interesting mappings can be
00422    * achieved, like perspective projections.
00423 
00424    * \section mtexam Example
00425    *
00426    * The following example rotates an image on the axis parallel to
00427    * the y axis but passing through the middle of the image.
00428    *
00429    * \code
00430    *   // type definitions just for shorter names.
00431    *   typedef cvr::nearestNeighborInterpolation<cvr::rgbaPixel> inter_type;
00432    *   typedef cvr::matrixTransform< inter_type > trans_type;
00433    *   trans_type transformer;
00434    *
00435    *   // get an image to work with
00436    *   cvr::ioImage loader;
00437    *   cvr::viewer2D view("Image");
00438    *   cvr::image img,img2;
00439    *   if (!loader.load("../img/testImg.bmp",img)) {
00440    *     std::cout << loader.getStatusString() << std::endl;
00441    *     exit(1);
00442    *   }
00443    *
00444    *   cvr::fmatrix mat,pro;
00445    *
00446    *   // generate a projection matrix to give a perspective effect
00447    *   pro = cvr::projection(1000.0f);
00448    *
00449    *   cvr::ipoint o = img.size()/2;
00450    *
00451    *   // animation of 360 images rotated.
00452    *   for (int deg=0;deg<=360;++deg) {
00453    *     float rad=degToRad(static_cast<float>(deg)); // angle in radians
00454    *
00455    *     // generate a transformation matrix using several elemental operations
00456    *     mat =
00457    *       cvr::translation(fpoint3D(o.x,o.y,0)) *
00458    *       pro *
00459    *       cvr::rotation(fpoint3D(0.0f,0.0f,0.0f),fpoint3D(1,0,0),rad) *
00460    *       cvr::translation(fpoint3D(-o.x,-o.y,0));
00461    *
00462    *       transformer.setMatrix(mat);
00463    *       transformer.apply(img,img2);
00464    *
00465    *       view.show(img2);
00466    *   }
00467    * \endcode
00468    *
00469    * \section tparams Template parameter
00470    *
00471    * The template parameter I indicates the interpolator type to be used.
00472    * The class provided must be inherited from cvr::fixedGridInterpolation.
00473    * Note that the interpolator works for one type of containers only, and
00474    * only that type will be supported by this class too.
00475    *
00476    * @see matrixTransform<I>::parameters.
00477    *
00478    * @ingroup gGeometricTrans
00479    */
00480   template<class I>
00481   class matrixTransform : public geometricTransform<I> {
00482   public:
00483     typedef I interpolator_type;
00484     typedef typename I::value_type value_type;
00485 
00486     /**
00487      * The parameters for the class matrixTransform<T>
00488      */
00489     class parameters : public geometricTransform<I>::parameters {
00490     public:
00491       /**
00492        * Default constructor
00493        */
00494       parameters();
00495 
00496       /**
00497        * Copy constructor
00498        * @param other the parameters object to be copied
00499        */
00500       parameters(const parameters& other);
00501 
00502       /**
00503        * Destructor
00504        */
00505       ~parameters();
00506 
00507       /**
00508        * Copy the contents of a parameters object
00509        * @param other the parameters object to be copied
00510        * @return a reference to this parameters object
00511        */
00512       parameters& copy(const parameters& other);
00513 
00514       /**
00515        * Copy the contents of a parameters object
00516        * @param other the parameters object to be copied
00517        * @return a reference to this parameters object
00518        */
00519       parameters& operator=(const parameters& other);
00520 
00521       /**
00522        * Returns the complete name of the parameters class.
00523        */
00524       virtual const std::string& name() const;
00525 
00526       /**
00527        * Returns a pointer to a clone of the parameters.
00528        */
00529       virtual parameters* clone() const;
00530 
00531       /**
00532        * Returns a pointer to a new instance of the parameters.
00533        */
00534       virtual parameters* newInstance() const;
00535 
00536       /**
00537        * Write the parameters in the given ioHandler
00538        * @param handler the ioHandler to be used
00539        * @param complete if true (the default) the enclosing begin/end will
00540        *        be also written, otherwise only the data block will be written.
00541        * @return true if write was successful
00542        */
00543       virtual bool write(ioHandler& handler,const bool complete=true) const;
00544 
00545       /**
00546        * Read the parameters from the given ioHandler
00547        * @param handler the ioHandler to be used
00548        * @param complete if true (the default) the enclosing begin/end will
00549        *        be also written, otherwise only the data block will be written.
00550        * @return true if write was successful
00551        */
00552       virtual bool read(ioHandler& handler,const bool complete=true);
00553 
00554       // ------------------------------------------------
00555       // the parameters
00556       // ------------------------------------------------
00557       /**
00558        * Transformation matrix
00559        *
00560        * The transformation matrix have to be invertible, and need to have
00561        * size 2x2, 2x3, 3x3, 4x4 or 4x3.
00562        *
00563        * Default value: 2x2 identity matrix
00564        */
00565       fmatrix transformation;
00566     };
00567 
00568     /**
00569      * Default constructor
00570      */
00571     matrixTransform();
00572 
00573     /**
00574      * Construct a functor using the given parameters
00575      */
00576     matrixTransform(const parameters& par);
00577 
00578     /**
00579      * Copy constructor
00580      * @param other the object to be copied
00581      */
00582     matrixTransform(const matrixTransform<I>& other);
00583 
00584     /**
00585      * Destructor
00586      */
00587     virtual ~matrixTransform();
00588 
00589     /**
00590      * Transform geometrically the given image and leave the result on the
00591      * same container.
00592      *
00593      * @param srcdest matrix<T> with the source data. The result
00594      *                will be left here too.
00595      * @return true if apply successful or false otherwise.
00596      */
00597     virtual bool apply(matrix<value_type>& srcdest) const;
00598 
00599     /**
00600      * Transform geometrically the source image and leave the result on the
00601      * destination container.
00602      *
00603      * Operates on a copy of the given %parameters.
00604      *
00605      * @param src matrix<value_type> with the source data.
00606      * @param dest matrix<value_type> where the result will be left.
00607      * @return true if apply successful or false otherwise.
00608      */
00609     virtual bool apply(const matrix<value_type>& src,
00610                              matrix<value_type>& dest) const;
00611 
00612     /**
00613      * Transform geometrically the given image and leave the result on the
00614      * same container.
00615      *
00616      * If the parameters specify to AdjustDimensions, then the offset
00617      * value will contain the relative position of the \a srcdest
00618      * origin with respect to the original image coordinate system.
00619      * To all other resize policies, the value of offset is set to
00620      * (0,0).
00621      *
00622      * If you need to find out where in the rotated image is located the origin
00623      * of the initial image, then that would be in -offset.
00624      *
00625      * @param srcdest matrix<T> with the source data. The result
00626      *                will be left here too.
00627      * @param offset position of the origin of the result with respect to the
00628      *               coordinate system of the original image.
00629      * @return true if apply successful or false otherwise.
00630      */
00631     virtual bool apply(matrix<value_type>& srcdest,
00632                        fpoint& offset) const;
00633 
00634     /**
00635      * Transform geometrically the source image and leave the result on the
00636      * destination container.
00637      *
00638      *
00639      * If the parameters specify to AdjustDimensions, then the offset
00640      * value will contain the relative position of the \a dest
00641      * origin with respect to the original image coordinate system.
00642      * To all other resize policies, the value of offset is set to
00643      * (0,0).
00644      *
00645      * If you need to find out where in the rotated image is located the origin
00646      * of the initial image, then that would be in -offset.
00647      *
00648      * @param src matrix<value_type> with the source data.
00649      * @param dest matrix<value_type> where the result will be left.
00650      * @param offset position of the origin of the result with respect to the
00651      *               coordinate system of the original image.
00652      * @return true if apply successful or false otherwise.
00653      */
00654     virtual bool apply(const matrix<value_type>& src,
00655                              matrix<value_type>& dest,
00656                              fpoint& offset) const;
00657 
00658     /**
00659      * @name Point transformation tools
00660      *
00661      * The following tools permit to transform individual points, which is
00662      * useful when looking for the direct and inverse transformations of
00663      * particular pixels.
00664      *
00665      * Before using any of this methods you MUST call the use() method first,
00666      * in order for this class to know in what context it has to work, i.e.,
00667      * since the position of a pixel in the transformed matrix depends entirely
00668      * on the dimension of the original image and the parameter settings, the
00669      * use() method precomputes everything necessary to later transform each
00670      * pixel more efficiently.
00671      */
00672     //@{
00673 
00674     /**
00675      * Provide the size of the matrix from which it will be assumed the
00676      * positions will be taken.
00677      *
00678      * @param size Size of the matrix from which the positions will be analyzed
00679      * @return \c true if everything is ok, or  \c false if the matrix set in
00680      *         the parameters is not invertible or some other weird problem.
00681      */
00682     bool use(const ipoint& size);
00683 
00684     /**
00685      * Transform the given point coordinates.
00686      *
00687      * \warning Do not forget to provide first the size of the matrix
00688      *          from which the points are going to be taken, using
00689      *          use(const ipoint&).
00690      *
00691      * This method takes the orig position, assumed to be in a reference system
00692      * of a matrix/image of the size given by the use(const ipoint&) method,
00693      * and transforms this position according to the set parameters.
00694      */
00695     void forwards(const fpoint& orig,
00696                         fpoint& dest) const;
00697 
00698 
00699     /**
00700      * Inverse transform the given point coordinates.
00701      *
00702      * \warning Do not forget to provide first the size of the matrix
00703      *          from which the points are going to be taken, using
00704      *          use(const ipoint&).
00705      *
00706      * This method is the inverse of forwards(const fpoint&,fpoint&).  Given a
00707      * position \c dest in the transformed system, it computes the coordinates
00708      * of that point in the original coordinate system.
00709      *
00710      * @param dest Position of a point in the transformed space.
00711      * @param orig Position of the point in the original space.
00712      */
00713     void backwards(const fpoint& dest,
00714                          fpoint& orig) const;
00715 
00716     //@}
00717 
00718     /**
00719      * Copy data of "other" functor.
00720      * @param other the functor to be copied
00721      * @return a reference to this functor object
00722      */
00723     matrixTransform& copy(const matrixTransform<I>& other);
00724 
00725     /**
00726      * Alias for copy member
00727      * @param other the functor to be copied
00728      * @return a reference to this functor object
00729      */
00730     matrixTransform& operator=(const matrixTransform<I>& other);
00731 
00732     /**
00733      * Returns the complete name of the functor class
00734      */
00735     virtual const std::string& name() const;
00736 
00737     /**
00738      * Returns a pointer to a clone of this functor.
00739      */
00740     virtual matrixTransform<I>* clone() const;
00741 
00742     /**
00743      * Returns a pointer to a new instance of this functor.
00744      */
00745     virtual matrixTransform<I>* newInstance() const;
00746 
00747     /**
00748      * Returns used parameters
00749      */
00750     const parameters& getParameters() const;
00751 
00752     /**
00753      * Update functor state on a parameters change
00754      */
00755     virtual bool updateParameters();
00756 
00757     /**
00758      * Shortcut for setting the transformation matrix without changing
00759      * the rest of the parameters.
00760      *
00761      * The matrix has to have valid dimensions: 2x2, 2x3, 3x3, 4x4 or 4x3.
00762      */
00763     bool setMatrix(const fmatrix& transMat);
00764 
00765   protected:
00766 
00767     /**
00768      * Returns used parameters
00769      */
00770     parameters& getParameters();
00771 
00772     /**
00773      * Base class of helpers
00774      *
00775      * This is the parent class of all helper classes, each one
00776      * designed to optimize the computation of the transformation for
00777      * a particular matrix size.
00778      */
00779     class helperBase {
00780     public:
00781       /**
00782        * The only available constructor forces to provide the
00783        * interpolator of the enclosing class, which is inherited from the
00784        * geometricTransform class.
00785        */
00786       helperBase(interpolator_type& interp,const parameters& par);
00787 
00788       /**
00789        * Virtual destructor
00790        */
00791       virtual ~helperBase();
00792 
00793       /**
00794        * Analyze the matrix in the parameters and compute its inverse.
00795        * If the matrix is not invertible, then return false.
00796        */
00797       virtual bool analyzeMatrix() = 0;
00798 
00799       /**
00800        * Transform an image according to the matrix provided in the parameters.
00801        *
00802        * The offset provides information of the coordinate values of
00803        * the resulting image with respect to the coordinate system of
00804        * the original image.  Of course, this will be (0,0) if
00805        * KeepDimensions or KeepOrigin are chosen in the parameter.
00806        *
00807        * If you need to find out where in the rotated image is located the
00808        * origin of the initial image, then that would be in -offset.
00809        *
00810        * @param src    original image
00811        * @param dest   transformed image
00812        * @param offset coordinate in the original reference system of the
00813        *               new image pixel (0,0).
00814        */
00815       virtual bool apply(const matrix<value_type>& src,
00816                                matrix<value_type>& dest,
00817                                fpoint& offset) const = 0;
00818 
00819       /**
00820        * Transform the given point coordinates.
00821        *
00822        * \warning Do not forget to provide first the size of the matrix
00823        *          from which the points are going to be taken, using
00824        *          use(const ipoint&).
00825        *
00826        * This method takes the orig position, assumed to be in a reference
00827        * system of a matrix/image of the size given by the use(const ipoint&)
00828        * method, and transforms this position according to the set parameters.
00829        */
00830       virtual void forwards(const fpoint& orig,
00831                             fpoint& dest,
00832                             const fpoint& offset) const=0;
00833 
00834 
00835       /**
00836        * Inverse transform the given point coordinates.
00837        *
00838        * \warning Do not forget to provide first the size of the matrix
00839        *          from which the points are going to be taken, using
00840        *          use(const ipoint&).
00841        *
00842        * This method is the inverse of forwards(const fpoint&,fpoint&).  Given a
00843        * position \c dest in the transformed system, it computes the
00844        * coordinates of that point in the original coordinate system.
00845        *
00846        * @param dest Position of a point in the transformed space.
00847        * @param orig Position of the point in the original space.
00848        * @param offset Position of the origin of the result with respect to the
00849        *               coordinate system of the original image.
00850        */
00851       virtual void backwards(const fpoint& dest,
00852                              fpoint& orig,
00853                              const fpoint& offset) const=0;
00854 
00855 
00856       /**
00857        * After the matrix has been analyzed, this method can be used to
00858        * compute the dimensions of the resulting image and the offset.
00859        *
00860        * If you need to find out where in the rotated image is located the
00861        * origin of the initial image, then that would be in -offset.
00862        *
00863        * Usually, this method just need to compute the coordinates of
00864        * the corners internally, optimizing the computation according to the
00865        * matrix employed, followed by a call the the getDimsFromCorners().
00866        */
00867       virtual bool evalDims(const ipoint& orig,
00868                                   ipoint& res,
00869                                   fpoint& offset) const = 0;
00870 
00871     protected:
00872       /**
00873        * Reference to the interpolator object
00874        */
00875       const interpolator_type& interpolator_;
00876 
00877       /**
00878        * Reference to the parameter objects
00879        */
00880       const parameters& params_;
00881 
00882       /**
00883        * From the transformed coordinates of the corners, compute the
00884        * result image dimension and the offset of the origin of that
00885        * image.
00886        *
00887        * If you need to find out where in the rotated image is located the
00888        * origin of the initial image, then that would be in -offset.
00889        *
00890        * Returns true if the image size is possible or false if the required
00891        * size is negative (can happen for KeepOrigin).
00892        */
00893       bool getDimsFromCorners(const fpoint& tl,
00894                               const fpoint& tr,
00895                               const fpoint& bl,
00896                               const fpoint& br,
00897                               ipoint& dim,
00898                               fpoint& offset) const;
00899 
00900     };
00901 
00902     /**
00903      * Helper for 2x2 matrix transformations
00904      */
00905     class helper2x2 : public helperBase {
00906     public:
00907      /**
00908        * The only available constructor.
00909        */
00910       helper2x2(interpolator_type& interp,const parameters& par);
00911 
00912       /**
00913        * Virtual destructor
00914        */
00915       virtual ~helper2x2();
00916 
00917       /**
00918        * Analyze the matrix in the parameters and compute its inverse.
00919        * If the matrix is not invertible, then return false.
00920        */
00921       virtual bool analyzeMatrix();
00922 
00923       /**
00924        * Transform an image according to the matrix provided in the parameters
00925        */
00926       virtual bool apply(const matrix<value_type>& src,
00927                                matrix<value_type>& dest,
00928                                fpoint& offset) const;
00929 
00930       /**
00931        * After the matrix has been analyzed, this method can be used to
00932        * compute the dimensions of the resulting image and the offset.
00933        */
00934       virtual bool evalDims(const ipoint& orig,
00935                                   ipoint& res,
00936                                   fpoint& offset) const;
00937 
00938       /**
00939        * Transform the given point coordinates.
00940        *
00941        * \warning Do not forget to provide first the size of the matrix
00942        *          from which the points are going to be taken, using
00943        *          use(const ipoint&).
00944        *
00945        * This method takes the \a orig position, assumed to be in a reference
00946        * system of a matrix/image of the size given by the use(const ipoint&)
00947        * method, and transforms this position according to the set parameters.
00948        */
00949       virtual void forwards(const fpoint& orig,
00950                             fpoint& dest,
00951                             const fpoint& offset) const;
00952 
00953 
00954       /**
00955        * Inverse transform the given point coordinates.
00956        *
00957        * \warning Do not forget to provide first the size of the matrix
00958        *          from which the points are going to be taken, using
00959        *          use(const ipoint&).
00960        *
00961        * This method is the inverse of forwards(const fpoint&,fpoint&).  Given
00962        * a position \c dest in the transformed system, it computes the
00963        * coordinates of that point in the original coordinate system.
00964        *
00965        * @param dest Position of a point in the transformed space.
00966        * @param orig Position of the point in the original space.
00967        * @param offset Position of the origin of the result with respect to the
00968        *               coordinate system of the original image.
00969        */
00970       virtual void backwards(const fpoint& dest,
00971                              fpoint& orig,
00972                              const fpoint& offset) const;
00973     private:
00974       /**
00975        * @name Matrix entries
00976        */
00977       //@{
00978       float m00_,m01_;
00979       float m10_,m11_;
00980       //@}
00981     };
00982 
00983     /**
00984      * Helper for 2x3 matrix transformations
00985      */
00986     class helper2x3 : public helperBase {
00987     public:
00988       /**
00989        * The only available constructor.
00990        */
00991       helper2x3(interpolator_type& interp,const parameters& par);
00992 
00993       /**
00994        * Virtual destructor
00995        */
00996       virtual ~helper2x3();
00997 
00998       /**
00999        * Analyze the matrix in the parameters and compute its inverse.
01000        * If the matrix is not invertible, then return false.
01001        */
01002       virtual bool analyzeMatrix();
01003 
01004       /**
01005        * Transform an image according to the matrix provided in the parameters
01006        */
01007       virtual bool apply(const matrix<value_type>& src,
01008                                matrix<value_type>& dest,
01009                                fpoint& offset) const;
01010 
01011       /**
01012        * After the matrix has been analyzed, this method can be used to
01013        * compute the dimensions of the resulting image and the offset.
01014        */
01015       virtual bool evalDims(const ipoint& orig,
01016                                   ipoint& res,
01017                                   fpoint& offset) const;
01018       /**
01019        * Transform the given point coordinates.
01020        *
01021        * \warning Do not forget to provide first the size of the matrix
01022        *          from which the points are going to be taken, using
01023        *          use(const ipoint&).
01024        *
01025        * This method takes the orig position, assumed to be in a reference
01026        * system of a matrix/image of the size given by the use(const ipoint&)
01027        * method, and transforms this position according to the set parameters.
01028        */
01029       virtual void forwards(const fpoint& orig,
01030                             fpoint& dest,
01031                             const fpoint& offset) const;
01032 
01033 
01034       /**
01035        * Inverse transform the given point coordinates.
01036        *
01037        * \warning Do not forget to provide first the size of the matrix
01038        *          from which the points are going to be taken, using
01039        *          use(const ipoint&).
01040        *
01041        * This method is the inverse of forwards(const fpoint&,fpoint&).  Given
01042        * a position \c dest in the transformed system, it computes the
01043        * coordinates of that point in the original coordinate system.
01044        *
01045        * @param dest Position of a point in the transformed space.
01046        * @param orig Position of the point in the original space.
01047        * @param offset Position of the origin of the result with respect to the
01048        *               coordinate system of the original image.
01049        */
01050       virtual void backwards(const fpoint& dest,
01051                              fpoint& orig,
01052                              const fpoint& offset) const;
01053     private:
01054       /**
01055        * @name Matrix entries
01056        */
01057       //@{
01058       float m00_,m01_,m02_;
01059       float m10_,m11_,m12_;
01060       //@}
01061     };
01062 
01063     /**
01064      * Helper for 2x3 matrix transformations
01065      */
01066     class helper3x3 : public helperBase {
01067     public:
01068       /**
01069        * The only available constructor.
01070        */
01071       helper3x3(interpolator_type& interp,const parameters& par);
01072 
01073       /**
01074        * Virtual destructor
01075        */
01076       virtual ~helper3x3();
01077 
01078       /**
01079        * Analyze the matrix in the parameters and compute its inverse.
01080        * If the matrix is not invertible, then return false.
01081        */
01082       virtual bool analyzeMatrix();
01083 
01084       /**
01085        * Transform an image according to the matrix provided in the parameters
01086        */
01087       virtual bool apply(const matrix<value_type>& src,
01088                                matrix<value_type>& dest,
01089                                fpoint& offset) const;
01090 
01091       /**
01092        * After the matrix has been analyzed, this method can be used to
01093        * compute the dimensions of the resulting image and the offset.
01094        */
01095       virtual bool evalDims(const ipoint& orig,
01096                                   ipoint& res,
01097                                   fpoint& offset) const;
01098 
01099       /**
01100        * Transform the given point coordinates.
01101        *
01102        * \warning Do not forget to provide first the size of the matrix
01103        *          from which the points are going to be taken, using
01104        *          use(const ipoint&).
01105        *
01106        * This method takes the orig position, assumed to be in a reference
01107        * system of a matrix/image of the size given by the use(const ipoint&)
01108        * method, and transforms this position according to the set parameters.
01109        */
01110       virtual void forwards(const fpoint& orig,
01111                             fpoint& dest,
01112                             const fpoint& offset) const;
01113 
01114 
01115       /**
01116        * Inverse transform the given point coordinates.
01117        *
01118        * \warning Do not forget to provide first the size of the matrix
01119        *          from which the points are going to be taken, using
01120        *          use(const ipoint&).
01121        *
01122        * This method is the inverse of forwards(const fpoint&,fpoint&).  Given
01123        * a position \c dest in the transformed system, it computes the
01124        * coordinates of that point in the original coordinate system.
01125        *
01126        * @param dest Position of a point in the transformed space.
01127        * @param orig Position of the point in the original space.
01128        * @param offset Position of the origin of the result with respect to the
01129        *               coordinate system of the original image.
01130        */
01131       virtual void backwards(const fpoint& dest,
01132                              fpoint& orig,
01133                              const fpoint& offset) const;
01134     private:
01135       /**
01136        * @name Matrix entries
01137        */
01138       //@{
01139       float m00_,m01_,m02_;
01140       float m10_,m11_,m12_;
01141       float m20_,m21_,m22_;
01142       //@}
01143     };
01144 
01145 
01146     /**
01147      * Helper for 4x4 matrix transformations
01148      */
01149     class helper4x4 : public helperBase {
01150     public:
01151       /**
01152        * The only available constructor.
01153        */
01154       helper4x4(interpolator_type& interp,const parameters& par);
01155 
01156       /**
01157        * Virtual destructor
01158        */
01159       virtual ~helper4x4();
01160 
01161       /**
01162        * Analyze the matrix in the parameters and compute its inverse.
01163        * If the matrix is not invertible, then return false.
01164        */
01165       virtual bool analyzeMatrix();
01166 
01167       /**
01168        * Transform an image according to the matrix provided in the parameters
01169        */
01170       virtual bool apply(const matrix<value_type>& src,
01171                                matrix<value_type>& dest,
01172                                fpoint& offset) const;
01173       /**
01174        * After the matrix has been analyzed, this method can be used to
01175        * compute the dimensions of the resulting image and the offset.
01176        */
01177       virtual bool evalDims(const ipoint& orig,
01178                                   ipoint& res,
01179                                   fpoint& offset) const;
01180 
01181       /**
01182        * Get inverse matrix as matrix
01183        */
01184       bool getMatrix(fmatrix& m) const;
01185 
01186       /**
01187        * Get the transformation of the given point (x,y) extending it to
01188        * homogeneous coordinates (x,y,0,1), and normalizing the result
01189        */
01190       bool trans(const fmatrix& m,const ipoint& p,fpoint& res) const;
01191 
01192       /**
01193        * Transform the given point coordinates.
01194        *
01195        * \warning Do not forget to provide first the size of the matrix
01196        *          from which the points are going to be taken, using
01197        *          use(const ipoint&).
01198        *
01199        * This method takes the orig position, assumed to be in a reference
01200        * system of a matrix/image of the size given by the use(const ipoint&)
01201        * method, and transforms this position according to the set parameters.
01202        */
01203       virtual void forwards(const fpoint& orig,
01204                             fpoint& dest,
01205                             const fpoint& offset) const;
01206 
01207 
01208       /**
01209        * Inverse transform the given point coordinates.
01210        *
01211        * \warning Do not forget to provide first the size of the matrix
01212        *          from which the points are going to be taken, using
01213        *          use(const ipoint&).
01214        *
01215        * This method is the inverse of forwards(const fpoint&,fpoint&).  Given
01216        * a position \c dest in the transformed system, it computes the
01217        * coordinates of that point in the original coordinate system.
01218        *
01219        * @param dest Position of a point in the transformed space.
01220        * @param orig Position of the point in the original space.
01221        * @param offset Position of the origin of the result with respect to the
01222        *               coordinate system of the original image.
01223        */
01224       virtual void backwards(const fpoint& dest,
01225                              fpoint& orig,
01226                              const fpoint& offset) const;
01227     protected:
01228       /**
01229        * @name Matrix entries of the inverse
01230        */
01231       //@{
01232       float m00_,m01_,m02_,m03_;
01233       float m10_,m11_,m12_,m13_;
01234       float m20_,m21_,m22_,m23_;
01235       float m30_,m31_,m32_,m33_;
01236       //@}
01237 
01238       /**
01239        * Compute the inverse.
01240        *
01241        * Return false if matrix is singular.
01242        */
01243       bool inverse(const double& m00,
01244                    const double& m01,
01245                    const double& m02,
01246                    const double& m03,
01247                    const double& m10,
01248                    const double& m11,
01249                    const double& m12,
01250                    const double& m13,
01251                    const double& m20,
01252                    const double& m21,
01253                    const double& m22,
01254                    const double& m23,
01255                    const double& m30,
01256                    const double& m31,
01257                    const double& m32,
01258                    const double& m33);
01259 
01260     };
01261 
01262     /**
01263      * Helper for 4x3 matrix transformations
01264      */
01265     class helper4x3 : public helper4x4 {
01266     public:
01267       /**
01268        * The only available constructor.
01269        */
01270       helper4x3(interpolator_type& interp,const parameters& par);
01271 
01272       /**
01273        * Virtual destructor
01274        */
01275       virtual ~helper4x3();
01276 
01277       /**
01278        * Analyze the matrix in the parameters and compute its inverse.
01279        * If the matrix is not invertible, then return false.
01280        */
01281       virtual bool analyzeMatrix();
01282 
01283       /**
01284        * After the matrix has been analyzed, this method can be used to
01285        * compute the dimensions of the resulting image and the offset.
01286        */
01287       virtual bool evalDims(const ipoint& orig,
01288                                   ipoint& res,
01289                                   fpoint& offset) const;
01290 
01291       /**
01292        * Get the transformation of the given point (x,y) extending it to
01293        * homogeneous coordinates (x,y,0,1), and normalizing the result
01294        */
01295       bool trans(const fmatrix& m,const ipoint& p,fpoint& res) const;
01296     };
01297 
01298     /**
01299      * Pointer to the actual helper being used.
01300      *
01301      * This pointer is managed by the updateParameters() method.
01302      */
01303     helperBase* helper_;
01304 
01305     /**
01306      * Last offset computed in use();
01307      */
01308     fpoint offset_;
01309 
01310     /**
01311      * Last size indicated with use()
01312      */
01313     ipoint usedSize_;
01314 
01315   }; // class matrixTransform<I>
01316 
01317 } // namespace cvr
01318 
01319 #include "cvrMatrixTransform_template.h"
01320 
01321 #endif

Generated on Sun Sep 20 22:08:00 2009 for CVR-Lib by Doxygen 1.5.8