[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
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) |
html generated using doxygen and Python
|