vgl_fit_plane_3d.hxx
Go to the documentation of this file.
1 // This is core/vgl/algo/vgl_fit_plane_3d.hxx
2 #ifndef vgl_fit_plane_3d_hxx_
3 #define vgl_fit_plane_3d_hxx_
4 //:
5 // \file
6 
7 #include <iostream>
8 #include <utility>
9 #include "vgl_fit_plane_3d.h"
10 #ifdef _MSC_VER
11 # include <vcl_msvc_warnings.h>
12 #endif
14 #include <vnl/algo/vnl_svd.h>
15 #include <vnl/vnl_matrix.h>
16 
17 template <class T>
19 : points_(std::move(points))
20 {
21 }
22 
23 template <class T>
25 {
26  points_.push_back(p);
27 }
28 
29 template <class T>
30 void vgl_fit_plane_3d<T>::add_point(const T x, const T y, const T z)
31 {
32  points_.push_back(vgl_homg_point_3d<T> (x, y, z));
33 }
34 
35  template <class T>
37 {
38  points_.clear();
39 }
40 
41  template <class T>
42  bool vgl_fit_plane_3d<T>::fit(const T error_marg, std::ostream* errstream/*=0*/)
43 {
44 
45  T min = this->fit(errstream);
46  if (min > error_marg) {
47  if (errstream) *errstream << "Error Margin " << error_marg << '<' << min << ". Could not fit the points to a plane\n";
48  return false;
49  }
50 
51  return true;
52 }
53 
54 template <class T>
55 T vgl_fit_plane_3d<T>::fit(std::ostream* errstream)
56 {
57  // normalize the points
59  if (!norm.compute_from_points(points_) && errstream) {
60  *errstream << "there is a problem with norm transform\n";
61  }
62 
63  // compute the matrix A of Ax=b
64  T A=0, B=0, C=0, D=0, E=0, F=0, G=0, H=0, I=0;
65  const unsigned n = static_cast<const unsigned>(points_.size());
66  for (unsigned i=0; i<n; i++) {
67  points_[i] = norm(points_[i]);//normalize
68  const T x = points_[i].x()/points_[i].w();
69  const T y = points_[i].y()/points_[i].w();
70  const T z = points_[i].z()/points_[i].w();
71  A += x;
72  B += y;
73  C += z;
74  D += x*x;
75  E += y*y;
76  F += z*z;
77  G += x*y;
78  H += y*z;
79  I += x*z;
80  }
81 
82  vnl_matrix<T> coeff_matrix(4,4);
83  coeff_matrix(0, 0) = D;
84  coeff_matrix(0, 1) = G;
85  coeff_matrix(0, 2) = I;
86  coeff_matrix(0, 3) = A;
87 
88  coeff_matrix(1, 0) = G;
89  coeff_matrix(1, 1) = E;
90  coeff_matrix(1, 2) = H;
91  coeff_matrix(1, 3) = B;
92 
93  coeff_matrix(2, 0) = I;
94  coeff_matrix(2, 1) = H;
95  coeff_matrix(2, 2) = F;
96  coeff_matrix(2, 3) = C;
97 
98  coeff_matrix(3, 0) = A;
99  coeff_matrix(3, 1) = B;
100  coeff_matrix(3, 2) = C;
101  coeff_matrix(3, 3) = T(n);
102 
103  vnl_svd<T> svd(coeff_matrix);
104  // check if the error_margin is achieved
105 
106  // null vector gives the solution to the linear equation where b=[0]
107  vnl_vector<T> s = svd.nullvector();
108 
109  // re-transform the points back to the real world
110  vnl_matrix_fixed<T,4,4> N_transp=norm.get_matrix().transpose();
111  s = N_transp * s;
112 
113  T a, b, c, d;
114  a = s.get(0);
115  b = s.get(1);
116  c = s.get(2);
117  d = s.get(3);
118  plane_ = vgl_homg_plane_3d<T> (a, b, c, d);
119 
120  return svd.sigma_min();
121 }
122 
123 //--------------------------------------------------------------------------
124 #undef VGL_FIT_PLANE_3D_INSTANTIATE
125 #define VGL_FIT_PLANE_3D_INSTANTIATE(T) \
126 template class vgl_fit_plane_3d<T >
127 
128 #endif // vgl_fit_plane_3d_hxx_
void clear()
clear internal data.
Represents a homogeneous 3D point.
Definition: vgl_fwd.h:9
bool fit(const T error_marg, std::ostream *outstream=nullptr)
fits a plane to the stored points.
void add_point(vgl_homg_point_3d< T > const &p)
add a point to point set.
bool compute_from_points(std::vector< vgl_homg_point_3d< T > > const &points)
compute the normalizing transform.
vnl_matrix_fixed< T, 4, 4 > const & get_matrix() const
Return the 4x4 homography matrix.
vgl_fit_plane_3d()=default
The similarity transform that normalizes a 3-d point set.
Fits a plane to a set of 3D points.