52 #ifndef __PCL_Homography_h
53 #define __PCL_Homography_h
58 #include <pcl/Diagnostics.h>
93 : m_H(
Matrix::UnitMatrix( 3 ) )
129 template <
class po
int_list1,
class po
int_list2>
131 : m_H( DLT( P1, P2 ) )
162 template <
typename T1,
typename T2>
165 double fx = double( x );
166 double fy = double( y );
167 double w = m_H[2][0]*fx + m_H[2][1]*fy + m_H[2][2];
168 PCL_CHECK( 1 + w != 1 )
169 x = T1( (m_H[0][0]*fx + m_H[0][1]*fy + m_H[0][2])/w );
170 y = T2( (m_H[1][0]*fx + m_H[1][1]*fy + m_H[1][2])/w );
179 template <
typename T>
191 DPoint operator ()(
double x,
double y )
const
203 template <
typename T>
206 return operator ()(
double( p.
x ),
double( p.
y ) );
239 return TransformationMatrix();
247 return !m_H.IsEmpty();
262 &&
Abs( m_H[2][0] ) <= std::numeric_limits<double>::epsilon()
263 &&
Abs( m_H[2][1] ) <= std::numeric_limits<double>::epsilon()
264 && 1 -
Abs( m_H[2][2] ) <= std::numeric_limits<double>::epsilon();
282 struct NormalizedPoints
287 template <
class po
int_list>
288 NormalizedPoints(
const point_list& points )
294 for (
const auto& p : points )
295 centroid +=
DPoint( p.x, p.y );
296 centroid /= points.Length();
302 for (
const auto& p : points )
304 double dx = double( p.x ) - centroid.x;
305 double dy = double( p.y ) - centroid.y;
307 d0 +=
Sqrt( dx*dx + dy*dy );
309 d0 /= points.Length();
321 T =
Matrix( scale, 0.0, -scale*centroid.x,
322 0.0, scale, -scale*centroid.y,
331 template <
class po
int_list1,
class po
int_list2>
332 static Matrix DLT(
const point_list1& P1,
const point_list2& P2 )
334 int n = int(
Min( P1.Length(), P2.Length() ) );
336 throw Error(
"Homography::DLT(): Less than four points specified." );
341 NormalizedPoints p1( P1 );
342 NormalizedPoints p2( P2 );
348 for (
int i = 0; i < n; ++i )
350 double x1 = p1.N[i].x;
351 double y1 = p1.N[i].y;
352 double x2 = p2.N[i].x;
353 double y2 = p2.N[i].y;
355 double* A1 = A[2*i + 1];
358 A0[0] = A0[1] = A0[2] = 0;
369 A1[3] = A1[4] = A1[5] = 0;
393 for (
int i = 0; i < svd.W.Length(); ++i )
394 if (
Abs( svd.W[i] ) <= std::numeric_limits<double>::epsilon() )
400 int i = svd.IndexOfSmallestSingularValue();
407 Matrix H( svd.V[0][i], svd.V[1][i], svd.V[2][i],
408 svd.V[3][i], svd.V[4][i], svd.V[5][i],
409 svd.V[6][i], svd.V[7][i], svd.V[8][i] );
411 if (
Abs( H[2][2] ) <= std::numeric_limits<double>::epsilon() )
412 throw Error(
"Homography::DLT(): Singular matrix." );
417 H = p2.T.Inverse() * H * p1.T;
422 return H *= 1/H[2][2];
static constexpr T sqrt2()
Generic dynamic matrix of arbitrary dimensions.
A generic point in the two-dimensional space.
component x
Abscissa (horizontal, or X-axis coordinate).
component y
Ordinate (vertical, or Y-axis coordinate).
Homography geometric transformation.
Homography(const point_list1 &P1, const point_list2 &P2)
Homography(const Homography &)=default
GenericPoint< T > & Apply(GenericPoint< T > &p) const
const Matrix & TransformationMatrix() const
void Apply(T1 &x, T2 &y) const
Homography(Homography &&)=default
Homography Inverse() const
Homography(const Matrix &H)
64-bit floating point real matrix.
Complex< T > Sqrt(const Complex< T > &c) noexcept
T Abs(const Complex< T > &c) noexcept
constexpr const T & Min(const T &a, const T &b) noexcept
void Apply(FI i, FI j, F f) noexcept(noexcept(f))