Image Component Library (ICL)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Public Types | Public Member Functions | Static Public Member Functions
icl::math::GenericHomography2D< T > Struct Template Reference

Utility structure that represents a 2D homography (implemented for float and double) More...

#include <Homography2D.h>

Inheritance diagram for icl::math::GenericHomography2D< T >:
icl::math::FixedMatrix< T, 3, 3 > icl::utils::FixedArray< T, COLS *ROWS > icl::math::FixedMatrixBase

List of all members.

Public Types

enum  Algorithm { Simple, Advanced }
 Internally used algorithm type. More...
typedef FixedMatrix< T, 3, 3 > Super
 super class typedef for shorter super-class references

Public Member Functions

 GenericHomography2D ()
 Empty constructor.
 GenericHomography2D (const utils::Point32f *pAs, const utils::Point32f *pBs, int n=4, Algorithm algo=Advanced)
 Constructor from given two point sets of size n>=4.
utils::Point32f apply (const utils::Point32f &p) const
 applies the homography
utils::Point32f apply_int (const utils::Point32f &p) const
 applies the homography

Static Public Member Functions

static utils::Point32f apply_homography (const FixedMatrix< float, 3, 3 > &H, const utils::Point32f &p)
 applies a given homography matrix
static utils::Point apply_homography_int (const FixedMatrix< float, 3, 3 > &H, const utils::Point &p)
 applies a given homography matrix

Detailed Description

template<class T>
struct icl::math::GenericHomography2D< T >

Utility structure that represents a 2D homography (implemented for float and double)

Basically, a 2D homography implements a transformation between 2 paralellograms Given a set of at least 4 points in parallellogram A and the same number of corresponding points in parallelogram B, the homography (affine 2D transformation between space A and space B is defined as follows:

$H$ must transform each point $a_i$ (given wrt. space A) to it's corresponding point $b_i$. Please refer to Wikipedia or the class implementation for more details:

Algorithms

The Homography2D class provides two different algorithms: a faster simple one, and a slightly slower, but more elaborated one. The simple algorithm creates a simpler matrix whose last row becomes (0,0,1)^T. In some cases, this is enough, which is why, this algorithm is provided even though, it does not lead to perfect results.

Simplicity

The homography is used to transform a set of homogeneous 2D source points $ \{a_i\} \;\;i \in [0,n[ $ into a set of 2D destination points $ \{b_i\} \;\;i \in [0,n[ $. Since we search for a linear transformation, This transformation H is modelled by a 3x3 matrix whose last element is fixed to 1. We call the rows of H X,Y,L, which leads to the targeted equation:

\[ H a_i = b_i \;\;\; \forall i \in [0,n[ \]

The most simple approach is to stack all $a_i$ and all $b_i$ horizontally which leads to the equation

\[ H A = B \]

\[ H (a_0 a_1 a_2 ... a_{n-1}) = (b_0 b_1 b_2 ... b_{n-1}) \]

Obviously, this can be solved using a standard pseudoinverse approach

\[ H = B A^{-1} \]

This approach does somehow optimize the problem, but it does not really touch the last row of H. Therefore, the results of this simple approach are sometimes not good enough. Please continue with The Advanced Algorithm

The Advanced Algorithm

In order to also fill the last row of H with optimal values, the originating problem must be reformulated in matrix notation in a different way:
Again, we start with

\[ H a_i = b_i \;\;\; \forall i \in [0,n[ \]

For a single $a_i$ (we call it a and the counter part b resp.), we always have two formulas, one for the x- and one for the y-component.

\[ H ( a_x a_y 1 )^T = (b_x b_y 1)^T \]

Decomposing H to its rows X,Y and L, this can be reformulated as

\[ \frac{X a}{L a} = b_x \;\;\;\;\;and\;\;\;\;\;\; \frac{Y a}{L a} = b_y \]

\[ \Leftrightarrow \frac{X a}{b_x} = La \;\;\;\;\;and\;\;\;\;\;\; \frac{Y a}{b_y} = La \]

\[ \Leftrightarrow \frac{X a}{b_x} - La = 0 \;\;\;\;\;and\;\;\;\;\;\; \frac{Y a}{b_y} - La = 0 \]

\[ \Leftrightarrow \frac{X a}{b_x} - L_x a_x - L_y a_y - 1 = 0 \;\;\;\;\;and\;\;\;\;\;\; \frac{Y a}{b_y} - L_x a_x - L_y a_y - 1 = 0 \]

\[ \Leftrightarrow \frac{X a}{b_x} - L_x a_x - L_y a_y = 1 \;\;\;\;\;and\;\;\;\;\;\; \frac{Y a}{b_y} - L_x a_x - L_y a_y = 1 \]

By multiplying with $ b_x $ ( $ b_y $ resp.), we get

\[ \Leftrightarrow X a - L_x b_x a_x - L_y a_y b_x = b_x \;\;\;\;\;and\;\;\;\;\;\; Y a - L_x a_x b_y - L_y a_y b_y = b_y \]

These two equations can be expressed in a single huge matrix expression $ M h = r $ where M is a 2n by 8 matrix, and $ h = (X^T Y^T L_x L_y)^T $ and r are 2n-dimensional row vectors. M and r are build as follows. For each input/output tuple $(a_i,b_i)$, two rows of M are created using the following scheme:

\[ M=\left(\begin{array}{cccccccc} a_x & a_y & 1 & 0 & 0 & 0 & -a_x b_x & -a_y b_x \\ 0 & 0 & 0 & a_x & a_y & 1 & -a_x b_y & -a_y b_y \\ ... \end{array}\right) \]

The result vector r is just filled with the target values

\[ r = ( b_x b_y ... )^T \]

Finally the matrix equation $ M h = r $ is evaluated with respect to h by

\[ h = M^{-1} r \]

And h's elements are put back into the homography matrix H in a row-wise manner. Remember that The last elememt of H was set fixed to 1. Please note: Internally, the matrix equation $ M h = r $ is solved using an SVD (

See also:
ICLMath/DynMatrix::solve) based solver (the much faster lu-decomposition based solver does not provide useful results)

Member Typedef Documentation

template<class T >
typedef FixedMatrix<T,3,3> icl::math::GenericHomography2D< T >::Super

super class typedef for shorter super-class references


Member Enumeration Documentation

Internally used algorithm type.

Enumerator:
Simple 

use the simple algorithm (

See also:
Algorithms)
Advanced 

use the advanced algorithm (

See also:
Algorithms)

Constructor & Destructor Documentation

template<class T >
icl::math::GenericHomography2D< T >::GenericHomography2D ( ) [inline]

Empty constructor.

template<class T >
icl::math::GenericHomography2D< T >::GenericHomography2D ( const utils::Point32f pAs,
const utils::Point32f pBs,
int  n = 4,
Algorithm  algo = Advanced 
)

Constructor from given two point sets of size n>=4.


Member Function Documentation

template<class T >
utils::Point32f icl::math::GenericHomography2D< T >::apply ( const utils::Point32f p) const [inline]

applies the homography

template<class T >
static utils::Point32f icl::math::GenericHomography2D< T >::apply_homography ( const FixedMatrix< float, 3, 3 > &  H,
const utils::Point32f p 
) [inline, static]

applies a given homography matrix

template<class T >
static utils::Point icl::math::GenericHomography2D< T >::apply_homography_int ( const FixedMatrix< float, 3, 3 > &  H,
const utils::Point p 
) [inline, static]

applies a given homography matrix

template<class T >
utils::Point32f icl::math::GenericHomography2D< T >::apply_int ( const utils::Point32f p) const [inline]

applies the homography


The documentation for this struct was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines