Candidate.h
Go to the documentation of this file.
1 #ifndef CANDIDATE_HEADER
2 #define CANDIDATE_HEADER
3 #include <algorithm>
4 #include <limits>
5 
6 #include "Octree.h"
7 #include "PrimitiveShape.h"
8 #include "ScoreComputer.h"
10 #include <MiscLib/Random.h>
11 #include <MiscLib/RefCountPtr.h>
12 #include <MiscLib/RefCounted.h>
13 #include <MiscLib/Vector.h>
14 
15 #ifndef DLL_LINKAGE
16 #define DLL_LINKAGE
17 #endif
18 
20 {
21 public:
22  Candidate();
23  Candidate(PrimitiveShape* shape, size_t level);
24 
27  {
28  return m_shape;
29  }
30 
31  void
33  {
34  m_shape = shape;
35  }
36 
37  float
38  LowerBound() const
39  {
40  return m_lowerBound;
41  }
42 
43  float
44  UpperBound() const
45  {
46  return m_upperBound;
47  }
48 
51  {
52  return m_indices;
53  }
54 
55  void
57  {
58  m_indices = indices;
59  }
60 
61  size_t
63  {
64  return m_subset;
65  }
66 
67  float
68  ExpectedValue() const
69  {
70  return (m_lowerBound + m_upperBound) / 2.f;
71  }
72 
73  void
74  SetSubset(size_t subset)
75  {
76  m_subset = subset;
77  }
78 
79  size_t
80  Level() const
81  {
82  return m_level;
83  }
84 
85  void Reset();
86  template <class ScoreVisitorT>
87  bool ImproveBounds(const MiscLib::Vector<ImmediateOctreeType*>& octrees,
88  const PointCloud& pc,
89  ScoreVisitorT& scoreVisitor,
90  size_t currentSize,
91  float bitmapEpsilon,
92  size_t maxSubset,
93  size_t minPoints = 500);
94  template <class ScoreVisitorT>
95  void RecomputeBounds(const MiscLib::Vector<ImmediateOctreeType*>& octrees,
96  const PointCloud& pc,
97  ScoreVisitorT& scoreVisitor,
98  size_t currentSize,
99  float epsilon,
100  float normalThresh,
101  float bitmapEpsilon);
102  void Reindex(const MiscLib::Vector<int>& newIndices,
103  int minInvalidIndex,
104  size_t mergedSubsets,
105  const MiscLib::Vector<size_t>& subsetSizes,
106  const PointCloud& pc,
107  size_t currentSize,
108  float epsilon,
109  float normalThresh,
110  float bitmapEpsilon);
111  void Reindex(const MiscLib::Vector<size_t>& reindex);
112  template <class ScoreVisitorT>
113  void GlobalScore(ScoreVisitorT& scoreVisitor, const IndexedOctreeType& oct);
114  float WeightedScore(const PointCloud& pc, float epsilon, float normalThresh) const;
115  void ConnectedComponent(const PointCloud& pc, float bitmapEpsilon, float* borderRatio = 0);
116  template <class ScoreVisitorT>
117  float GlobalWeightedScore(ScoreVisitorT& scoreVisitor,
118  const IndexedOctreeType& oct,
119  const PointCloud& pc,
120  float epsilon,
121  float normalThresh,
122  float bitmapEpsilon);
123  inline bool operator<(const Candidate& c) const;
124  inline bool operator>(const Candidate& c) const;
125  inline bool operator<=(const Candidate& c) const;
126  inline bool operator>=(const Candidate& c) const;
127  inline void Clone(Candidate* c) const;
128  bool
129  IsEquivalent(const Candidate& c, const PointCloud& pc, float epsilon, float normalThresh) const;
130 
131  size_t
132  Size() const
133  {
134  return m_indices->size();
135  }
136 
137 private:
138  inline void GetBounds(size_t sampledPoints, size_t totalPoints);
139  inline void Induct(double totalSize,
140  double sampleSize,
141  double totalCorrectSize,
142  float* lower,
143  float* upper) const;
144  inline void Deduct(double totalSize,
145  double sampleSize,
146  double totalCorrectSize,
147  float* lower,
148  float* upper) const;
149 
150  void GetScore(const PointCloud& pc, float bitmapEpsilon, bool doFiltering);
151  void GetScoreMaxCCSize(const PointCloud& pc, float bitmapEpsilon, bool doFiltering);
152  void GetScoreMaxCCMinBorder(const PointCloud& pc, float bitmapEpsilon, bool doFiltering);
153 
154  float GetVariance(const PointCloud& pc);
155  float GetPseudoVariance(const PointCloud& pc);
156 
157 private:
159  size_t m_subset;
160  float m_lowerBound;
161  float m_upperBound;
163  size_t m_level;
164  bool m_hasConnectedComponent;
165  size_t m_score;
166 };
167 
168 bool
170 {
171  return ExpectedValue() < c.ExpectedValue();
172 }
173 
174 bool
176 {
177  return ExpectedValue() > c.ExpectedValue();
178 }
179 
180 bool
182 {
183  return ExpectedValue() <= c.ExpectedValue();
184 }
185 
186 bool
188 {
189  return ExpectedValue() >= c.ExpectedValue();
190 }
191 
192 void
194 {
195  c->m_shape = m_shape->Clone();
196  c->m_shape->Release();
197  c->m_subset = m_subset;
198  c->m_lowerBound = m_lowerBound;
199  c->m_upperBound = m_upperBound;
200  c->m_indices = new MiscLib::RefCounted<MiscLib::Vector<size_t>>(*m_indices);
201  c->m_indices->Release();
202  c->m_level = m_level;
203  ;
204  c->m_hasConnectedComponent = m_hasConnectedComponent;
205  c->m_score = m_score;
206 }
207 
208 void
209 Candidate::GetBounds(size_t sampledPoints, size_t totalPoints)
210 {
211  Induct(
212  (double)totalPoints, (double)sampledPoints, (double)m_score, &m_lowerBound, &m_upperBound);
213  m_lowerBound = std::max(0.f, m_lowerBound);
214 }
215 
216 void
217 Candidate::Induct(double totalSize,
218  double sampleSize,
219  double totalCorrectSize,
220  float* lower,
221  float* upper) const
222 {
223  Deduct(-2.0 - sampleSize, -2.0 - totalSize, -1.0 - totalCorrectSize, lower, upper);
224  *lower = -1.f - *lower;
225  *upper = -1.f - *upper;
226 }
227 
228 void
229 Candidate::Deduct(double totalSize,
230  double sampleSize,
231  double totalCorrectSize,
232  float* lower,
233  float* upper) const
234 {
235  double nI = sampleSize * totalCorrectSize;
236  double denom = nI * (totalSize - sampleSize) * (totalSize - totalCorrectSize);
237  double frac = denom / (totalSize - 1);
238  double dev = std::sqrt(frac);
239  *lower = float((nI - dev) / totalSize); // 95% quantile
240  *upper = float((nI + dev) / totalSize); // 95% quantile
241 }
242 
243 template <class ScoreVisitorT>
244 bool
246  const PointCloud& pc,
247  ScoreVisitorT& scoreVisitor,
248  size_t currentSize,
249  float bitmapEpsilon,
250  size_t maxSubset,
251  size_t minPoints)
252 {
253  if (m_subset >= maxSubset)
254  {
255  return false;
256  }
257  if (m_subset >= octrees.size())
258  {
259  return false;
260  }
261 
262  size_t sampledPoints = 0;
263  for (size_t i = 0; i < m_subset; ++i)
264  {
265  sampledPoints += octrees[i]->size();
266  }
267 
268  size_t newlySampledPoints = 0;
269  scoreVisitor.SetIndices(m_indices);
270  do
271  {
272  scoreVisitor.SetOctree(*octrees[m_subset]);
273  m_shape->Visit(&scoreVisitor);
274  newlySampledPoints += octrees[m_subset]->size();
275  sampledPoints += octrees[m_subset]->size();
276  ++m_subset;
277  } while (m_subset < octrees.size() && newlySampledPoints < minPoints);
278 
279  m_score = m_indices->size();
280  GetBounds(sampledPoints, currentSize);
281 
282  // check if connected component is worthwhile
283  if (m_subset == 1)
284  {
285  return true;
286  }
287  if (m_hasConnectedComponent ||
288  (2.f * (m_upperBound - (m_lowerBound / .7f)) / (m_upperBound + (m_lowerBound / .7f))) < .3f)
289  {
290  if (!m_hasConnectedComponent && m_indices->size() < 2)
291  {
292  return true;
293  }
294  m_hasConnectedComponent = true;
295  m_score = m_shape->ConnectedComponent(
296  pc, (4 << ((octrees.size() - m_subset) / 2)) * bitmapEpsilon, m_indices, false);
297  m_indices->resize(m_score);
298  if (m_subset >= octrees.size())
299  {
300  GetScore(pc, bitmapEpsilon, true);
301  m_upperBound = m_lowerBound = m_score;
302  return true;
303  }
304  GetScore(pc, (2 << ((octrees.size() - m_subset) / 2)) * bitmapEpsilon, false);
305 
306  GetBounds(sampledPoints, currentSize);
307  }
308  return true;
309 }
310 
311 template <class ScoreVisitorT>
312 void
314  const PointCloud& pc,
315  ScoreVisitorT& scoreVisitor,
316  size_t currentSize,
317  float epsilon,
318  float normalThresh,
319  float bitmapEpsilon)
320 {
321  // run over indices and check if still unassigned
322  const MiscLib::Vector<int>& shapeIndex = scoreVisitor.GetShapeIndex();
323  size_t indicesSize = m_indices->size();
324  for (size_t i = 0; i < indicesSize;)
325  {
326  if (shapeIndex[(*m_indices)[i]] != -1)
327  {
328  --indicesSize;
329  std::swap((*m_indices)[i], (*m_indices)[indicesSize]);
330  }
331  else
332  {
333  ++i;
334  }
335  }
336 
337  m_score = indicesSize;
338 
339  if (m_hasConnectedComponent)
340  {
341  if (m_indices->size() != indicesSize) // dirty!
342  {
343  if ((float)indicesSize / m_indices->size() > 0.95)
344  {
345  m_indices->resize(indicesSize);
346 
347  GetScore(pc,
348  m_subset >= octrees.size()
349  ? bitmapEpsilon
350  : (4 << ((octrees.size() - m_subset) / 2)) * bitmapEpsilon,
351  m_subset >= octrees.size());
352 
353  if (m_subset >= octrees.size())
354  {
355  m_upperBound = m_lowerBound = (float)m_indices->size();
356  return;
357  }
358  // reevaluate bounds
359  }
360  else
361  {
362  m_subset = 0;
363  m_hasConnectedComponent = false;
364  m_indices->clear();
365  m_score = 0;
366  ImproveBounds(octrees, pc, scoreVisitor, currentSize, bitmapEpsilon, 1);
367  return;
368  }
369  }
370  else if (m_subset > octrees.size())
371  {
372  return;
373  }
374  // reevaluate bounds
375  }
376  else
377  {
378  m_indices->resize(indicesSize);
379  m_score = m_indices->size();
380  }
381  size_t sampledPoints = 0, endi = std::min(m_subset, octrees.size());
382  for (size_t i = 0; i < endi; ++i)
383  {
384  sampledPoints += octrees[i]->size();
385  }
386 
387  GetBounds(sampledPoints, currentSize);
388 }
389 
390 template <class ScoreVisitorT>
391 void
392 Candidate::GlobalScore(ScoreVisitorT& scoreVisitor, const IndexedOctreeType& oct)
393 {
394  m_indices->clear();
395  scoreVisitor.SetOctree(oct);
396  scoreVisitor.SetIndices(m_indices);
397  m_shape->Visit(&scoreVisitor);
398  m_lowerBound = m_upperBound = (float)m_indices->size();
399 }
400 
401 template <class ScoreVisitorT>
402 float
403 Candidate::GlobalWeightedScore(ScoreVisitorT& scoreVisitor,
404  const IndexedOctreeType& oct,
405  const PointCloud& pc,
406  float epsilon,
407  float normalThresh,
408  float bitmapEpsilon)
409 {
410  GlobalScore(scoreVisitor, oct);
411  ConnectedComponent(pc, bitmapEpsilon);
412  return WeightedScore(pc, epsilon, normalThresh);
413 }
414 
415 #endif
MiscLib::RefCounted
Definition: RefCounted.h:10
Vector.h
RefCounted.h
Candidate::Clone
void Clone(Candidate *c) const
Definition: Candidate.h:193
MiscLib::Vector::resize
void resize(size_type s, const value_type &v)
Definition: Vector.h:227
Candidate::operator<=
bool operator<=(const Candidate &c) const
Definition: Candidate.h:181
PrimitiveShape::ConnectedComponent
virtual size_t ConnectedComponent(const PointCloud &pc, float epsilon, MiscLib::Vector< size_t > *indices, bool doFiltering=true, float *borderRatio=0)=0
Candidate::ImproveBounds
bool ImproveBounds(const MiscLib::Vector< ImmediateOctreeType * > &octrees, const PointCloud &pc, ScoreVisitorT &scoreVisitor, size_t currentSize, float bitmapEpsilon, size_t maxSubset, size_t minPoints=500)
Definition: Candidate.h:245
Candidate::UpperBound
float UpperBound() const
Definition: Candidate.h:44
Candidate::ConnectedComponent
void ConnectedComponent(const PointCloud &pc, float bitmapEpsilon, float *borderRatio=0)
Definition: Candidate.cpp:100
Candidate::operator<
bool operator<(const Candidate &c) const
Definition: Candidate.h:169
Candidate::operator>=
bool operator>=(const Candidate &c) const
Definition: Candidate.h:187
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
PrimitiveShape
PrimtiveShape is a shape primitive in conjunction with a parametrization.
Definition: PrimitiveShape.h:34
Candidate::Size
size_t Size() const
Definition: Candidate.h:132
Candidate::operator>
bool operator>(const Candidate &c) const
Definition: Candidate.h:175
Candidate::RecomputeBounds
void RecomputeBounds(const MiscLib::Vector< ImmediateOctreeType * > &octrees, const PointCloud &pc, ScoreVisitorT &scoreVisitor, size_t currentSize, float epsilon, float normalThresh, float bitmapEpsilon)
Definition: Candidate.h:313
MiscLib::Vector< size_t >
Candidate::Shape
PrimitiveShape * Shape()
Definition: Candidate.h:26
Candidate
Definition: Candidate.h:19
armarx::armem::client::util::swap
void swap(SubscriptionHandle &first, SubscriptionHandle &second)
Definition: SubscriptionHandle.cpp:66
NoShrinkVector.h
RefCountPtr.h
MiscLib::Vector::size
size_type size() const
Definition: Vector.h:215
Candidate::ExpectedValue
float ExpectedValue() const
Definition: Candidate.h:68
Candidate::ComputedSubsets
size_t ComputedSubsets() const
Definition: Candidate.h:62
Candidate::GlobalWeightedScore
float GlobalWeightedScore(ScoreVisitorT &scoreVisitor, const IndexedOctreeType &oct, const PointCloud &pc, float epsilon, float normalThresh, float bitmapEpsilon)
Definition: Candidate.h:403
pcl::graph::indices
pcl::PointIndices::Ptr indices(const PCG &g)
Retrieve the indices of the points of the point cloud stored in a point cloud graph that actually bel...
Definition: point_cloud_graph.h:717
armarx::operator>=
bool operator>=(const RemoteHandle< PrxTA > &fst, const RemoteHandle< PrxTB > &snd)
Definition: RemoteHandle.h:320
Candidate::Indices
void Indices(MiscLib::RefCounted< MiscLib::Vector< size_t >> *indices)
Definition: Candidate.h:56
Candidate::Shape
void Shape(PrimitiveShape *shape)
Definition: Candidate.h:32
Candidate::SetSubset
void SetSubset(size_t subset)
Definition: Candidate.h:74
max
T max(T t1, T t2)
Definition: gdiam.h:51
IceStormElection::operator<
bool operator<(const ReplicaObserver &lhs, const ReplicaObserver &rhs)
Definition: Election.h:2564
Candidate::GlobalScore
void GlobalScore(ScoreVisitorT &scoreVisitor, const IndexedOctreeType &oct)
Definition: Candidate.h:392
MiscLib::RefCountPtr< PrimitiveShape >
Candidate::Indices
MiscLib::RefCounted< MiscLib::Vector< size_t > > * Indices()
Definition: Candidate.h:50
Candidate::Level
size_t Level() const
Definition: Candidate.h:80
PointCloud
Definition: PointCloud.h:85
Candidate::WeightedScore
float WeightedScore(const PointCloud &pc, float epsilon, float normalThresh) const
Definition: Candidate.cpp:88
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:704
float
#define float
Definition: 16_Level.h:22
Random.h
armarx::operator<=
bool operator<=(const RemoteHandle< PrxTA > &fst, const RemoteHandle< PrxTB > &snd)
Definition: RemoteHandle.h:304
DLL_LINKAGE
#define DLL_LINKAGE
Definition: basic.h:12
ScoreComputer.h
Octree.h
pc
Introduction Thank you for taking interest in our work and downloading this software This library implements the algorithm described in the paper R R R Klein Efficient RANSAC for Point Cloud Shape in Computer Graphics Blackwell June If you use this software you should cite the aforementioned paper in any resulting publication Please send comments or bug reports to Ruwen Roland BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE Example usage This section shows how to use the library to detect the shapes in a point cloud PointCloud pc
Definition: ReadMe.txt:68
min
T min(T t1, T t2)
Definition: gdiam.h:44
Candidate::LowerBound
float LowerBound() const
Definition: Candidate.h:38
MiscLib::Vector::clear
void clear()
Definition: Vector.h:175
PrimitiveShape.h
PrimitiveShape::Clone
virtual PrimitiveShape * Clone() const =0
GfxTL::AACubeTree
Definition: AACubeTree.h:338
PrimitiveShape::Visit
virtual void Visit(PrimitiveShapeVisitor *visitor) const =0
armarx::operator>
bool operator>(const RemoteHandle< PrxTA > &fst, const RemoteHandle< PrxTB > &snd)
Definition: RemoteHandle.h:312