[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

vigra/affine_registration.hxx VIGRA

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*               Copyright 2005-2006 by Ullrich Koethe                  */
00004 /*                                                                      */
00005 /*    This file is part of the VIGRA computer vision library.           */
00006 /*    The VIGRA Website is                                              */
00007 /*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
00008 /*    Please direct questions, bug reports, and contributions to        */
00009 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
00010 /*        vigra@informatik.uni-hamburg.de                               */
00011 /*                                                                      */
00012 /*    Permission is hereby granted, free of charge, to any person       */
00013 /*    obtaining a copy of this software and associated documentation    */
00014 /*    files (the "Software"), to deal in the Software without           */
00015 /*    restriction, including without limitation the rights to use,      */
00016 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
00017 /*    sell copies of the Software, and to permit persons to whom the    */
00018 /*    Software is furnished to do so, subject to the following          */
00019 /*    conditions:                                                       */
00020 /*                                                                      */
00021 /*    The above copyright notice and this permission notice shall be    */
00022 /*    included in all copies or substantial portions of the             */
00023 /*    Software.                                                         */
00024 /*                                                                      */
00025 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
00026 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
00027 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
00028 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
00029 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
00030 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
00031 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
00032 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
00033 /*                                                                      */
00034 /************************************************************************/
00035  
00036 #ifndef VIGRA_AFFINE_REGISTRATION_HXX
00037 #define VIGRA_AFFINE_REGISTRATION_HXX
00038 
00039 #include "mathutil.hxx"
00040 #include "matrix.hxx"
00041 #include "linear_solve.hxx"
00042 #include "tinyvector.hxx"
00043 #include "splineimageview.hxx"
00044 #include "imagecontainer.hxx"
00045 #include <cmath>
00046 
00047 namespace vigra {
00048 
00049 /** \addtogroup Registration Image Registration
00050 */
00051 //@{
00052 
00053 /********************************************************/
00054 /*                                                      */
00055 /*       affineMatrix2DFromCorrespondingPoints          */
00056 /*                                                      */
00057 /********************************************************/
00058 
00059 /** \brief Create homogeneous matrix that maps corresponding points onto each other.
00060  
00061     For use with \ref affineWarpImage(). Since only two corresponding points are given,
00062     the matrix will not use a full affine transform, but only a similarity transform 
00063     (translation, rotation, and uniform scaling). See \
00064 */
00065 template <class SrcIterator, class DestIterator>
00066 linalg::TemporaryMatrix<double> 
00067 affineMatrix2DFromCorrespondingPoints(SrcIterator s, SrcIterator send, DestIterator d)
00068 {
00069     int size = send - s;
00070     
00071     linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
00072 
00073     if(size == 1)
00074     {
00075         ret(0,2) = (*d)[0] - (*s)[0];
00076         ret(1,2) = (*d)[1] - (*s)[1];
00077     }
00078     else if(size == 2)
00079     {
00080         Matrix<double> m(4,4), r(4,1), so(4,1);
00081         
00082         for(int k=0; k<size; ++k, ++s, ++d)
00083         {
00084             m(2*k,0) = (*s)[0];
00085             m(2*k,1) = -(*s)[1];
00086             m(2*k,2) = 1.0;
00087             m(2*k,3) = 0.0;
00088             r(2*k,0) = (*d)[0];
00089             
00090             m(2*k+1,0) = (*s)[1];
00091             m(2*k+1,1) = (*s)[0];
00092             m(2*k+1,2) = 0.0;
00093             m(2*k+1,3) = 1.0;
00094             r(2*k+1,0) = (*d)[1];
00095         }
00096     
00097         if(!linearSolve(m, r, so))
00098             vigra_fail("affineMatrix2DFromCorrespondingPoints(): singular solution matrix.");
00099         
00100         ret(0,0) = so(0,0);
00101         ret(1,1) = so(0,0);
00102         ret(0,1) = -so(1,0);
00103         ret(1,0) = so(1,0);
00104         ret(0,2) = so(2,0);
00105         ret(1,2) = so(3,0);
00106     }
00107     else if(size >= 3)
00108     {
00109         Matrix<double> m(3,3),  rx(3,1), sx(3,1), ry(3,1), sy(3,1), c(3,1);
00110         c(2,0) = 1.0;
00111         for(int k=0; k<size; ++k, ++s, ++d)
00112         {
00113             c(0,0) = (*s)[0];
00114             c(1,0) = (*s)[1];
00115             
00116             m  += outer(c);
00117             rx += (*d)[0]*c;
00118             ry += (*d)[1]*c;
00119         }
00120     
00121         if(!linearSolve(m, rx, sx) || !linearSolve(m, ry, sy))
00122             vigra_fail("affineMatrix2DFromCorrespondingPoints(): singular solution matrix.");
00123         
00124         ret(0,0) = sx(0,0);
00125         ret(0,1) = sx(1,0);
00126         ret(0,2) = sx(2,0);
00127         ret(1,0) = sy(0,0);
00128         ret(1,1) = sy(1,0);
00129         ret(1,2) = sy(2,0);
00130     }
00131 
00132     return ret;
00133 }
00134 
00135 template <int SPLINEORDER = 2>
00136 class AffineMotionEstimationOptions
00137 {
00138   public:
00139     double burt_filter_strength;
00140     int highest_level, iterations_per_level;
00141     bool use_laplacian_pyramid;
00142     
00143     AffineMotionEstimationOptions()
00144     : burt_filter_strength(0.4),
00145       highest_level(4),
00146       iterations_per_level(4),
00147       use_laplacian_pyramid(false)
00148     {}
00149     
00150     template <int ORDER>
00151     AffineMotionEstimationOptions(AffineMotionEstimationOptions<ORDER>  const & other)
00152     : burt_filter_strength(other.burt_filter_strength),
00153       highest_level(other.highest_level),
00154       iterations_per_level(other.iterations_per_level),
00155       use_laplacian_pyramid(other.use_laplacian_pyramid)
00156     {}
00157     
00158     template <int NEWORDER>
00159     AffineMotionEstimationOptions<NEWORDER> splineOrder() const
00160     {
00161         return AffineMotionEstimationOptions<NEWORDER>(*this);
00162     }
00163     
00164     AffineMotionEstimationOptions & burtFilterStrength(double strength)
00165     {
00166         vigra_precondition(0.25 <= strength && strength <= 0.5,
00167           "AffineMotionEstimationOptions::burtFilterStrength(): strength must be between 0.25 and 0.5 (inclusive).");
00168         burt_filter_strength = strength;
00169         return *this;
00170     }
00171     
00172     AffineMotionEstimationOptions & highestPyramidLevel(unsigned int level)
00173     {
00174         highest_level = (int)level;
00175         return *this;
00176     }
00177     
00178     AffineMotionEstimationOptions & iterationsPerLevel(unsigned int iter)
00179     {
00180         vigra_precondition(0 < iter,
00181           "AffineMotionEstimationOptions::iterationsPerLevel(): must do at least one iteration per level.");
00182         iterations_per_level = (int)iter;
00183         return *this;
00184     }
00185     
00186     AffineMotionEstimationOptions & useGaussianPyramid(bool f = true)
00187     {
00188         use_laplacian_pyramid = !f;
00189         return *this;
00190     }
00191     
00192     AffineMotionEstimationOptions & useLaplacianPyramid(bool f = true)
00193     {
00194         use_laplacian_pyramid = f;
00195         return *this;
00196     }
00197 };
00198 
00199 namespace detail {
00200 
00201 struct TranslationEstimationFunctor
00202 {
00203     template <class SplineImage, class Image>
00204     void operator()(SplineImage const & src, Image const & dest, Matrix<double> & matrix) const
00205     {
00206         int w = dest.width();
00207         int h = dest.height();
00208         
00209         Matrix<double> grad(2,1), m(2,2), r(2,1), s(2,1);
00210         double dx = matrix(0,0), dy = matrix(1,0);
00211         
00212         for(int y = 0; y < h; ++y)
00213         {
00214             double sx = matrix(0,1)*y + matrix(0,2);
00215             double sy = matrix(1,1)*y + matrix(1,2);
00216             for(int x = 0; x < w; ++x, sx += dx, sy += dy)
00217             {
00218                 if(!src.isInside(sx, sy))
00219                     continue;
00220                   
00221                 grad(0,0) = src.dx(sx, sy);
00222                 grad(1,0) = src.dy(sx, sy);
00223                 double diff = dest(x, y) - src(sx, sy);
00224                 
00225                 m += outer(grad);
00226                 r -= diff*grad;
00227             }
00228         }
00229         
00230         linearSolve(m, r, s);
00231         
00232         matrix(0,2) -= s(0,0);
00233         matrix(1,2) -= s(1,0);
00234     }
00235 };
00236 
00237 struct SimilarityTransformEstimationFunctor
00238 {
00239     template <class SplineImage, class Image>
00240     void operator()(SplineImage const & src, Image const & dest, Matrix<double> & matrix) const
00241     {
00242         int w = dest.width();
00243         int h = dest.height();
00244         
00245         Matrix<double> grad(2,1), coord(4, 2), c(4, 1), m(4, 4), r(4,1), s(4,1);
00246         coord(0,0) = 1.0;
00247         coord(1,1) = 1.0;
00248         double dx = matrix(0,0), dy = matrix(1,0);
00249         
00250         for(int y = 0; y < h; ++y)
00251         {
00252             double sx = matrix(0,1)*y + matrix(0,2);
00253             double sy = matrix(1,1)*y + matrix(1,2);
00254             for(int x = 0; x < w; ++x, sx += dx, sy += dy)
00255             {
00256                 if(!src.isInside(sx, sy))
00257                     continue;
00258                   
00259                 grad(0,0) = src.dx(sx, sy);
00260                 grad(1,0) = src.dy(sx, sy);
00261                 coord(2,0) = (double)x;
00262                 coord(3,1) = (double)x;
00263                 coord(3,0) = -(double)y;
00264                 coord(2,1) = (double)y;
00265                 double diff = dest(x, y) - src(sx, sy);
00266                 
00267                 c = coord * grad;
00268                 m += outer(c);
00269                 r -= diff*c;
00270             }
00271         }
00272         
00273         linearSolve(m, r, s);
00274         
00275         matrix(0,2) -= s(0,0);
00276         matrix(1,2) -= s(1,0);
00277         matrix(0,0) -= s(2,0);
00278         matrix(1,1) -= s(2,0);
00279         matrix(0,1) += s(3,0);
00280         matrix(1,0) -= s(3,0);
00281     }
00282 };
00283 
00284 struct AffineTransformEstimationFunctor
00285 {
00286     template <class SplineImage, class Image>
00287     void operator()(SplineImage const & src, Image const & dest, Matrix<double> & matrix) const
00288     {
00289         int w = dest.width();
00290         int h = dest.height();
00291         
00292         Matrix<double> grad(2,1), coord(6, 2), c(6, 1), m(6,6), r(6,1), s(6,1);
00293         coord(0,0) = 1.0;
00294         coord(1,1) = 1.0;
00295         double dx = matrix(0,0), dy = matrix(1,0);
00296         
00297         for(int y = 0; y < h; ++y)
00298         {
00299             double sx = matrix(0,1)*y + matrix(0,2);
00300             double sy = matrix(1,1)*y + matrix(1,2);
00301             for(int x = 0; x < w; ++x, sx += dx, sy += dy)
00302             {
00303                 if(!src.isInside(sx, sy))
00304                     continue;
00305                   
00306                 grad(0,0) = src.dx(sx, sy);
00307                 grad(1,0) = src.dy(sx, sy);
00308                 coord(2,0) = (double)x;
00309                 coord(4,1) = (double)x;
00310                 coord(3,0) = (double)y;
00311                 coord(5,1) = (double)y;
00312                 double diff = dest(x, y) - src(sx, sy);
00313                 
00314                 c = coord * grad;
00315                 m += outer(c);
00316                 r -= diff*c;
00317             }
00318         }
00319         
00320         linearSolve(m, r, s);
00321         
00322         matrix(0,2) -= s(0,0);
00323         matrix(1,2) -= s(1,0);
00324         matrix(0,0) -= s(2,0);
00325         matrix(0,1) -= s(3,0);
00326         matrix(1,0) -= s(4,0);
00327         matrix(1,1) -= s(5,0);
00328     }
00329 };
00330 
00331 template <class SrcIterator, class SrcAccessor, 
00332           class DestIterator, class DestAccessor, 
00333           int SPLINEORDER, class Functor>
00334 void 
00335 estimateAffineMotionImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
00336                          DestIterator dul, DestIterator dlr, DestAccessor dest,
00337                          Matrix<double> & affineMatrix, 
00338                          AffineMotionEstimationOptions<SPLINEORDER> const & options,
00339                          Functor motionModel)
00340 {
00341     typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote STmpType;
00342     typedef BasicImage<STmpType> STmpImage;
00343     typedef typename NumericTraits<typename DestAccessor::value_type>::RealPromote DTmpType;
00344     typedef BasicImage<DTmpType> DTmpImage;
00345     
00346     int toplevel = options.highest_level;
00347     ImagePyramid<STmpImage> srcPyramid(0, toplevel, sul, slr, src);
00348     ImagePyramid<DTmpImage> destPyramid(0, toplevel, dul, dlr, dest);
00349     
00350     if(options.use_laplacian_pyramid)
00351     {
00352         pyramidReduceBurtLaplacian(srcPyramid, 0, toplevel, options.burt_filter_strength);
00353         pyramidReduceBurtLaplacian(destPyramid, 0, toplevel, options.burt_filter_strength);
00354     }
00355     else
00356     {
00357         pyramidReduceBurtFilter(srcPyramid, 0, toplevel, options.burt_filter_strength);
00358         pyramidReduceBurtFilter(destPyramid, 0, toplevel, options.burt_filter_strength);
00359     }
00360         
00361     Matrix<double> currentMatrix(affineMatrix(2,2) == 0.0 
00362                                     ? identityMatrix<double>(3)
00363                                     : affineMatrix);
00364     currentMatrix(0,2) /= std::pow(2.0, toplevel);
00365     currentMatrix(1,2) /= std::pow(2.0, toplevel);
00366     
00367     for(int level = toplevel; level >= 0; --level)
00368     {
00369         SplineImageView<SPLINEORDER, STmpType> sp(srcImageRange(srcPyramid[level]));
00370         
00371         for(int iter = 0; iter < options.iterations_per_level; ++iter)
00372         {
00373             motionModel(sp, destPyramid[level], currentMatrix);
00374         }
00375         
00376         if(level > 0)
00377         {
00378             currentMatrix(0,2) *= 2.0;
00379             currentMatrix(1,2) *= 2.0;
00380         }
00381     }
00382     
00383     affineMatrix = currentMatrix;
00384 }
00385 
00386 } // namespace detail 
00387 
00388 /********************************************************/
00389 /*                                                      */
00390 /*                 estimateTranslation                  */
00391 /*                                                      */
00392 /********************************************************/
00393 
00394 /** \brief Estimate the optical flow between two images according to a translation model.
00395 
00396     Sorry, no \ref detailedDocumentation() available yet.
00397 
00398     <b> Declarations:</b>
00399 
00400     <b>\#include</b> <vigra/affine_registration.hxx><br>
00401     Namespace: vigra
00402 
00403     pass arguments explicitly:
00404     \code
00405     namespace vigra {
00406         template <class SrcIterator, class SrcAccessor,
00407                   class DestIterator, class DestAccessor,
00408                   int SPLINEORDER = 2>
00409         void
00410         estimateTranslation(SrcIterator sul, SrcIterator slr, SrcAccessor src,
00411                             DestIterator dul, DestIterator dlr, DestAccessor dest,
00412                             Matrix<double> & affineMatrix,
00413                             AffineMotionEstimationOptions<SPLINEORDER> const & options = 
00414                                                         AffineMotionEstimationOptions<>())
00415     }
00416     \endcode
00417 
00418 
00419     use argument objects in conjunction with \ref ArgumentObjectFactories :
00420     \code
00421     namespace vigra {
00422         template <class SrcIterator, class SrcAccessor,
00423                   class DestIterator, class DestAccessor,
00424                   int SPLINEORDER = 2>
00425         void
00426         estimateTranslation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00427                             triple<DestIterator, DestIterator, DestAccessor> dest,
00428                             Matrix<double> & affineMatrix,
00429                             AffineMotionEstimationOptions<SPLINEORDER> const & options =
00430                                                         AffineMotionEstimationOptions<>())
00431     }
00432     \endcode
00433 */
00434 doxygen_overloaded_function(template <...> void estimateTranslation)
00435 
00436 template <class SrcIterator, class SrcAccessor,
00437           class DestIterator, class DestAccessor,
00438           int SPLINEORDER>
00439 inline void
00440 estimateTranslation(SrcIterator sul, SrcIterator slr, SrcAccessor src,
00441                     DestIterator dul, DestIterator dlr, DestAccessor dest,
00442                     Matrix<double> & affineMatrix,
00443                     AffineMotionEstimationOptions<SPLINEORDER> const & options)
00444 {
00445     detail::estimateAffineMotionImpl(sul, slr, src, dul, dlr, dest, affineMatrix,
00446                                      options, detail::TranslationEstimationFunctor());
00447 }
00448              
00449 template <class SrcIterator, class SrcAccessor,
00450           class DestIterator, class DestAccessor>
00451 inline void 
00452 estimateTranslation(SrcIterator sul, SrcIterator slr, SrcAccessor src,
00453                     DestIterator dul, DestIterator dlr, DestAccessor dest,
00454                     Matrix<double> & affineMatrix)
00455 {
00456     estimateTranslation(sul, slr, src, dul, dlr, dest,
00457                         affineMatrix, AffineMotionEstimationOptions<>());
00458 }
00459 
00460 template <class SrcIterator, class SrcAccessor, 
00461           class DestIterator, class DestAccessor, 
00462           int SPLINEORDER>
00463 inline void 
00464 estimateTranslation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00465                     triple<DestIterator, DestIterator, DestAccessor> dest,
00466                     Matrix<double> & affineMatrix, 
00467                     AffineMotionEstimationOptions<SPLINEORDER> const & options)
00468 {
00469     estimateTranslation(src.first, src.second, src.third, dest.first, dest.second, dest.third,
00470                         affineMatrix, options);
00471 }
00472 
00473 template <class SrcIterator, class SrcAccessor, 
00474           class DestIterator, class DestAccessor>
00475 inline void 
00476 estimateTranslation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00477                     triple<DestIterator, DestIterator, DestAccessor> dest,
00478                     Matrix<double> & affineMatrix)
00479 {
00480     estimateTranslation(src.first, src.second, src.third, dest.first, dest.second, dest.third,
00481                         affineMatrix, AffineMotionEstimationOptions<>());
00482 }
00483 
00484 /********************************************************/
00485 /*                                                      */
00486 /*              estimateSimilarityTransform             */
00487 /*                                                      */
00488 /********************************************************/
00489 
00490 /** \brief Estimate the optical flow between two images according to a similarity transform model
00491            (e.g. translation, rotation, and uniform scaling).
00492 
00493     Sorry, no \ref detailedDocumentation() available yet.
00494 
00495     <b> Declarations:</b>
00496 
00497     <b>\#include</b> <vigra/affine_registration.hxx><br>
00498     Namespace: vigra
00499 
00500     pass arguments explicitly:
00501     \code
00502     namespace vigra {
00503         template <class SrcIterator, class SrcAccessor,
00504                   class DestIterator, class DestAccessor,
00505                   int SPLINEORDER = 2>
00506         void
00507         estimateSimilarityTransform(SrcIterator sul, SrcIterator slr, SrcAccessor src,
00508                             DestIterator dul, DestIterator dlr, DestAccessor dest,
00509                             Matrix<double> & affineMatrix,
00510                             AffineMotionEstimationOptions<SPLINEORDER> const & options = 
00511                                                         AffineMotionEstimationOptions<>())
00512     }
00513     \endcode
00514 
00515 
00516     use argument objects in conjunction with \ref ArgumentObjectFactories :
00517     \code
00518     namespace vigra {
00519         template <class SrcIterator, class SrcAccessor,
00520                   class DestIterator, class DestAccessor,
00521                   int SPLINEORDER = 2>
00522         void
00523         estimateSimilarityTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00524                             triple<DestIterator, DestIterator, DestAccessor> dest,
00525                             Matrix<double> & affineMatrix,
00526                             AffineMotionEstimationOptions<SPLINEORDER> const & options =
00527                                                         AffineMotionEstimationOptions<>())
00528     }
00529     \endcode
00530 */
00531 doxygen_overloaded_function(template <...> void estimateSimilarityTransform)
00532 
00533 template <class SrcIterator, class SrcAccessor,
00534           class DestIterator, class DestAccessor, 
00535           int SPLINEORDER>
00536 inline void 
00537 estimateSimilarityTransform(SrcIterator sul, SrcIterator slr, SrcAccessor src,
00538                             DestIterator dul, DestIterator dlr, DestAccessor dest,
00539                             Matrix<double> & affineMatrix, 
00540                             AffineMotionEstimationOptions<SPLINEORDER> const & options)
00541 {
00542     detail::estimateAffineMotionImpl(sul, slr, src, dul, dlr, dest, affineMatrix,
00543                                      options, detail::SimilarityTransformEstimationFunctor());
00544 }
00545              
00546 template <class SrcIterator, class SrcAccessor, 
00547           class DestIterator, class DestAccessor>
00548 inline void 
00549 estimateSimilarityTransform(SrcIterator sul, SrcIterator slr, SrcAccessor src,
00550                             DestIterator dul, DestIterator dlr, DestAccessor dest,
00551                             Matrix<double> & affineMatrix)
00552 {
00553     estimateSimilarityTransform(sul, slr, src, dul, dlr, dest,
00554                                 affineMatrix, AffineMotionEstimationOptions<>());
00555 }
00556              
00557 template <class SrcIterator, class SrcAccessor, 
00558           class DestIterator, class DestAccessor, 
00559           int SPLINEORDER>
00560 inline void 
00561 estimateSimilarityTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00562                             triple<DestIterator, DestIterator, DestAccessor> dest,
00563                             Matrix<double> & affineMatrix, 
00564                             AffineMotionEstimationOptions<SPLINEORDER> const & options)
00565 {
00566     estimateSimilarityTransform(src.first, src.second, src.third, dest.first, dest.second, dest.third,
00567                                 affineMatrix, options);
00568 }
00569 
00570 template <class SrcIterator, class SrcAccessor, 
00571           class DestIterator, class DestAccessor>
00572 inline void 
00573 estimateSimilarityTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00574                             triple<DestIterator, DestIterator, DestAccessor> dest,
00575                             Matrix<double> & affineMatrix)
00576 {
00577     estimateSimilarityTransform(src.first, src.second, src.third, dest.first, dest.second, dest.third,
00578                                 affineMatrix, AffineMotionEstimationOptions<>());
00579 }
00580 
00581 /********************************************************/
00582 /*                                                      */
00583 /*                estimateAffineTransform               */
00584 /*                                                      */
00585 /********************************************************/
00586 
00587 /** \brief Estimate the optical flow between two images according to an affine transform model
00588            (e.g. translation, rotation, non-uniform scaling, and shearing).
00589 
00590     Sorry, no \ref detailedDocumentation() available yet.
00591 
00592     <b> Declarations:</b>
00593 
00594     <b>\#include</b> <vigra/affine_registration.hxx><br>
00595     Namespace: vigra
00596 
00597     pass arguments explicitly:
00598     \code
00599     namespace vigra {
00600         template <class SrcIterator, class SrcAccessor,
00601                   class DestIterator, class DestAccessor,
00602                   int SPLINEORDER = 2>
00603         void
00604         estimateAffineTransform(SrcIterator sul, SrcIterator slr, SrcAccessor src,
00605                             DestIterator dul, DestIterator dlr, DestAccessor dest,
00606                             Matrix<double> & affineMatrix,
00607                             AffineMotionEstimationOptions<SPLINEORDER> const & options = 
00608                                                         AffineMotionEstimationOptions<>())
00609     }
00610     \endcode
00611 
00612 
00613     use argument objects in conjunction with \ref ArgumentObjectFactories :
00614     \code
00615     namespace vigra {
00616         template <class SrcIterator, class SrcAccessor,
00617                   class DestIterator, class DestAccessor,
00618                   int SPLINEORDER = 2>
00619         void
00620         estimateAffineTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00621                             triple<DestIterator, DestIterator, DestAccessor> dest,
00622                             Matrix<double> & affineMatrix,
00623                             AffineMotionEstimationOptions<SPLINEORDER> const & options =
00624                                                         AffineMotionEstimationOptions<>())
00625     }
00626     \endcode
00627 */
00628 doxygen_overloaded_function(template <...> void estimateAffineTransform)
00629 
00630 template <class SrcIterator, class SrcAccessor,
00631           class DestIterator, class DestAccessor, 
00632           int SPLINEORDER>
00633 inline void 
00634 estimateAffineTransform(SrcIterator sul, SrcIterator slr, SrcAccessor src,
00635                         DestIterator dul, DestIterator dlr, DestAccessor dest,
00636                         Matrix<double> & affineMatrix, 
00637                         AffineMotionEstimationOptions<SPLINEORDER> const & options)
00638 {
00639     detail::estimateAffineMotionImpl(sul, slr, src, dul, dlr, dest, affineMatrix,
00640                                      options, detail::AffineTransformEstimationFunctor());
00641 }
00642              
00643 template <class SrcIterator, class SrcAccessor, 
00644           class DestIterator, class DestAccessor>
00645 inline void 
00646 estimateAffineTransform(SrcIterator sul, SrcIterator slr, SrcAccessor src,
00647                         DestIterator dul, DestIterator dlr, DestAccessor dest,
00648                         Matrix<double> & affineMatrix)
00649 {
00650     estimateAffineTransform(sul, slr, src, dul, dlr, dest,
00651                             affineMatrix, AffineMotionEstimationOptions<>());
00652 }
00653              
00654 template <class SrcIterator, class SrcAccessor, 
00655           class DestIterator, class DestAccessor, 
00656           int SPLINEORDER>
00657 inline void 
00658 estimateAffineTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00659                         triple<DestIterator, DestIterator, DestAccessor> dest,
00660                         Matrix<double> & affineMatrix, 
00661                         AffineMotionEstimationOptions<SPLINEORDER> const & options)
00662 {
00663     estimateAffineTransform(src.first, src.second, src.third, dest.first, dest.second, dest.third,
00664                             affineMatrix, options);
00665 }
00666 
00667 template <class SrcIterator, class SrcAccessor, 
00668           class DestIterator, class DestAccessor>
00669 inline void 
00670 estimateAffineTransform(triple<SrcIterator, SrcIterator, SrcAccessor> src,
00671                         triple<DestIterator, DestIterator, DestAccessor> dest,
00672                         Matrix<double> & affineMatrix)
00673 {
00674     estimateAffineTransform(src.first, src.second, src.third, dest.first, dest.second, dest.third,
00675                             affineMatrix, AffineMotionEstimationOptions<>());
00676 }
00677 
00678 //@}
00679 
00680 } // namespace vigra
00681 
00682 
00683 #endif /* VIGRA_AFFINE_REGISTRATION_HXX */

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.9.0 (Tue Nov 6 2012)