last update 20 Sep 2009 |
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