DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testDecomposition.cpp
1 
16 //LICENSE-END
34 #include <cstdio>
35 #include <cmath>
36 #include <fstream>
37 #include <vector>
38 #include <iostream>
39 #include <iterator>
40 
41 
42 
43 
44 #include "DGtal/base/Common.h"
45 #include "DGtal/base/Exceptions.h"
46 #include "DGtal/io/boards/Board2D.h"
47 #include "DGtal/io/Color.h"
48 
49 #include "DGtal/geometry/curves/ArithmeticalDSS.h"
50 #include "DGtal/geometry/curves/FreemanChain.h"
51 #include "DGtal/geometry/curves/GreedyDecomposition.h"
52 
53 
54 #include "ConfigTest.h"
55 
56 
57 using namespace DGtal;
58 using namespace DGtal::deprecated;
59 using namespace std;
60 using namespace LibBoard;
61 
63 // Functions for testing class GreedyDecomposition.
65 
70 bool testDec4()
71 {
72 
73  typedef int Coordinate;
75  typedef FreemanChain<Coordinate> ContourType;
76 
78 
79  typedef GreedyDecomposition<PrimitiveType> DecompositionType;
80 
81 
82  std::string filename = testPath + "samples/manche.fc";
83  std::cout << filename << std::endl;
84 
85  std::fstream fst;
86  fst.open (filename.c_str(), std::ios::in);
87  ContourType theContour(fst);
88 
89  //Segmentation
90  trace.beginBlock("Segmentation of a chain code into DSS");
91  PrimitiveType computer;
92  DecompositionType theDecomposition(theContour.begin(), theContour.end(), computer, false);
93 
94  // Draw the grid
95  Board2D aBoard;
96  aBoard.setUnit(Board::UCentimeter);
97 
98  aBoard << SetMode("PointVector", "Grid")
99  << theContour;
100 
101  //for each segment
102  unsigned int compteur = 0;
103  DecompositionType::SegmentIterator i = theDecomposition.begin();
104  for ( ; i != theDecomposition.end(); ++i) {
105 
106  compteur++;
107  PrimitiveType segment(*i);
108  trace.info() << segment << std::endl; //standard output
109  aBoard << SetMode( "ArithmeticalDSS", "BoundingBox" )
110  << segment; // draw each segment
111 
112  }
113 
114  aBoard.saveSVG("segmentationDSS4.svg");
115 
116  trace.endBlock();
117  return (compteur==91);
118 }
119 
125 bool testDec8()
126 {
127 
128  typedef int Coordinate;
129  typedef PointVector<2,Coordinate> Point;
130  typedef std::vector<Point> ContourType;
132 
133  typedef GreedyDecomposition<PrimitiveType> DecompositionType;
134 
135  std::vector<Point> curve;
136  curve.push_back(Point(0,0));
137  curve.push_back(Point(1,1));
138  curve.push_back(Point(2,1));
139  curve.push_back(Point(3,2));
140  curve.push_back(Point(4,2));
141  curve.push_back(Point(5,2));
142  curve.push_back(Point(6,3));
143  curve.push_back(Point(6,4));
144  curve.push_back(Point(7,4));
145  curve.push_back(Point(8,4));
146  curve.push_back(Point(9,3));
147  curve.push_back(Point(10,2));
148  curve.push_back(Point(11,2));
149 
150  //Segmentation
151  trace.beginBlock("Segmentation of a 8-connected digital curve into DSS");
152  PrimitiveType computer;
153  DecompositionType theDecomposition(curve.begin(), curve.end(), computer, false);
154 
155  // Draw the pixels
156  Board2D aBoard;
157  aBoard.setUnit(Board::UCentimeter);
158  aBoard << SetMode("PointVector", "Both");
159  for (ContourType::iterator it = curve.begin(); it != curve.end(); ++it) {
160  aBoard << (*it);
161  }
162 
163 
164  //for each segment
165  unsigned int compteur = 0;
166  DecompositionType::SegmentIterator i = theDecomposition.begin();
167  for ( ; i != theDecomposition.end(); ++i) {
168 
169  compteur++;
170  trace.info() << "Segment " << compteur << std::endl;
171  PrimitiveType segment(*i);
172  trace.info() << segment << std::endl; //standard output
173  aBoard << SetMode( "ArithmeticalDSS", "BoundingBox" )
174  << segment; // draw each segment
175  }
176 
177  aBoard.saveSVG("segmentationDSS8.svg");
178 
179  trace.endBlock();
180 
181  return (compteur==4);
182 }
183 
189 bool testDisconnectedCurve()
190 {
191 
192  typedef int Coordinate;
193  typedef PointVector<2,Coordinate> Point;
194  typedef std::vector<Point> ContourType;
196 
197  typedef GreedyDecomposition<PrimitiveType> DecompositionType;
198 
199  std::vector<Point> curve;
200  curve.push_back(Point(-1,-1));
201  curve.push_back(Point(0,0));
202  curve.push_back(Point(1,0));
203  curve.push_back(Point(1,1));
204  curve.push_back(Point(2,1));
205  curve.push_back(Point(3,2));
206  curve.push_back(Point(4,2));
207  curve.push_back(Point(5,2));
208  curve.push_back(Point(6,2));
209  curve.push_back(Point(6,3));
210  curve.push_back(Point(6,4));
211  curve.push_back(Point(7,4));
212  curve.push_back(Point(8,4));
213  curve.push_back(Point(9,3));
214  curve.push_back(Point(9,2));
215  curve.push_back(Point(10,2));
216  curve.push_back(Point(11,2));
217 
218  //Segmentation
219  trace.beginBlock("Segmentation of disconnected digital curve");
220  PrimitiveType computer;
221  DecompositionType theDecomposition(curve.begin(), curve.end(), computer, false);
222 
223  // Draw the pixels
224  Board2D aBoard;
225  aBoard.setUnit(Board::UCentimeter);
226  aBoard << SetMode("PointVector", "Both");
227  for (ContourType::iterator it = curve.begin(); it != curve.end(); ++it) {
228  aBoard << (*it);
229  }
230 
231 
232  //for each segment
233  unsigned int compteur = 0;
234  DecompositionType::SegmentIterator i = theDecomposition.begin();
235  for ( ; i != theDecomposition.end(); ++i) {
236 
237  compteur++;
238  trace.info() << "Segment " << compteur << std::endl;
239  trace.info() << i.intersectPrevious() << " - " << i.intersectNext() << std::endl;
240  PrimitiveType segment(*i);
241  trace.info() << segment << std::endl; //standard output
242  aBoard << SetMode( segment.className(), "BoundingBox" )
243  << segment; // draw each segment
244  }
245 
246  aBoard.saveSVG("specialCase.svg");
247 
248  trace.endBlock();
249 
250  return (compteur==5);
251 
252 }
253 
258 bool testClosedCurvesProcessedAsClosed()
259 {
260 
261  trace.beginBlock ( "Test for closed curves processed as closed" );
262 
263 
264  typedef FreemanChain<int> Contour4;
266  typedef GreedyDecomposition<DSS4> Decomposition4;
267 
268  // A Freeman chain code is a string composed by the coordinates of the first pixel, and the list of elementary displacements.
269  std::stringstream ss(stringstream::in | stringstream::out);
270  ss << "31 16 1112121212121221212121221212212222232232323332333333332333332330333033003030000010001001001000100010101010111" << endl;
271 
272  // Construct the Freeman chain
273  Contour4 theContour( ss );
274 
275  //Segmentation
276  DSS4 computer;
277  Decomposition4 theDecomposition( theContour.begin(),theContour.end(),computer,true );
278 
279  Board2D aBoard;
280  aBoard << SetMode( "PointVector", "Grid" )
281  << theContour;
282  //for each segment
283  aBoard << SetMode( "ArithmeticalDSS", "BoundingBox" );
284  string className = "ArithmeticalDSS/BoundingBox";
285  for ( Decomposition4::SegmentIterator i = theDecomposition.begin();
286  i != theDecomposition.end(); ++i )
287  {
288 
289  DSS4 segment(*i);
290  aBoard << CustomStyle( className,
291  new CustomPenColor( Color::Blue ) )
292  << segment; // draw each segment
293 
294  }
295  aBoard.saveSVG("testClosedCurvesProcessedAsClosed.svg");
296 
297  trace.endBlock();
298 
299  return true;
300 }
301 
306 bool testClosedCurvesProcessedAsOpen()
307 {
308 
309  trace.beginBlock ( "Test for closed curves processed as open" );
310 
311  typedef FreemanChain<int> Contour4;
313  typedef GreedyDecomposition<DSS4> Decomposition4;
314 
315  // A Freeman chain code is a string composed by the coordinates of the first pixel, and the list of elementary displacements.
316  std::stringstream ss(stringstream::in | stringstream::out);
317  ss << "31 16 1112121212121221212121221212212222232232323332333333332333332330333033003030000010001001001000100010101010111" << endl;
318 
319  // Construct the Freeman chain
320  Contour4 theContour( ss );
321 
322  //Segmentation
323  DSS4 computer;
324  Decomposition4 theDecomposition( theContour.begin(),theContour.end(),computer,false );
325 
326  Board2D aBoard;
327  aBoard << SetMode( "PointVector", "Grid" )
328  << theContour;
329  //for each segment
330  aBoard << SetMode( "ArithmeticalDSS", "BoundingBox" );
331  string className = "ArithmeticalDSS/BoundingBox";
332  for ( Decomposition4::SegmentIterator i = theDecomposition.begin();
333  i != theDecomposition.end(); ++i )
334  {
335 
336  DSS4 segment(*i);
337  aBoard << CustomStyle( className,
338  new CustomPenColor( Color::Blue ) )
339  << segment; // draw each segment
340 
341  }
342  aBoard.saveSVG("testClosedCurvesProcessedAsOpen.svg");
343 
344  trace.endBlock();
345 
346  return true;
347 }
348 
353 bool testOpenCurvesProcessedAsClosed()
354 {
355 
356  trace.beginBlock ( "Test for open curves processed as closed" );
357 
358  typedef FreemanChain<int> Contour4;
360  typedef GreedyDecomposition<DSS4> Decomposition4;
361 
362  // A Freeman chain code is a string composed by the coordinates of the first pixel, and the list of elementary displacements.
363  std::stringstream ss(stringstream::in | stringstream::out);
364  ss << "31 16 1112121212121221212121221212212222232232323332333333332333" << endl;
365 
366  // Construct the Freeman chain
367  Contour4 theContour( ss );
368 
369  //Segmentation
370  DSS4 computer;
371  Decomposition4 theDecomposition( theContour.begin(),theContour.end(),computer,true );
372 
373  Board2D aBoard;
374  aBoard << SetMode( "PointVector", "Grid" )
375  << theContour;
376  //for each segment
377  aBoard << SetMode( "ArithmeticalDSS", "BoundingBox" );
378  string className = "ArithmeticalDSS/BoundingBox";
379  for ( Decomposition4::SegmentIterator i = theDecomposition.begin();
380  i != theDecomposition.end(); ++i )
381  {
382 
383  DSS4 segment(*i);
384  aBoard << CustomStyle( className,
385  new CustomPenColor( Color::Blue ) )
386  << segment; // draw each segment
387 
388  }
389  aBoard.saveSVG("testOpenCurvesProcessedAsClosed.svg");
390 
391  trace.endBlock();
392 
393  return true;
394 }
395 
400 bool testNoPoint()
401 {
402  typedef int Coordinate;
403  typedef PointVector<2,Coordinate> Point;
404  typedef ArithmeticalDSS<std::vector<Point>::iterator,Coordinate,4> PrimitiveType;
405  typedef GreedyDecomposition<PrimitiveType> DecompositionType;
406 
407  std::vector<Point> curve;
408  try {
409 
410  trace.beginBlock("Digital curve having no point");
411  PrimitiveType computer;
412  DecompositionType theDecomposition(curve.begin(), curve.end(), computer, false);
413 
414  for ( DecompositionType::SegmentIterator i = theDecomposition.begin();
415  i != theDecomposition.end(); ++i )
416  { }
417  trace.endBlock();
418 
419  return true;
420  } catch (std::exception e) {
421  return false;
422  }
423 
424 
425 }
426 
431 bool testOnePoint()
432 {
433  typedef int Coordinate;
434  typedef PointVector<2,Coordinate> Point;
435  typedef ArithmeticalDSS<std::vector<Point>::iterator,Coordinate,4> PrimitiveType;
436 
437  typedef GreedyDecomposition<PrimitiveType> DecompositionType;
438 
439  std::vector<Point> curve;
440  curve.push_back(Point(5,5));
441  try {
442 
443  trace.beginBlock("Digital curve having one point");
444  PrimitiveType computer;
445  DecompositionType theDecomposition(curve.begin(), curve.end(), computer, false);
446 
447  Board2D aBoard;
448  aBoard << curve.at(0);
449  //for each segment
450  aBoard << SetMode( "ArithmeticalDSS", "BoundingBox" );
451  for ( DecompositionType::SegmentIterator i = theDecomposition.begin();
452  i != theDecomposition.end(); ++i )
453  {
454  PrimitiveType primitive(*i);
455  trace.info() << primitive << endl;
456  aBoard << primitive;
457 
458  }
459  aBoard.saveSVG("testOnePoint.svg");
460  trace.endBlock();
461 
462  return true;
463  } catch (std::exception e) {
464  return false;
465  }
466 
467 
468 }
473 bool testTwoEndIterators()
474 {
475  typedef int Coordinate;
476  typedef PointVector<2,Coordinate> Point;
477  typedef ArithmeticalDSS<std::vector<Point>::iterator,Coordinate,4> PrimitiveType;
478 
479  typedef GreedyDecomposition<PrimitiveType> DecompositionType;
480 
481  std::vector<Point> curve;
482  curve.push_back(Point(5,5));
483 
484  try {
485 
486  trace.beginBlock("Two end iterators");
487  PrimitiveType computer;
488  DecompositionType theDecomposition(curve.begin(), curve.end(), computer, false);
489 
490  for ( DecompositionType::SegmentIterator i = theDecomposition.begin();
491  i != theDecomposition.end(); ++i )
492  { }
493 
494  trace.endBlock();
495 
496  return true;
497  } catch (std::exception e) {
498  return false;
499  }
500 
501 
502 }
503 
509 bool testOneDSS()
510 {
511 
512  typedef int Coordinate;
513  typedef PointVector<2,Coordinate> Point;
514  typedef ArithmeticalDSS<std::vector<Point>::iterator,Coordinate,8> PrimitiveType;
515  typedef GreedyDecomposition<PrimitiveType> DecompositionType;
516 
517  std::vector<Point> curve;
518  curve.push_back(Point(0,0));
519  curve.push_back(Point(1,1));
520  curve.push_back(Point(2,1));
521  curve.push_back(Point(3,2));
522  curve.push_back(Point(4,2));
523  curve.push_back(Point(5,2));
524  curve.push_back(Point(6,3));
525  curve.push_back(Point(7,3));
526 
527  //Segmentation
528  trace.beginBlock("Segmentation of one DSS");
529  PrimitiveType computer;
530  DecompositionType theDecomposition(curve.begin(), curve.end(), computer, false);
531 
532  // Draw the pixels
533  Board2D aBoard;
534  aBoard.setUnit(Board::UCentimeter);
535  aBoard << SetMode("PointVector", "Both");
536  for (std::vector<Point>::iterator it = curve.begin(); it != curve.end(); ++it) {
537  aBoard << (*it);
538  }
539 
540  //for each segment
541  unsigned int compteur = 0;
542  DecompositionType::SegmentIterator i = theDecomposition.begin();
543  for ( ; i != theDecomposition.end(); ++i) {
544 
545  ++compteur;
546  PrimitiveType segment(*i);
547  trace.info() << segment << std::endl; //standard output
548  aBoard << SetMode( "ArithmeticalDSS", "BoundingBox" )
549  << segment; // draw each segment
550  }
551 
552  aBoard.saveSVG("oneDSS.svg");
553 
554  trace.endBlock();
555 
556  return (compteur==1);
557 }
558 
564 bool testDec8Reverse()
565 {
566 
567  typedef int Coordinate;
568  typedef PointVector<2,Coordinate> Point;
569  typedef std::vector<Point> ContourType;
571  typedef GreedyDecomposition<PrimitiveType> DecompositionType;
572 
573  std::vector<Point> curve;
574 curve.push_back(Point(1,1)); //input elements
575 curve.push_back(Point(2,1));
576 curve.push_back(Point(3,2));
577 curve.push_back(Point(4,2));
578 curve.push_back(Point(5,2));
579 curve.push_back(Point(6,2));
580 curve.push_back(Point(7,2));
581 curve.push_back(Point(8,1));
582 curve.push_back(Point(9,1));
583 
584  //Segmentation
585  trace.beginBlock("Segmentation of a 8-connected digital curve into DSS");
586  PrimitiveType computer;
587  DecompositionType theDecomposition(curve.rbegin(), curve.rend(), computer, false);
588 
589  // Draw the pixels
590  Board2D aBoard;
591  aBoard.setUnit(Board::UCentimeter);
592  aBoard << SetMode("PointVector", "Both");
593  for (ContourType::iterator it = curve.begin(); it != curve.end(); ++it) {
594  aBoard << (*it);
595  }
596 
597 
598  //for each segment
599  unsigned int compteur = 0;
600  DecompositionType::SegmentIterator i = theDecomposition.begin();
601  for ( ; i != theDecomposition.end(); ++i) {
602 
603  compteur++;
604  trace.info() << "Segment " << compteur << std::endl;
605  PrimitiveType segment(*i);
606  trace.info() << segment << std::endl; //standard output
607  aBoard << SetMode( "ArithmeticalDSS", "BoundingBox" )
608  << segment; // draw each segment
609  }
610 
611  aBoard.saveSVG("right_left.svg");
612 
613  trace.endBlock();
614 
615  return (compteur==2);
616 }
617 
621 
622 int main(int argc, char **argv)
623 {
624 
625  trace.beginBlock ( "Testing class GreedyDecomposition" );
626  trace.info() << "Args:";
627  for ( int i = 0; i < argc; ++i )
628  trace.info() << " " << argv[ i ];
629  trace.info() << endl;
630 
631  bool res = testDec4()
632  && testDec8()
633  && testDisconnectedCurve()
634  && testClosedCurvesProcessedAsClosed()
635  && testClosedCurvesProcessedAsOpen()
636  && testOpenCurvesProcessedAsClosed()
637  && testNoPoint()
638  && testOnePoint()
639  && testTwoEndIterators()
640  && testOneDSS()
641  && testDec8Reverse();
642  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
643  trace.endBlock();
644 
645  return res ? 0 : 1;
646 
647 }