BitmapPrimitiveShape.cpp
Go to the documentation of this file.
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>
13using namespace MiscLib;
14
15void
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
25void
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
36bool
37BitmapPrimitiveShape::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
109size_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
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
165 bitmapInfo.bitmap, bitmapInfo.uextent, bitmapInfo.vextent, uwrap, vwrap, &tempBmp);
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
186 bitmapInfo.bbox, epsilon, bitmapInfo.uextent, bitmapInfo.vextent, &componentsImg, &labels);
187
188 return labels.size();
189}
190
191size_t
193 float epsilon,
195 bool doFiltering,
196 float* borderRatio)
197{
198 MiscLib::Vector<int> componentsImg;
200
201 BitmapInfo bitmapInfo;
203 pc, epsilon, bitmapInfo, indices, componentsImg, labels, doFiltering) <= 1)
204 {
205 return 0;
206 }
207
208 size_t size = indices->size();
209 MiscLib::Vector<size_t>::iterator begin = indices->begin();
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
331void
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
343void
345 float epsilon,
346 size_t begin,
347 size_t end,
348 PointCloud* bmpPc) const
349{
350 // constructing the bitmap is similar to ConnectedComponent
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
406void
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
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}
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
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
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
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
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
void TrimmingPolygons(const PointCloud &pc, float epsilon, size_t begin, size_t end, std::deque< ComponentPolygons > *polys) const
virtual void WrapBitmap(const GfxTL::AABox< GfxTL::Vector2Df > &bbox, float epsilon, bool *uwrap, bool *vwrap) const =0
virtual void PreWrapBitmap(const GfxTL::AABox< GfxTL::Vector2Df > &bbox, float epsilon, size_t uextent, size_t vextent, MiscLib::Vector< char > *bmp) const
virtual bool InSpace(float u, float v, Vec3f *p, Vec3f *n) const =0
bool Init(bool binary, std::istream *i)
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
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)
void BuildBitmap(const PointCloud &pc, float *epsilon, IteratorT begin, IteratorT end, MiscLib::Vector< std::pair< float, float > > *params, GfxTL::AABox< GfxTL::Vector2Df > *bbox, MiscLib::Vector< char > *bitmap, size_t *uextent, size_t *vextent, MiscLib::Vector< size_t > *bmpIdx) const
GfxTL::AABox< GfxTL::Vector2Df > m_extBbox
size_t ConnectedComponent(const PointCloud &pc, float epsilon, MiscLib::Vector< size_t > *indices, bool doFiltering=true, float *borderRatio=0)
void GenerateBitmapPoints(const PointCloud &pc, float epsilon, size_t begin, size_t end, PointCloud *bmpPc) const
Point & Min()
Definition AABox.hpp:68
Point & Max()
Definition AABox.hpp:82
void resize(size_type s, const value_type &v)
Definition Vector.h:227
size_type size() const
Definition Vector.h:215
VectorXD< 2, float > Vector2Df
Definition VectorXD.h:716
MiscLib::Vector< char > bitmap
GfxTL::AABox< GfxTL::Vector2Df > bbox
MiscLib::Vector< std::pair< float, float > > params
MiscLib::Vector< size_t > bmpIdx