BitmapPrimitiveShape.cpp
Go to the documentation of this file.
1 #include "BitmapPrimitiveShape.h"
2 
3 #include <float.h>
4 
5 #include <fstream>
6 #include <iomanip>
7 #include <iostream>
8 #include <sstream>
9 
10 #include "Bitmap.h"
11 #include "IndexIterator.h"
12 #include <MiscLib/Performance.h>
13 using namespace MiscLib;
14 
15 void
17  float epsilon,
18  size_t uextent,
19  size_t vextent,
20  MiscLib::Vector<char>* bmp) const
21 {
22  // the default case is: do nothing
23 }
24 
25 void
27  float epsilon,
28  size_t uextent,
29  size_t vextent,
30  MiscLib::Vector<int>* componentImg,
31  MiscLib::Vector<std::pair<int, size_t>>* labels) const
32 {
33  // default: do nothing
34 }
35 
36 bool
37 BitmapPrimitiveShape::Init(bool binary, std::istream* i)
38 {
39  if (binary)
40  {
42  size_t uextent, vextent;
43  // read number of components
44  size_t size;
45  i->read((char*)&size, sizeof(size));
46  if (size)
47  {
48  // read bbox
49  i->read((char*)&bbox, sizeof(bbox));
50  // read uextent and vextent
51  i->read((char*)&uextent, sizeof(uextent));
52  i->read((char*)&vextent, sizeof(vextent));
53  // read every component
54  for (size_t j = 0; j < size; ++j)
55  {
56  // read number of polys in component
57  size_t numPolys;
58  i->read((char*)&numPolys, sizeof(numPolys));
59  for (size_t k = 0; k < numPolys; ++k)
60  {
61  // read number of points in poly
62  size_t numPoints;
63  i->read((char*)&numPoints, sizeof(numPoints));
65  for (size_t l = 0; l < numPoints; ++l)
66  {
67  i->read((char*)&pp, sizeof(pp));
68  }
69  }
70  }
71  }
72  }
73  else
74  {
76  size_t uextent, vextent;
77  // read number of components
78  size_t size;
79  (*i) >> size;
80  if (size)
81  {
82  // read bbox
83  (*i) >> bbox.Min()[0] >> bbox.Max()[0] >> bbox.Min()[1] >> bbox.Max()[1];
84  // read uextent and vextent
85  (*i) >> uextent >> vextent;
86  // read every component
87  for (size_t j = 0; j < size; ++j)
88  {
89  // read number of polys in component
90  size_t numPolys;
91  (*i) >> numPolys;
92  for (size_t k = 0; k < numPolys; ++k)
93  {
94  // read number of points in poly
95  size_t numPoints;
96  (*i) >> numPoints;
98  for (size_t l = 0; l < numPoints; ++l)
99  {
100  (*i) >> pp[0] >> pp[1];
101  }
102  }
103  }
104  }
105  }
106  return true;
107 }
108 
109 size_t
111  float epsilon,
112  BitmapInfo& bitmapInfo,
114  MiscLib::Vector<int>& componentsImg,
115  MiscLib::Vector<std::pair<int, size_t>>& labels,
116  bool doFiltering)
117 {
118  // first find the extent in the parametrization
119  // but remember the parametrized points for projection into a bitmap
120  size_t size = indices->size();
121  if (!size)
122  {
123  return 0;
124  }
125 
126  // set up bitmap
128 
129  BuildBitmap(pc,
130  &epsilon,
131  indices->begin(),
132  indices->end(),
133  &bitmapInfo.params,
134  &bitmapInfo.bbox,
135  &bitmapInfo.bitmap,
136  &bitmapInfo.uextent,
137  &bitmapInfo.vextent,
138  &bitmapInfo.bmpIdx);
139 
140  /*static int fname_int = 0;
141  std::ostringstream fn;
142  fn << "bitmapImg" << fname_int++ << ".txt";
143  std::ofstream file;
144  file.open(fn.str().c_str(), std::ios::out);
145  for(size_t j = 0; j < vextent; ++j)
146  {
147  for(size_t i = 0; i < uextent; ++i)
148  file << bitmap[j * uextent + i];
149  file << std::endl;
150  }
151  file.close();*/
152 
153  // do a wrapping by copying pixels
154  PreWrapBitmap(
155  bitmapInfo.bbox, epsilon, bitmapInfo.uextent, bitmapInfo.vextent, &bitmapInfo.bitmap);
156 
157  MiscLib::Vector<char> tempBmp(bitmapInfo.bitmap.size()); // temporary bitmap object
158  bool uwrap, vwrap;
159  WrapBitmap(bitmapInfo.bbox, epsilon, &uwrap, &vwrap);
160 
161  if (doFiltering)
162  {
163  // closing
164  DilateCross(
165  bitmapInfo.bitmap, bitmapInfo.uextent, bitmapInfo.vextent, uwrap, vwrap, &tempBmp);
166  ErodeCross(
167  tempBmp, bitmapInfo.uextent, bitmapInfo.vextent, uwrap, vwrap, &bitmapInfo.bitmap);
168  // opening
169  //ErodeCross(bitmap, uextent, vextent, uwrap, vwrap, &tempBmp);
170  //DilateCross(tempBmp, uextent, vextent, uwrap, vwrap, &bitmap);
171  }
172 
173  Components(bitmapInfo.bitmap,
174  bitmapInfo.uextent,
175  bitmapInfo.vextent,
176  uwrap,
177  vwrap,
178  &componentsImg,
179  &labels);
180  if (labels.size() <= 1) // found no connected component!
181  {
182  return 0; // associate no points with this shape
183  }
184 
185  WrapComponents(
186  bitmapInfo.bbox, epsilon, bitmapInfo.uextent, bitmapInfo.vextent, &componentsImg, &labels);
187 
188  return labels.size();
189 }
190 
191 size_t
193  float epsilon,
195  bool doFiltering,
196  float* borderRatio)
197 {
198  MiscLib::Vector<int> componentsImg;
200 
201  BitmapInfo bitmapInfo;
202  if (AllConnectedComponents(
203  pc, epsilon, bitmapInfo, indices, componentsImg, labels, doFiltering) <= 1)
204  {
205  return 0;
206  }
207 
208  size_t size = indices->size();
210 
211  // find the largest component
212  size_t maxComp = 1;
213  for (size_t i = 2; i < labels.size(); ++i)
214  if (labels[maxComp].second < labels[i].second)
215  {
216  maxComp = i;
217  }
218 
220  bbox.Min() = GfxTL::Vector2Df(std::numeric_limits<float>::infinity(),
221  std::numeric_limits<float>::infinity());
222  bbox.Max() = -bbox.Min();
223  // compute bbox and update indices
224  size_t offset = 0;
225  for (size_t i = 0; i < size; ++i)
226  {
227  if (componentsImg[bitmapInfo.bmpIdx[i]] == labels[maxComp].first)
228  {
229  std::swap(begin[offset], begin[i]);
230  offset++;
231  // update bounding box
232  if (bbox.Min()[0] > bitmapInfo.params[i].first)
233  {
234  bbox.Min()[0] = bitmapInfo.params[i].first;
235  }
236  if (bbox.Max()[0] < bitmapInfo.params[i].first)
237  {
238  bbox.Max()[0] = bitmapInfo.params[i].first;
239  }
240  if (bbox.Min()[1] > bitmapInfo.params[i].second)
241  {
242  bbox.Min()[1] = bitmapInfo.params[i].second;
243  }
244  if (bbox.Max()[1] < bitmapInfo.params[i].second)
245  {
246  bbox.Max()[1] = bitmapInfo.params[i].second;
247  }
248  }
249  }
250 
251  // ratio between border and connected-comp size should be calculated if borderRatio is a valid pointer
252  if (borderRatio)
253  {
254  int borderPixels = 0;
255  int maxLabel = labels[maxComp].first;
256  int row = bitmapInfo.uextent;
257  int pos = 0;
258  char numNeighbours = 0;
259  int ccSize = 0;
260 
261  // test neightbourhood for all bitmappixels that are not marginal
262  for (size_t v = 1; v < bitmapInfo.vextent - 1; ++v)
263  {
264  for (size_t u = 1; u < bitmapInfo.uextent - 1; ++u)
265  {
266  pos = row + u;
267 
268  if (componentsImg[pos] == maxLabel)
269  {
270  ccSize++;
271  numNeighbours = bitmapInfo.bitmap[pos - 1] + bitmapInfo.bitmap[pos + 1] +
272  bitmapInfo.bitmap[pos - bitmapInfo.uextent - 1] +
273  bitmapInfo.bitmap[pos - bitmapInfo.uextent + 1] +
274  bitmapInfo.bitmap[pos + bitmapInfo.uextent - 1] +
275  bitmapInfo.bitmap[pos + bitmapInfo.uextent + 1] +
276  bitmapInfo.bitmap[pos - bitmapInfo.uextent] +
277  bitmapInfo.bitmap[pos + bitmapInfo.uextent];
278 
279  if ((int)numNeighbours != 8)
280  {
281  ++borderPixels;
282  }
283  }
284  }
285  row += bitmapInfo.uextent;
286  }
287 
288  // check left/right margins
289  row = bitmapInfo.uextent;
290  for (size_t v = 1; v < bitmapInfo.vextent - 1; ++v)
291  {
292  ccSize++;
293  if (componentsImg[row] == maxLabel)
294  {
295  ++borderPixels;
296  }
297 
298  ccSize++;
299  if (componentsImg[row + bitmapInfo.uextent - 1] == maxLabel)
300  {
301  ++borderPixels;
302  }
303 
304  row += bitmapInfo.uextent;
305  }
306 
307  // check top/bottom margins
308  row = (bitmapInfo.vextent - 1) * bitmapInfo.uextent;
309  for (size_t u = 0; u < bitmapInfo.uextent; ++u)
310  {
311  ccSize++;
312  if (componentsImg[u] == maxLabel)
313  {
314  ++borderPixels;
315  }
316 
317  ccSize++;
318  if (componentsImg[row + u] == maxLabel)
319  {
320  ++borderPixels;
321  }
322  }
323 
324  *borderRatio = static_cast<float>(borderPixels) / static_cast<float>(ccSize);
325  }
326 
327  m_extBbox = bbox;
328  return offset;
329 }
330 
331 void
333  float epsilon,
334  size_t begin,
335  size_t end,
336  std::deque<ComponentPolygons>* polys) const
337 {
339  size_t uextent, vextent;
340  BuildPolygons(pc, epsilon, begin, end, &bbox, &uextent, &vextent, polys);
341 }
342 
343 void
345  float epsilon,
346  size_t begin,
347  size_t end,
348  PointCloud* bmpPc) const
349 {
350  // constructing the bitmap is similar to ConnectedComponent
351  MiscLib::Vector<std::pair<float, float>> params, extParams;
352  MiscLib::Vector<char> bitmap;
355  size_t uextent, vextent;
356  BuildBitmap(pc,
357  &epsilon,
358  IndexIterator(begin),
359  IndexIterator(end),
360  &params,
361  &bbox,
362  &bitmap,
363  &uextent,
364  &vextent,
365  &bmpIdx);
366  m_extBbox = bbox;
367 
368  //// do closing
369  //MiscLib::Vector< char > tempBmp(bitmap.size());
370  //DilateSquare(bitmap, uextent, vextent, false, false, &tempBmp);
371  //ErodeSquare(tempBmp, uextent, vextent, false, false, &bitmap);
372  //// do opening
373  //ErodeSquare(bitmap, uextent, vextent, false, false, &tempBmp);
374  //DilateSquare(tempBmp, uextent, vextent, false, false, &bitmap);
375 
376  if (bmpPc)
377  {
378  size_t count = 0;
379  for (size_t i = 0; i < vextent * uextent; ++i)
380  {
381  // create point on surface
382  if (!bitmap[i])
383  {
384  continue;
385  }
386  if (count >= bmpPc->size())
387  {
388  bmpPc->resize(2 * count + 1);
389  }
390  if (InSpace(i % uextent,
391  i / uextent,
392  epsilon,
393  bbox,
394  uextent,
395  vextent,
396  &(*bmpPc)[count].pos,
397  &(*bmpPc)[count].normal))
398  {
399  ++count;
400  }
401  }
402  bmpPc->resize(count);
403  }
404 }
405 
406 void
408  float epsilon,
409  size_t begin,
410  size_t end,
412  size_t* uextent,
413  size_t* vextent,
414  std::deque<ComponentPolygons>* polys) const
415 {
416  // curves are extracted in the following way:
417  // first the bitmap is constructed
418  // then connected components are found
419  // for each component the curves are found
420 
421  // constructing the bitmap is similar to ConnectedComponent
422  // -> use the same code
424  MiscLib::Vector<char> bitmap;
426  BuildBitmap(pc,
427  &epsilon,
428  IndexIterator(begin),
429  IndexIterator(end),
430  &params,
431  bbox,
432  &bitmap,
433  uextent,
434  vextent,
435  &bmpIdx);
436 
437  // do closing
438  MiscLib::Vector<char> tempBmp(bitmap.size());
439  DilateCross(bitmap, *uextent, *vextent, false, false, &tempBmp);
440  ErodeCross(tempBmp, *uextent, *vextent, false, false, &bitmap);
441 
442  // find connected components
443  MiscLib::Vector<int> componentsImg;
445  Components(bitmap, *uextent, *vextent, false, false, &componentsImg, &labels);
446  if (labels.size() <= 1) // found no connected component!
447  {
448  return;
449  }
450 
451  // for each component find all polygons
452  for (size_t i = 1; i < labels.size(); ++i)
453  {
454  polys->resize(polys->size() + 1);
455  ComponentLoops(componentsImg,
456  *uextent,
457  *vextent,
458  labels[i].first,
459  false,
460  false,
461  &(*polys)[polys->size() - 1]);
462  }
463 }
GfxTL::VectorXD
Definition: MatrixXX.h:24
DilateCross
void DilateCross(const MiscLib::Vector< char > &bitmap, size_t uextent, size_t vextent, bool uwrap, bool vwrap, MiscLib::Vector< char > *dilated)
Definition: Bitmap.cpp:144
GfxTL::AABox::Max
Point & Max()
Definition: AABox.hpp:82
BitmapPrimitiveShape::AllConnectedComponents
size_t AllConnectedComponents(const PointCloud &pc, float epsilon, BitmapInfo &bitmapInfo, MiscLib::Vector< size_t > *indices, MiscLib::Vector< int > &componentsImg, MiscLib::Vector< std::pair< int, size_t >> &labels, bool doFiltering=true)
Definition: BitmapPrimitiveShape.cpp:110
BitmapInfo::params
MiscLib::Vector< std::pair< float, float > > params
Definition: BitmapPrimitiveShape.h:24
Performance.h
BitmapPrimitiveShape::PreWrapBitmap
virtual void PreWrapBitmap(const GfxTL::AABox< GfxTL::Vector2Df > &bbox, float epsilon, size_t uextent, size_t vextent, MiscLib::Vector< char > *bmp) const
Definition: BitmapPrimitiveShape.cpp:16
MiscLib::Vector::resize
void resize(size_type s, const value_type &v)
Definition: Vector.h:227
ComponentLoops
void ComponentLoops(const MiscLib::Vector< int > &componentImg, size_t uextent, size_t vextent, int label, bool uwrap, bool vwrap, MiscLib::Vector< MiscLib::Vector< GfxTL::VectorXD< 2, size_t >>> *polys)
Definition: Bitmap.cpp:961
Bitmap.h
BitmapInfo::bmpIdx
MiscLib::Vector< size_t > bmpIdx
Definition: BitmapPrimitiveShape.h:27
BitmapInfo::bbox
GfxTL::AABox< GfxTL::Vector2Df > bbox
Definition: BitmapPrimitiveShape.h:26
MiscLib::Vector< char >
BitmapInfo
Definition: BitmapPrimitiveShape.h:22
BitmapPrimitiveShape::BuildPolygons
void BuildPolygons(const PointCloud &pc, float epsilon, size_t begin, size_t end, GfxTL::AABox< GfxTL::Vector2Df > *bbox, size_t *uextent, size_t *vextent, std::deque< ComponentPolygons > *polys) const
Definition: BitmapPrimitiveShape.cpp:407
armarx::armem::client::util::swap
void swap(SubscriptionHandle &first, SubscriptionHandle &second)
Definition: SubscriptionHandle.cpp:66
MiscLib::Vector::size
size_type size() const
Definition: Vector.h:215
BitmapPrimitiveShape::GenerateBitmapPoints
void GenerateBitmapPoints(const PointCloud &pc, float epsilon, size_t begin, size_t end, PointCloud *bmpPc) const
Definition: BitmapPrimitiveShape.cpp:344
BitmapPrimitiveShape::TrimmingPolygons
void TrimmingPolygons(const PointCloud &pc, float epsilon, size_t begin, size_t end, std::deque< ComponentPolygons > *polys) const
Definition: BitmapPrimitiveShape.cpp:332
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
MiscLib
Definition: AlignedAllocator.h:12
IndexIterator.h
BitmapPrimitiveShape::Init
bool Init(bool binary, std::istream *i)
Definition: BitmapPrimitiveShape.cpp:37
BitmapPrimitiveShape.h
for
for(;yybottom<=yytop;yybottom++)
Definition: Grammar.cpp:705
BitmapPrimitiveShape::WrapComponents
virtual void WrapComponents(const GfxTL::AABox< GfxTL::Vector2Df > &bbox, float epsilon, size_t uextent, size_t vextent, MiscLib::Vector< int > *componentImg, MiscLib::Vector< std::pair< int, size_t >> *labels) const
Definition: BitmapPrimitiveShape.cpp:26
ErodeCross
void ErodeCross(const MiscLib::Vector< char > &bitmap, size_t uextent, size_t vextent, bool uwrap, bool vwrap, MiscLib::Vector< char > *eroded)
Definition: Bitmap.cpp:425
PointCloud
Definition: PointCloud.h:85
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
BitmapInfo::vextent
size_t vextent
Definition: BitmapPrimitiveShape.h:28
GfxTL::AABox::Min
Point & Min()
Definition: AABox.hpp:68
BitmapPrimitiveShape::ConnectedComponent
size_t ConnectedComponent(const PointCloud &pc, float epsilon, MiscLib::Vector< size_t > *indices, bool doFiltering=true, float *borderRatio=0)
Definition: BitmapPrimitiveShape.cpp:192
GfxTL::Vector2Df
VectorXD< 2, float > Vector2Df
Definition: VectorXD.h:716
BitmapInfo::bitmap
MiscLib::Vector< char > bitmap
Definition: BitmapPrimitiveShape.h:25
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
Components
void Components(const MiscLib::Vector< char > &bitmap, size_t uextent, size_t vextent, bool uwrap, bool vwrap, MiscLib::Vector< int > *componentsImg, MiscLib::Vector< std::pair< int, size_t >> *labels)
Definition: Bitmap.cpp:596
BitmapInfo::uextent
size_t uextent
Definition: BitmapPrimitiveShape.h:28
IndexIterator
Definition: IndexIterator.h:9
GfxTL::AABox
Definition: AABox.h:19