GteApprGaussian3.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
10 #include <Mathematics/GteVector3.h>
14 
15 // Fit points with a Gaussian distribution. The center is the mean of the
16 // points, the axes are the eigenvectors of the covariance matrix, and the
17 // extents are the eigenvalues of the covariance matrix and are returned in
18 // increasing order. An oriented box is used to store the mean, axes, and
19 // extents.
20 
21 namespace gte
22 {
23 
24 template <typename Real>
26  :
27  public ApprQuery<Real, ApprGaussian3<Real>, Vector3<Real>>
28 {
29 public:
30  // Initialize the model parameters to zero.
31  ApprGaussian3();
32 
33  // Basic fitting algorithm.
34  bool Fit(int numPoints, Vector3<Real> const* points);
35  OrientedBox3<Real> const& GetParameters() const;
36 
37  // Functions called by ApprQuery::RANSAC. See GteApprQuery.h for a
38  // detailed description.
39  int GetMinimumRequired() const;
40  Real Error(Vector3<Real> const& observation) const;
41  bool Fit(std::vector<Vector3<Real>> const& observations,
42  std::vector<int> const& indices);
43 
44 private:
46 };
47 
48 
49 template <typename Real>
51 {
53  mParameters.axis[0] = Vector3<Real>::Zero();
54  mParameters.axis[1] = Vector3<Real>::Zero();
55  mParameters.axis[2] = Vector3<Real>::Zero();
57 }
58 
59 template <typename Real>
60 bool ApprGaussian3<Real>::Fit(int numPoints, Vector3<Real> const* points)
61 {
62  if (numPoints >= GetMinimumRequired() && points)
63  {
64  // Compute the mean of the points.
66  for (int i = 0; i < numPoints; ++i)
67  {
68  mean += points[i];
69  }
70  Real invSize = ((Real)1) / (Real)numPoints;
71  mean *= invSize;
72 
73  // Compute the covariance matrix of the points.
74  Real covar00 = (Real)0, covar01 = (Real)0, covar02 = (Real)0;
75  Real covar11 = (Real)0, covar12 = (Real)0, covar22 = (Real)0;
76  for (int i = 0; i < numPoints; ++i)
77  {
78  Vector3<Real> diff = points[i] - mean;
79  covar00 += diff[0] * diff[0];
80  covar01 += diff[0] * diff[1];
81  covar02 += diff[0] * diff[2];
82  covar11 += diff[1] * diff[1];
83  covar12 += diff[1] * diff[2];
84  covar22 += diff[2] * diff[2];
85  }
86  covar00 *= invSize;
87  covar01 *= invSize;
88  covar02 *= invSize;
89  covar11 *= invSize;
90  covar12 *= invSize;
91  covar22 *= invSize;
92 
93  // Solve the eigensystem.
95  std::array<Real, 3> eval;
96  std::array<std::array<Real, 3>, 3> evec;
97  es(covar00, covar01, covar02, covar11, covar12, covar22, false, +1,
98  eval, evec);
99  mParameters.center = mean;
100  mParameters.axis[0] = evec[0];
101  mParameters.axis[1] = evec[1];
102  mParameters.axis[2] = evec[2];
103  mParameters.extent = eval;
104  return true;
105  }
106 
107  mParameters.center = Vector3<Real>::Zero();
108  mParameters.axis[0] = Vector3<Real>::Zero();
109  mParameters.axis[1] = Vector3<Real>::Zero();
110  mParameters.axis[2] = Vector3<Real>::Zero();
111  mParameters.extent = Vector3<Real>::Zero();
112  return false;
113 }
114 
115 template <typename Real>
117 {
118  return mParameters;
119 }
120 
121 template <typename Real>
123 {
124  return 2;
125 }
126 
127 template <typename Real>
128 Real ApprGaussian3<Real>::Error(Vector3<Real> const& observation) const
129 {
130  Vector3<Real> diff = observation - mParameters.center;
131  Real error = (Real)0;
132  for (int i = 0; i < 3; ++i)
133  {
134  if (mParameters.extent[i] >(Real)0)
135  {
136  Real ratio = Dot(diff, mParameters.axis[i]) /
137  mParameters.extent[i];
138  error += ratio * ratio;
139  }
140  }
141  return error;
142 }
143 
144 template <typename Real>
146  std::vector<Vector3<Real>> const& observations,
147  std::vector<int> const& indices)
148 {
149  if (static_cast<int>(indices.size()) >= GetMinimumRequired())
150  {
151  // Compute the mean of the points.
153  for (auto index : indices)
154  {
155  mParameters.center += observations[index];
156  }
157  Real invSize = ((Real)1) / (Real)indices.size();
158  mean *= invSize;
159 
160  // Compute the covariance matrix of the points.
161  Real covar00 = (Real)0, covar01 = (Real)0, covar02 = (Real)0;
162  Real covar11 = (Real)0, covar12 = (Real)0, covar22 = (Real)0;
163  for (auto index : indices)
164  {
165  Vector3<Real> diff = observations[index] - mean;
166  covar00 += diff[0] * diff[0];
167  covar01 += diff[0] * diff[1];
168  covar02 += diff[0] * diff[2];
169  covar11 += diff[1] * diff[1];
170  covar12 += diff[1] * diff[2];
171  covar22 += diff[2] * diff[2];
172  }
173  covar00 *= invSize;
174  covar01 *= invSize;
175  covar02 *= invSize;
176  covar11 *= invSize;
177  covar12 *= invSize;
178  covar22 *= invSize;
179 
180  // Solve the eigensystem.
182  std::array<Real, 3> eval;
183  std::array<std::array<Real, 3>, 3> evec;
184  es(covar00, covar01, covar02, covar11, covar12, covar22, false, +1,
185  eval, evec);
186  mParameters.center = mean;
187  mParameters.axis[0] = evec[0];
188  mParameters.axis[1] = evec[1];
189  mParameters.axis[2] = evec[2];
190  mParameters.extent = eval;
191  }
192 
193  mParameters.center = Vector3<Real>::Zero();
194  mParameters.axis[0] = Vector3<Real>::Zero();
195  mParameters.axis[1] = Vector3<Real>::Zero();
196  mParameters.axis[2] = Vector3<Real>::Zero();
197  mParameters.extent = Vector3<Real>::Zero();
198  return false;
199 }
200 
201 
202 }
bool Fit(int numPoints, Vector3< Real > const *points)
OrientedBox3< Real > mParameters
int GetMinimumRequired() const
GLfixed GLfixed GLint GLint GLfixed points
Definition: glext.h:4927
GLsizei GLenum const void * indices
Definition: glcorearb.h:401
static Vector Zero()
Definition: GteVector.h:295
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
OrientedBox3< Real > const & GetParameters() const
GLuint index
Definition: glcorearb.h:781
Real Error(Vector3< Real > const &observation) const


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:59