[ 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 /*                                                                      */
    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)