DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testDistanceTransformation.cpp
1 
30 
31 #include <iostream>
32 #include <iomanip>
33 #include "DGtal/base/Common.h"
34 
35 #include "DGtal/kernel/SpaceND.h"
36 #include "DGtal/kernel/domains/HyperRectDomain.h"
37 #include "DGtal/images/ImageSelector.h"
38 #include "DGtal/geometry/volumes/distance/DistanceTransformation.h"
39 #include "DGtal/io/colormaps/HueShadeColorMap.h"
40 #include "DGtal/io/colormaps/GrayscaleColorMap.h"
41 #include "DGtal/shapes/Shapes.h"
42 #include "DGtal/helpers/StdDefs.h"
43 #include "DGtal/shapes/ShapeFactory.h"
44 #include "DGtal/io/boards/Board2D.h"
45 #include "DGtal/kernel/sets/SetPredicate.h"
46 #include "DGtal/images/imagesSetsUtils/SimpleThresholdForegroundPredicate.h"
48 
49 using namespace std;
50 using namespace DGtal;
51 
53 // Functions for testing class DistanceTransformation.
55 
56 template<typename Image>
57 void randomSeeds(Image &input, const unsigned int nb, const int value)
58 {
59  typename Image::Point p, low = input.domain().lowerBound(), up = input.domain().upperBound();
60  typename Image::Vector ext;
61 
62  for (Dimension i = 0; i < Image::Domain::dimension; i++)
63  ext[i] = up[i] - low[i] + 1;
64 
65 
66  for (unsigned int k = 0 ; k < nb; k++)
67  {
68  for (unsigned int dim = 0; dim < Image::dimension; dim++)
69  {
70  p[dim] = rand() % (ext[dim]) + low[dim];
71  }
72  input.setValue(p, value);
73  }
74 }
75 
76 
77 
82 bool testDistanceTransformation()
83 {
84  unsigned int nbok = 0;
85  unsigned int nb = 0;
86 
87  trace.beginBlock ( "Testing the whole DT computation" );
88 
89  typedef SpaceND<2> TSpace;
90  typedef TSpace::Point Point;
92  typedef HueShadeColorMap<unsigned char, 2> HueTwice;
94  Point a ( 2, 2 );
95  Point b ( 15, 15 );
97  Image image ( Domain(a, b ));
98 
99  for ( unsigned k = 0; k < 49; k++ )
100  {
101  a[0] = ( k / 7 ) + 5;
102  a[1] = ( k % 7 ) + 5;
103  image.setValue ( a, 128 );
104  }
105  a= Point(2,2);
106 
108  Predicate aPredicate(image,0);
109 
110  DistanceTransformation<TSpace, Predicate , 2> dt(Domain(a,b),aPredicate);
112 
113  dt.checkTypesValidity ( );
114 
115  Board2D board;
117  Display2DFactory::drawImage<Gray>(board, image, (unsigned int)0, (unsigned int)255);
118  board.saveSVG ( "image-preDT.svg" );
119  //We just iterate on the Domain points and print out the point coordinates.
120  std::copy ( image.begin(),
121  image.end(),
122  std::ostream_iterator<unsigned int> ( std::cout, " " ) );
123 
124 
125 
126  ImageLong result = dt.compute ( );
127 
128  trace.warning() << result << endl;
129  //We just iterate on the Domain points and print out the point coordinates.
130  ImageLong::ConstIterator it = result.begin();
131  ImageLong::ConstIterator itend = result.end();
132  for (; it != itend; ++it)
133  {
134  std::cout << (*it) << " ";
135  }
136  std::cout << std::endl;
137 
138  board.clear();
139  Display2DFactory::drawImage<Gray>(board, result, (DGtal::int64_t)0, (DGtal::int64_t)16);
140  board.saveSVG ( "image-postDT.svg" );
141 
142 
143  trace.info() << result << endl;
144 
145  trace.endBlock();
146 
147  return nbok == nb;
148 }
153 bool testDistanceTransformationNeg()
154 {
155  unsigned int nbok = 0;
156  unsigned int nb = 0;
157 
158  trace.beginBlock ( "Testing the Neg DT computation" );
159 
160  typedef SpaceND<2> TSpace;
161  typedef TSpace::Point Point;
162  typedef HyperRectDomain<TSpace> Domain;
163  typedef HueShadeColorMap<unsigned char, 2> HueTwice;
165  Point a ( -10, -10 );
166  Point b ( 10, 10 );
168  Image image ( Domain( a, b ));
169 
170  for(int y=-10; y<=10;y++)
171  for(int x=-10; x<=10;x++)
172  {
173  if ((abs(x)<7) && (abs(y)<5))
174  image.setValue(Point(x,y),1);
175  else
176  image.setValue(Point(x,y),0);
177  }
178 
180  Predicate aPredicate(image,0);
181 
182 
183  DistanceTransformation<TSpace, Predicate , 2> dt(Domain(a,b), aPredicate);
185 
186  dt.checkTypesValidity ( );
187 
188  Board2D board;
190  Display2DFactory::drawImage<Gray>(board, image, (unsigned int)0, (unsigned int)1);
191  board.saveSVG ( "image-preDT-neg.svg" );
192 
193 
194  for(int y=-10; y<=10;y++)
195  {
196  for(int x=-10; x<=10;x++)
197  {
198  std::cout<<image(Point(x,y))<<" ";
199  }
200  std::cout<<std::endl;
201  }
202 
203 
204  ImageLong result = dt.compute ( );
205 
206  DGtal::int64_t maxv=0;
207  for(ImageLong::Iterator it = result.begin(), itend = result.end();
208  it != itend ; ++it)
209  if ((*it) > maxv)
210  maxv = (*it);
211 
212  for(int y=-10; y<=10;y++)
213  {
214  for(int x=-10; x<=10;x++)
215  {
216  std::cout<<result(Point(x,y))<<" ";
217  }
218  std::cout<<std::endl;
219  }
220 
221 
222 
223  trace.warning() << result << endl;
224 
225  board.clear();
226  Display2DFactory::drawImage<Gray>(board, result, (DGtal::int64_t)0, (DGtal::int64_t)maxv);
227  board.saveSVG ( "image-postDT-neg.svg" );
228 
229 
230  trace.info() << result << endl;
231 
232  trace.endBlock();
233 
234  return nbok == nb;
235 }
236 
237 
238 bool testDTFromSet()
239 {
240  unsigned int nbok = 0;
241  unsigned int nb = 0;
242 
243  trace.beginBlock ( "Testing the whole DT computation from a Set" );
244 
245  typedef SpaceND<2> TSpace;
246  typedef TSpace::Point Point;
247  typedef HyperRectDomain<TSpace> Domain;
250 
251 
252  Board2D board;
253 
254  AccFlower2D<Z2i::Space> flower(Z2i::Point(0,0), 30, 5,2,0);
255  Z2i::Domain domain(flower.getLowerBound(), flower.getUpperBound());
256  Z2i::DigitalSet aSet(domain);
257 
259 
260  SetPredicate<Z2i::DigitalSet> aPredicate(aSet);
261 
262 
264  typedef DistanceTransformation<TSpace,SetPredicate<Z2i::DigitalSet>, 2>::OutputImage ImageLong;
266  typedef DistanceTransformation<TSpace, SetPredicate<Z2i::DigitalSet>, 0>::OutputImage ImageLong0;
267  DistanceTransformation<TSpace, SetPredicate<Z2i::DigitalSet>, 1> dt1(domain,aPredicate);
268  typedef DistanceTransformation<TSpace, SetPredicate<Z2i::DigitalSet>,1>::OutputImage ImageLong1;
269 
270 
271  ImageLong result = dt.compute ( );
272  ImageLong0 result0 = dt0.compute ( );
273  ImageLong1 result1 = dt1.compute ( );
274 
275  trace.warning() << result << endl;
276 
277  DGtal::int64_t maxv = 0;
278  for ( ImageLong::Iterator it = result.begin(), itend = result.end();
279  it != itend; ++it)
280  if ( (*it) > maxv)
281  maxv = (*it);
282  trace.error() << "MaxV="<<maxv<<std::endl;
283  Display2DFactory::drawImage<Hue>(board, result, (DGtal::int64_t)0, (DGtal::int64_t)maxv+1);
284  board.saveSVG ( "image-DTSet.svg" );
285 
286  board.clear();
287  maxv = 0;
288  for ( ImageLong::Iterator it = result0.begin(), itend = result0.end();
289  it != itend; ++it)
290  if ( (*it) > maxv)
291  maxv = (*it);
292  trace.error() << "MaxV="<<maxv<<std::endl;
293  Display2DFactory::drawImage<Hue>(board, result0, (DGtal::int64_t)0, (DGtal::int64_t)maxv+1);
294  board.saveSVG ( "image-DTSet-linfty.svg" );
295 
296  board.clear();
297  maxv = 0;
298  for ( ImageLong::Iterator it = result1.begin(), itend = result1.end();
299  it != itend; ++it)
300  if ( (*it) > maxv)
301  maxv = (*it);
302  trace.error() << "MaxV="<<maxv<<std::endl;
303  Display2DFactory::drawImage<Hue>(board, result1, (DGtal::int64_t)0, (DGtal::int64_t)maxv+1);
304  board.saveSVG ( "image-DTSet-l1.svg" );
305  trace.endBlock();
306 
307  return nbok == nb;
308 }
309 
314 bool testDistanceTransformationBorder()
315 {
316  unsigned int nbok = 0;
317  unsigned int nb = 0;
318 
319  trace.beginBlock ( "Testing DT computation with Infinity values at the first step" );
320 
321  typedef SpaceND<2> TSpace;
322  typedef TSpace::Point Point;
323  typedef HyperRectDomain<TSpace> Domain;
326 
327  Point a (0, 0 );
328  Point b ( 128, 128 );
329 
331  Image image ( Domain(a, b ));
332 
333  for ( Image::Iterator it = image.begin(), itend = image.end();it != itend; ++it)
334  *it = 128 ;
335 
336 
337  randomSeeds(image, 19, 0);
338 
340  Predicate aPredicate(image,0);
341 
342  DistanceTransformation<TSpace, Predicate, 2> dt(Domain(a,b), aPredicate);
344 
345  dt.checkTypesValidity ( );
346 
347  Board2D board;
349  Display2DFactory::drawImage<Hue>(board, image, (unsigned int)0, (unsigned int)150);
350  board.saveSVG ( "image-preDT-border.svg" );
351 
352 
353  ImageLong result = dt.compute ( );
354 
355  DGtal::int64_t maxv = 0;
356  for ( ImageLong::Iterator it = result.begin(), itend = result.end();it != itend; ++it)
357  if ( (*it) > maxv)
358  maxv = (*it);
359 
360  ImageLong::ConstIterator it = result.begin();
361  for (unsigned int y = 0; y < 33; y++)
362  {
363  for (unsigned int x = 0; x < 33; x++)
364  {
365  std::cout << std::setw(4) << (*it) << " ";
366  ++it;
367  }
368  std::cout << std::endl;
369  }
370 
371  trace.warning() << result << "MaxV = " << maxv << endl;
372 
373 
374  board.clear();
375  Display2DFactory::drawImage<Hue>(board, result, (DGtal::int64_t)0, (DGtal::int64_t)maxv+1);
376  board.saveSVG ( "image-postDT-border.svg" );
377 
378 
379  trace.info() << result << endl;
380 
381  trace.endBlock();
382 
383  return nbok == nb;
384 }
385 
386 
391 bool testDistanceTransformation3D()
392 {
393  unsigned int nbok = 0;
394  unsigned int nb = 0;
395 
396  trace.beginBlock ( "Testing 3D DT computation" );
397 
398  typedef SpaceND<3> TSpace;
399  typedef TSpace::Point Point;
400  typedef HyperRectDomain<TSpace> Domain;
401  typedef HueShadeColorMap<unsigned char, 2> HueTwice;
403  Point a ( 0, 0, 0 );
404  Point b ( 15, 15, 15 );
406  Image image ( Domain(a, b ));
407  Point c(8, 8, 8);
408  Domain dom(a, b);
409 
410  for (Domain::ConstIterator it = dom.begin(),
411  itend = dom.end(); it != itend; ++it)
412  {
413  if ( ((*it) - c).norm() < 7)
414  image.setValue ( *it, 128 );
415  }
416 
418  Predicate aPredicate(image,0);
419 
420 
421  DistanceTransformation<TSpace, Predicate, 2> dt(Domain(a,b), aPredicate);
423 
424  dt.checkTypesValidity ( );
425 
426  ImageLong result = dt.compute ( );
427 
428  //We display the values on a 2D slice
429  for (unsigned int y = 0; y < 16; y++)
430  {
431  for (unsigned int x = 0; x < 16; x++)
432  {
433  Point p(x, y, 8);
434  std::cout << result(p) << " ";
435  }
436  std::cout << std::endl;
437  }
438 
439 
440  trace.warning() << result << endl;
441 
442  trace.endBlock();
443 
444  return nbok == nb;
445 }
446 
451 bool testTypeValidity()
452 {
453  unsigned int nbok = 0;
454  unsigned int nb = 0;
455 
456  trace.beginBlock ( "Testing type checker" );
457 
458  typedef SpaceND<2> TSpace;
459  typedef TSpace::Point Point;
460  typedef HyperRectDomain<TSpace> Domain;
461 
462  Point a ( 0, 0 );
463  Point b ( 15, 15 );
465  Image image ( Domain(a, b ));
466 
468  Predicate aPredicate(image,0);
469 
470 
471  DistanceTransformation<TSpace, Predicate, 2> dt(Domain(a,b), aPredicate);
473 
474  //No problem should be reported on the std:cerr.
475  dt.checkTypesValidity ( );
476 
477  DistanceTransformation<TSpace, Predicate, 34> dt34(Domain(a,b), aPredicate);
478 
479  //Type problem should be reported.
480  dt34.checkTypesValidity ( );
481 
482  trace.endBlock();
483  return nbok == nb;
484 }
485 
486 
487 bool testChessboard()
488 {
489  unsigned int nbok = 0;
490  unsigned int nb = 0;
491 
492  trace.beginBlock ( "Testing DT computation with Infinity values at the first step" );
493 
494  typedef SpaceND<2> TSpace;
495  typedef TSpace::Point Point;
496  typedef HyperRectDomain<TSpace> Domain;
499 
500  Point a (0, 0 );
501  Point b ( 128, 128 );
502 
504  Image image ( Domain( a, b ));
505 
506  for ( Image::Iterator it = image.begin(), itend = image.end();it != itend; ++it)
507  (*it) = 128;
508 
509 
510  randomSeeds(image, 19, 0);
511 
512  typedef ImageSelector<Domain, long int>::Type ImageLong;
513 
515  Predicate aPredicate(image,0);
516 
517 
518  //L_euc metric
520  DT2 dt2(Domain(a,b), aPredicate);
521 
522  //L_infinity metric
524  DT dt(Domain(a,b), aPredicate);;
525 
526  //L_1 metric
528  DT1 dt1(Domain(a,b), aPredicate);;
529 
530  DT::OutputImage result = dt.compute ( );
531  DT1::OutputImage result1 = dt1.compute ( );
532  DT2::OutputImage result2 = dt2.compute ();
533 
534  DGtal::int64_t maxv = 0;
535  for ( DT::OutputImage::Iterator it = result.begin(), itend = result.end();it != itend; ++it)
536  if ( (*it) > maxv)
537  maxv = (*it);
538 
539  //DT::OutputImage::ConstIterator it = result.begin();
540 
541  trace.warning() << result << "MaxV = " << maxv << endl;
542  //We display the values on a 2D slice
543  for (unsigned int y = 0; y < 16; y++)
544  {
545  for (unsigned int x = 0; x < 16; x++)
546  {
547  Point p(x, y);
548  std::cout << std::setw(4) << result(p) << " ";
549  }
550  std::cout << std::endl;
551  }
552 
553  trace.info()<< "Exporting to SVG"<<endl;
554 
555  Board2D board;
557  Display2DFactory::drawImage<Hue>(board, result, (DGtal::int64_t)0, (DGtal::int64_t)maxv+1);
558  board.saveSVG ( "image-DT-linfty.svg" );
559  trace.info()<< "done"<<endl;
560 
561 
562 
563  trace.info()<< "max L1"<<endl;
564  maxv = 0;
565  for ( DT1::OutputImage::Iterator it2 = result1.begin(),
566  itend = result1.end();
567  it2 != itend; ++it2)
568  {
569  if ( *it2 > maxv)
570  maxv = (*it2);
571  }
572 
573  trace.info()<< "Exporting to SVG L1"<<endl;
574  board.clear();
575  Display2DFactory::drawImage<Hue>(board, result1, (DGtal::int64_t)0, (DGtal::int64_t)maxv+1);
576  board.saveSVG ( "image-DT-l1.svg" );
577  trace.info()<< "done"<<endl;
578 
579  trace.info()<< "max Leuc"<<endl;
580  maxv = 0;
581  for ( DT2::OutputImage::Iterator it = result2.begin(), itend = result2.end();
582  it != itend; ++it)
583  {
584  if ( (*it) > maxv)
585  maxv = (*it);
586  }
587 
588  trace.info()<< "Exporting to SVG L2"<<endl;
589  board.clear();
590  Display2DFactory::drawImage<Hue>(board, result2, (DGtal::int64_t)0, (DGtal::int64_t)maxv+1);
591  board.saveSVG ( "image-DT-l2.svg" );
592  trace.info()<< "done"<<endl;
593  trace.info() << result << endl;
594 
595  trace.endBlock();
596 
597  return nbok == nb;
598 }
599 
601 // Standard services - public :
602 
603 int main ( int argc, char** argv )
604 {
605  trace.beginBlock ( "Testing class DistanceTransformation" );
606  trace.info() << "Args:";
607  for ( int i = 0; i < argc; ++i )
608  trace.info() << " " << argv[ i ];
609  trace.info() << endl;
610 
611  bool res = testTypeValidity() && testDistanceTransformation() && testDistanceTransformationNeg()
612  && testDTFromSet()
613  && testDistanceTransformationBorder()
614  && testDistanceTransformation3D()
615  && testChessboard()
616  && testDTFromSet();
617  //&& ... other tests
618  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
619  trace.endBlock();
620  return res ? 0 : 1;
621 }
622 // //