eightPointAlgorithm.cpp

Go to the documentation of this file.
00001 
00016 #include <dlrComputerVision/eightPointAlgorithm.h>
00017 
00018 namespace num = dlr::numeric;
00019 namespace linAlg = dlr::linearAlgebra;
00020 
00021 namespace dlr {
00022 
00023   namespace computerVision {
00024 
00025 
00026     // This function is used internally by eightPointAlgorithm() to
00027     // translate and scale input points so that their mean lies at the
00028     // origin and they have isotropic unit variance.
00029     void
00030     normalizePointSequence(dlr::numeric::Array2D<double> const& inputPoints,
00031                            dlr::numeric::Array2D<double>& outputPoints,
00032                            dlr::numeric::Array2D<double>& transform)
00033     {
00034       // Following Hartley (and quoting almost directly from the
00035       // paper), let u_i = [u_i,x , u_i,y , 1.0]^T, and form the
00036       // matrix
00037       //
00038       //   E = sum(u_i * u_i^T).
00039       //
00040       // Since this matrix is symmetric and positive definite, we may
00041       // take its Choleski factorization
00042       //
00043       //   E = K * K^T
00044       // 
00045       // where K is upper triangular. It follows that
00046       //
00047       //   sum(inv(K / sqrt(N)) * u_i * u_i^T * inv(K / sqrt(N))^T) = NI,
00048       //
00049       // where I is the identity matrix, [and N is the number of
00050       // elements in the sum]. [...] Note that K is upper triangular,
00051       // and so it represents an affine transformation.
00052       //
00053       // In other words transforming by K/sqrt(N) puts the centroid of
00054       // our points at the origin, and normalizes their variance.
00055       // Just what we need.
00056       dlr::numeric::Array2D<double> EE =
00057         num::matrixMultiply(inputPoints.transpose(), inputPoints);
00058       double sqrtN = std::sqrt(inputPoints.rows());
00059 
00060       num::Array2D<double> KK;
00061       linAlg::choleskyFactorization(EE, KK, false);
00062       KK /= sqrtN;
00063       num::Array2D<double> KKInv = linAlg::inverse(KK);
00064 
00065       // OK, now we've found our normalizing transform.  Apply it
00066       // to the input points.
00067       outputPoints = num::matrixMultiply(inputPoints, KKInv.transpose());
00068       transform = KKInv;
00069     }
00070 
00071   } // namespace computerVision
00072     
00073 } // namespace dlr

Generated on Wed Nov 25 12:15:04 2009 for dlrComputerVision Utility Library by  doxygen 1.5.8