[ 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) |
html generated using doxygen and Python
|