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

vigra/affine_registration.hxx

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