numeric
PlaneFitting.hpp
Go to the documentation of this file.
1 #ifndef __NUMERIC_PLANEFITTING_HPP__
2 #define __NUMERIC_PLANEFITTING_HPP__
3 
4 #include <Eigen/Core>
5 #include <Eigen/Cholesky>
6 #include <Eigen/Eigenvalues>
7 
8 namespace numeric
9 {
10 
19 template<class Scalar>
21 {
22 public:
23  typedef typename Eigen::Matrix<Scalar,3,1> Vector3;
24  typedef typename Eigen::Matrix<Scalar,3,3> Matrix3;
25 
26  Scalar x, y, z, xx, yy, xy, xz, yz, zz, n;
27 
29  x(0), y(0), z(0), xx(0), yy(0), xy(0), xz(0), yz(0), zz(0), n(0) {}
30 
31  explicit PlaneFitting( const Vector3& p, Scalar weight = 1.0 ) :
32  x(p.x() * weight),
33  y(p.y() * weight),
34  z(p.z() * weight),
35  xx(p.x()*x),
36  yy(p.y()*y),
37  xy(p.x()*y),
38  xz(p.x()*z),
39  yz(p.y()*z),
40  zz(p.z()*z),
41  n(weight)
42  {
43  }
44 
50  void scale( Scalar scale )
51  {
52  x *= scale;
53  y *= scale;
54  z *= scale;
55  xx *= scale;
56  yy *= scale;
57  xy *= scale;
58  xz *= scale;
59  yz *= scale;
60  zz *= scale;
61  n *= scale;
62  }
63 
67  void clear()
68  {
69  x = y = z = xx = yy = xy = xz = yz = zz = n = 0;
70  }
71 
72  void update( const PlaneFitting& other )
73  {
74  x += other.x;
75  y += other.y;
76  z += other.z;
77  xx += other.xx;
78  yy += other.yy;
79  xy += other.xy;
80  xz += other.xz;
81  yz += other.yz;
82  zz += other.zz;
83  n += other.n;
84  }
85 
86  void update( const Vector3& p, Scalar weight = 1.0 )
87  {
88  update( PlaneFitting( p, weight ) );
89  }
90 
91  class Result
92  {
93  Eigen::LDLT<Matrix3> ldlt;
94  Vector3 coeffs;
95  Scalar res;
96 
97  public:
98  explicit Result( const PlaneFitting<Scalar>& sum )
99  {
100  Matrix3 A;
101  Vector3 b;
102  A <<
103  sum.xx, sum.xy, sum.x,
104  sum.xy, sum.yy, sum.y,
105  sum.x, sum.y, sum.n;
106 
107  b = Vector3( sum.xz, sum.yz, sum.z );
108 
109  ldlt.compute( A );
110  coeffs = ldlt.solve( b );
111  res = sum.zz - b.dot(coeffs); // == sum.zz - 2*b^T*coeffs + coeffs^T*A*coeffs
112  }
113 
114  const Vector3& getCoeffs() const
115  {
116  return coeffs;
117  }
118 
119  Scalar getResiduals() const
120  {
121  return res;
122  }
123 
124  Matrix3 getCovariance() const
125  {
126  Matrix3 cov =
127  getResiduals() * ldlt.solve( Matrix3::Identity() );
128  return cov;
129  }
130  };
131 
140  Result solve() const
141  {
142  return Result( *this );
143  }
144 
157  Vector3 getCoeffs() const
158  {
159  return solve().getCoeffs();
160  }
161 
171  Matrix3 getCovariance() const
172  {
173  return solve().getCovariance();
174  }
175 
181  {
182  Eigen::SelfAdjointEigenSolver<Matrix3> eig;
183  Scalar offset;
184  public:
185  typedef Eigen::Hyperplane<Scalar, 3> Plane;
187  {
188  Matrix3 moments;
189  Vector3 mu(sum.x, sum.y, sum.z);
190  moments << sum.xx, sum.xy, sum.xz,
191  sum.xy, sum.yy, sum.yz,
192  sum.xz, sum.yz, sum.zz;
193  if(sum.n > 0.0)
194  {
195  moments -= mu * mu.transpose() * (1.0/sum.n);
196  mu *= (1.0/sum.n);
197  }
198  eig.computeDirect(moments, Eigen::ComputeEigenvectors);
199  offset = -eig.eigenvectors().col(0).dot(mu);
200  }
201 
202  Vector3 getNormal() const
203  {
204  return eig.eigenvectors().col(0);
205  }
206 
207  Scalar getOffset() const
208  {
209  return offset;
210  }
211 
215  Plane getPlane() const
216  {
217  return Plane(getNormal(), getOffset());
218  }
219 
223  Scalar getResiduals() const
224  {
225  return eig.eigenvalues()[0];
226  }
227 
228  };
229 
231  {
232  return ResultNormal(*this);
233  }
234  Vector3 getNormal() const
235  {
236  return solveNormal().getNormal();
237  }
238 };
239 
240 }
241 
242 #endif
Definition: PlaneFitting.hpp:180
Plane getPlane() const
Definition: PlaneFitting.hpp:215
Matrix3 getCovariance() const
calculate the covariance matrix
Definition: PlaneFitting.hpp:171
void scale(Scalar scale)
scale the statistics Note that this will not have influence on the solution, but will only change the...
Definition: PlaneFitting.hpp:50
Scalar zz
Definition: PlaneFitting.hpp:26
Definition: Circle.hpp:6
Vector3 getNormal() const
Definition: PlaneFitting.hpp:202
Scalar y
Definition: PlaneFitting.hpp:26
Eigen::Matrix< Scalar, 3, 1 > Vector3
Definition: PlaneFitting.hpp:23
Scalar getResiduals() const
Definition: PlaneFitting.hpp:119
Vector3 getNormal() const
Definition: PlaneFitting.hpp:234
Scalar x
Definition: PlaneFitting.hpp:26
Scalar yy
Definition: PlaneFitting.hpp:26
Eigen::Matrix< Scalar, 3, 3 > Matrix3
Definition: PlaneFitting.hpp:24
Scalar xy
Definition: PlaneFitting.hpp:26
Scalar z
Definition: PlaneFitting.hpp:26
Scalar xz
Definition: PlaneFitting.hpp:26
PlaneFitting()
Definition: PlaneFitting.hpp:28
Eigen::Hyperplane< Scalar, 3 > Plane
Definition: PlaneFitting.hpp:185
const Vector3 & getCoeffs() const
Definition: PlaneFitting.hpp:114
Scalar getResiduals() const
Definition: PlaneFitting.hpp:223
Definition: PlaneFitting.hpp:91
Definition: PlaneFitting.hpp:20
void update(const Vector3 &p, Scalar weight=1.0)
Definition: PlaneFitting.hpp:86
Result(const PlaneFitting< Scalar > &sum)
Definition: PlaneFitting.hpp:98
Matrix3 getCovariance() const
Definition: PlaneFitting.hpp:124
Vector3 getCoeffs() const
Get the coefficients of the fitted plane.
Definition: PlaneFitting.hpp:157
Scalar n
Definition: PlaneFitting.hpp:26
Result solve() const
Solve the regression and return a result object.
Definition: PlaneFitting.hpp:140
Scalar getOffset() const
Definition: PlaneFitting.hpp:207
ResultNormal(const PlaneFitting< Scalar > &sum)
Definition: PlaneFitting.hpp:186
PlaneFitting(const Vector3 &p, Scalar weight=1.0)
Definition: PlaneFitting.hpp:31
void update(const PlaneFitting &other)
Definition: PlaneFitting.hpp:72
Scalar yz
Definition: PlaneFitting.hpp:26
void clear()
clears all previous input to the update method
Definition: PlaneFitting.hpp:67
ResultNormal solveNormal() const
Definition: PlaneFitting.hpp:230
Scalar xx
Definition: PlaneFitting.hpp:26