34 #include <boost/program_options.hpp>
35 #include "DGtal/kernel/SpaceND.h"
36 #include "DGtal/base/Common.h"
37 #include "DGtal/helpers/StdDefs.h"
38 #include "DGtal/geometry/curves/FreemanChain.h"
39 #include "DGtal/kernel/domains/HyperRectDomain.h"
40 #include "DGtal/io/boards/Board2D.h"
41 #include "ConfigTest.h"
46 using namespace DGtal;
47 using namespace LibBoard;
59 bool testConstructors()
66 trace.
info() <<
"Constructor from string and coordinates" << endl;
67 std::string s =
"00001030003222321222";
68 FreemanChain c1(s, -42, 12);
70 trace.
info() <<
"Constructor from point vector" << endl;
71 std::vector<Z2i::Point> myVector;
72 for (Iterator i = c1.begin(); i != c1.end(); i++)
73 myVector.push_back(*i);
74 FreemanChain c2(myVector);
76 trace.
info() <<
"Constructor from input stream" << endl;
78 ss <<
"-42 12 " << s <<
"\n";
81 trace.
info() <<
"Copy constructor" << endl;
85 FreemanChain c5(
"0123" , 0, 0);
98 (c1 == c2) && (c1 == c3) && (c1 == c4) && (c1 == c5) && (c1 != c6)
99 && (c2 == c1) && (c2 == c3) && (c2 == c4) && (c2 == c5) && (c2 != c6)
100 && (c3 == c1) && (c3 == c2) && (c3 == c4) && (c3 == c5) && (c3 != c6)
101 && (c4 == c1) && (c4 == c2) && (c4 == c3) && (c4 == c5) && (c4 != c6)
102 && (c5 == c1) && (c5 == c2) && (c5 == c3) && (c5 == c4) && (c4 != c6)
103 && (c6 != c1) && (c6 != c2) && (c6 != c3) && (c6 != c4) && (c6 != c5)
114 bool testPublicSercives()
123 FreemanChain fc(
"000103000322232122", 0, 0);
127 bool test = ( fc.code(5) ==
'3' );
128 nbOk += (test) ? 1 : 0;
129 trace.
info() <<
"Test 1 " << ((test) ?
"passed" :
"failed" ) << endl;
132 test = ( fc.size() == 18 );
133 nbOk += (test) ? 1 : 0;
134 trace.
info() <<
"Test 2 " << ((test) ?
"passed" :
"failed" ) << endl;
137 test = ( fc.subChain(3, 3) == FreemanChain(
"103", 3, 0) );
138 nbOk += (test) ? 1 : 0;
139 trace.
info() <<
"Test 3 " << ((test) ?
"passed" :
"failed" ) << endl;
143 FreemanChain fcA(
"001",0,0);
144 FreemanChain fcB(
"001",0,0);
145 FreemanChain fcC(
"003",0,0);
147 test = ( fcB == FreemanChain(
"001003001", 0, 0) ) &&
148 ( fcB.totalDisplacement() == fcA.totalDisplacement()*2 + fcC.totalDisplacement() );
149 nbOk += (test) ? 1 : 0;
150 trace.
info() <<
"Test 4 " << ((test) ?
"passed" :
"failed" ) << endl;
154 int min_x, min_y, max_x, max_y;
155 fc.computeBoundingBox( min_x, min_y, max_x, max_y );
156 test = ( (min_x == 0) && (min_y == -2) && (max_x == 7) && (max_y == 1) );
157 nbOk += (test) ? 1 : 0;
158 trace.
info() <<
"Test 5 " << ((test) ?
"passed" :
"failed" ) << endl;
163 Iterator it = fc.findQuadrantChange( oa );
164 test = ( it.getPosition() == 4 );
165 nbOk += (test) ? 1 : 0;
166 trace.
info() <<
"Test 6 " << ((test) ?
"passed" :
"failed" ) << endl;
170 it = fc.findQuadrantChange4( oa );
171 test = ( it.getPosition() == 9 );
172 nbOk += (test) ? 1 : 0;
173 trace.
info() <<
"Test 7 " << ((test) ?
"passed" :
"failed" ) << endl;
176 test = ( ! fc.isClosed() && ( fc + FreemanChain(
"21") ).isClosed() );
177 nbOk += (test) ? 1 : 0;
178 trace.
info() <<
"Test 8 " << ((test) ?
"passed" :
"failed" ) << endl;
182 test = ( FreemanChain(
"0001212323", 12, 21).ccwLoops() == 1 ) &&
183 ( FreemanChain(
"0003232121", 12, 21).ccwLoops() == -1 ) &&
184 ( FreemanChain(
"000323212", 12, 21).ccwLoops() == 0 ) &&
185 ( FreemanChain(
"012301230123", 12, 21).ccwLoops() == 3 );
186 nbOk += (test) ? 1 : 0;
187 trace.
info() <<
"Test 9 " << ((test) ?
"passed" :
"failed" ) << endl;
194 for (
unsigned int i=0; i <= fc.size(); ++i, ++it)
196 test = ( fc.getPoint(i) == *it );
199 nbOk += (test) ? 1 : 0;
200 trace.
info() <<
"Test 10 " << ((test) ?
"passed" :
"failed" ) << endl;
204 test = ( ( fc.subChain(4,3).firstPoint() == Point(3,1) ) &&
205 ( fc.subChain(4,3).lastPoint() == Point(5,0) ) );
206 nbOk += (test) ? 1 : 0;
207 trace.
info() <<
"Test 11 " << ((test) ?
"passed" :
"failed" ) << endl;
213 fcB = fcA.extend(
'1');
214 test = ( (fcB == fc + FreemanChain(
"21",0,0) ) && fcA.isClosed()
215 && ( fcB.retract().retract() == fc ) );
216 nbOk += (test) ? 1 : 0;
217 trace.
info() <<
"Test 12 " << ((test) ?
"passed" :
"failed" ) << endl;
221 return ( nbOk == 12);
231 bool testPointsIterators()
233 typedef int Coordinate;
241 std::stringstream ss;
242 std::string myString =
"0 0 000011112222333";
243 ss << myString << std::endl;
244 FreemanChain seq(ss);
246 trace.
info()<<
"Freeman chain set to " << myString << endl;
249 trace.
info()<<
"Iterates on points." << endl;
250 std::stack<Point> myStack;
252 unsigned int nbPts = 0;
253 for (PointIterator i = seq.begin(); i != seq.end(); ++i)
259 trace.
info()<<
"Test reverse iterator." << endl;
260 bool samePoints =
true;
261 for (ReverseIterator ri(seq.end());
262 ri != ReverseIterator(seq.begin());
265 if ( !myStack.empty() && ( *ri == myStack.top() ) )
276 return myStack.empty() && samePoints && ( nbPts == seq.size() + 1);
282 bool testCodesIterators()
284 typedef int Coordinate;
292 std::stringstream ss;
293 std::string myString =
"0 0 000011112222333";
294 ss << myString << std::endl;
295 FreemanChain seq(ss);
297 trace.
info()<<
"Freeman chain set to " << myString << endl;
299 Range r = seq.getCodesRange();
302 trace.
info()<<
"Iterates on letters." << endl;
303 std::stack<char> myStack;
305 unsigned int nbLetters = 0;
306 for (Range::ConstIterator i = r.
begin(); i != r.
end(); ++i)
312 trace.
info()<<
"Test reverse iterator." << endl;
313 bool samePoints =
true;
314 for (Range::ConstReverseIterator ri = r.rbegin();
318 if ( !myStack.empty() && ( *ri == myStack.top() ) )
329 return myStack.empty() && samePoints && ( nbLetters == seq.size() );
335 bool testStaticServices()
341 typedef std::vector<unsigned int> numVector;
349 std::string s1(
"0001");
352 stringstream ss1, ss2;
353 ss1 << x0 <<
" " << y0 <<
" " << s1 << std::endl;;
355 FreemanChain::read(ss1, f);
356 FreemanChain::write(ss2, f);
360 test = (x == x0) && (y == y0) && (s1 == s2);
361 nbOk += (test) ? 1 : 0;
362 trace.
info() <<
"Test 1 " << ((test) ?
"passed" :
"failed" ) << endl;
366 Point p0, p1(-1,-1), p2(0,-1), p3(1,-1), p4(2,-1), p5(2,0);
367 vector<Point> pointVecRef, pointVecTest;
368 pointVecRef.push_back(p1);
369 pointVecRef.push_back(p2);
370 pointVecRef.push_back(p3);
371 pointVecRef.push_back(p4);
372 pointVecRef.push_back(p5);
373 FreemanChain::getContourPoints( f, pointVecTest );
374 test = pointVecRef == pointVecTest;
375 nbOk += (test) ? 1 : 0;
376 trace.
info() <<
"Test 2 " << ((test) ?
"passed" :
"failed" ) << endl;
380 Point P0(10,10), P1(10,10), P2(10,10), P3(10,10);
381 FreemanChain::movePointFromFC( P0,
'0'); FreemanChain::movePointFromFC( P1,
'1');
382 FreemanChain::movePointFromFC( P2,
'2'); FreemanChain::movePointFromFC( P3,
'3');
383 test = ( P0 == Point(11,10) ) && ( P1 == Point(10,11) ) &&
384 (P2 == Point(9,10) ) && ( P3 == Point(10,9) ) ;
385 nbOk += (test) ? 1 : 0;
386 trace.
info() <<
"Test 3 " << ((test) ?
"passed" :
"failed" ) << endl;
391 test = ( FreemanChain::movement (
'0' ,
'0' ,
true ) ==
'2' ) &&
392 ( FreemanChain::movement (
'0' ,
'1' ,
true ) ==
'1' ) &&
393 ( FreemanChain::movement (
'0' ,
'2' ,
true ) ==
'0' ) &&
394 ( FreemanChain::movement (
'0' ,
'3' ,
true ) ==
'3' ) &&
395 ( FreemanChain::movement (
'0' ,
'0' ,
false ) ==
'2' ) &&
396 ( FreemanChain::movement (
'0' ,
'1' ,
false ) ==
'3' ) &&
397 ( FreemanChain::movement (
'0' ,
'2' ,
false ) ==
'0' ) &&
398 ( FreemanChain::movement (
'0' ,
'3' ,
false ) ==
'1' );
399 nbOk += (test) ? 1 : 0;
400 trace.
info() <<
"Test 4 " << ((test) ?
"passed" :
"failed" ) << endl;
403 test = ( FreemanChain::addToCode(
'0' , 1 ) ==
'1' ) &&
404 ( FreemanChain::addToCode(
'1' , 1 ) ==
'2' ) &&
405 ( FreemanChain::addToCode(
'2' , 1 ) ==
'3' ) &&
406 ( FreemanChain::addToCode(
'3' , 1 ) ==
'0' ) &&
407 ( FreemanChain::addToCode(
'0' , -1 ) ==
'3' ) &&
408 ( FreemanChain::addToCode(
'1' , -1 ) ==
'0' ) &&
409 ( FreemanChain::addToCode(
'2' , -1 ) ==
'1' ) &&
410 ( FreemanChain::addToCode(
'3' , -1 ) ==
'2' ) &&
411 ( FreemanChain::addToCode(
'1' , 0 ) ==
'1' ) &&
412 ( FreemanChain::addToCode(
'1' , 2 ) ==
'3' ) &&
413 ( FreemanChain::addToCode(
'1' , 3 ) ==
'0' ) &&
414 ( FreemanChain::addToCode(
'1' , 4 ) ==
'1' ) &&
415 ( FreemanChain::addToCode(
'1' , 5 ) ==
'2' ) &&
416 ( FreemanChain::addToCode(
'1' , -2 ) ==
'3' ) &&
417 ( FreemanChain::addToCode(
'1' , -3 ) ==
'2' ) &&
418 ( FreemanChain::addToCode(
'1' , -4 ) ==
'1' ) &&
419 ( FreemanChain::addToCode(
'1' , -5 ) ==
'0' );
420 nbOk += (test) ? 1 : 0;
421 trace.
info() <<
"Test 5 " << ((test) ?
"passed" :
"failed" ) << endl;
427 FreemanChain::displacement( X[0] , Y[0],
'0');
428 FreemanChain::displacement( X[1] , Y[1],
'1');
429 FreemanChain::displacement( X[2] , Y[2],
'2');
430 FreemanChain::displacement( X[3] , Y[3],
'3');
432 p0 = FreemanChain::displacement(
'0' );
433 p1 = FreemanChain::displacement(
'1' );
434 p2 = FreemanChain::displacement(
'2' );
435 p3 = FreemanChain::displacement(
'3' );
437 test = (X[0] == 1) && (Y[0] == 0) && (p0 == Point( 1, 0)) &&
438 (X[1] == 0) && (Y[1] == 1) && (p1 == Point( 0, 1)) &&
439 (X[2] == -1) && (Y[2] == 0) && (p2 == Point(-1, 0)) &&
440 (X[3] == 0) && (Y[3] == -1) && (p3 == Point( 0,-1)) ;
441 nbOk += (test) ? 1 : 0;
442 trace.
info() <<
"Test 6 " << ((test) ?
"passed" :
"failed" ) << endl;
449 f = FreemanChain(
"000112321233", 0, 0);
450 numVector pl2pix, pix2pl;
451 FreemanChain pixChain;
452 FreemanChain::pointel2pixel( pixChain, pl2pix, pix2pl, f );
453 numVector pl2pixExpected;
454 pl2pixExpected.push_back( 0 ); pl2pixExpected.push_back( 1 ); pl2pixExpected.push_back( 2 );
455 pl2pixExpected.push_back( 2 ); pl2pixExpected.push_back( 3 ); pl2pixExpected.push_back( 3 );
456 pl2pixExpected.push_back( 3 ); pl2pixExpected.push_back( 5 ); pl2pixExpected.push_back( 7 );
457 pl2pixExpected.push_back( 7 ); pl2pixExpected.push_back( 7 ); pl2pixExpected.push_back( 8 );
458 numVector pix2plExpected;
459 pix2plExpected.push_back( 0 ); pix2plExpected.push_back( 1 ); pix2plExpected.push_back( 3 );
460 pix2plExpected.push_back( 6 ); pix2plExpected.push_back( 7 ); pix2plExpected.push_back( 7 );
461 pix2plExpected.push_back( 8 ); pix2plExpected.push_back( 10 );
462 test = ( pixChain == FreemanChain(
"00132213", 0, 0) ) &&
463 ( pl2pix == pl2pixExpected ) &&
464 ( pix2pl == pix2plExpected );
465 nbOk += (test) ? 1 : 0;
466 trace.
info() <<
"Test 7 " << ((test) ?
"passed" :
"failed" ) << endl;
474 FreemanChain innerChain;
475 numVector outer2inner, inner2outer;
476 FreemanChain::innerContour ( innerChain, outer2inner, inner2outer, f,
true);
477 test = ( innerChain == FreemanChain(
"00132213", 0, 0 ) ) &&
478 ( outer2inner == pl2pixExpected ) &&
479 ( inner2outer == pix2plExpected );
480 nbOk += (test) ? 1 : 0;
481 trace.
info() <<
"Test 8 " << ((test) ?
"passed" :
"failed" ) << endl;
489 FreemanChain c(
"0000112312213233", 0, 0 );
490 numVector c2clean, clean2c;
492 bool cleaned = FreemanChain::cleanOuterSpikes( cleanC, c2clean, clean2c, c,
true );
493 FreemanChain cleanCExpected(
"22233000011231", 3, 2);
494 numVector c2cleanExpected;
495 c2cleanExpected.push_back( 5 ); c2cleanExpected.push_back( 6 ); c2cleanExpected.push_back( 7 );
496 c2cleanExpected.push_back( 8 ); c2cleanExpected.push_back( 9 ); c2cleanExpected.push_back(10 );
497 c2cleanExpected.push_back(11 ); c2cleanExpected.push_back(12 ); c2cleanExpected.push_back(13 );
498 c2cleanExpected.push_back( 0 ); c2cleanExpected.push_back( 1 ); c2cleanExpected.push_back( 2 );
499 c2cleanExpected.push_back( 2 ); c2cleanExpected.push_back( 2 ); c2cleanExpected.push_back( 3 );
500 c2cleanExpected.push_back( 4 );
501 numVector clean2cExpected;
502 clean2cExpected.push_back( 9 ); clean2cExpected.push_back(10 ); clean2cExpected.push_back(13 );
503 clean2cExpected.push_back(14 ); clean2cExpected.push_back(15 ); clean2cExpected.push_back( 0 );
504 clean2cExpected.push_back( 1 ); clean2cExpected.push_back( 2 ); clean2cExpected.push_back( 3 );
505 clean2cExpected.push_back( 4 ); clean2cExpected.push_back( 5 ); clean2cExpected.push_back( 6 );
506 clean2cExpected.push_back( 7 ); clean2cExpected.push_back( 8 );
507 test = cleaned && (cleanC == cleanCExpected) && (c2clean == c2cleanExpected)
508 && (clean2c == clean2cExpected);
509 nbOk += (test) ? 1 : 0;
510 trace.
info() <<
"Test 9 " << ((test) ?
"passed" :
"failed" ) << endl;
531 aBoard.
setUnit(Board::UCentimeter);
534 fst.open ((testPath +
"samples/contourS.fc").c_str() , ios::in);
535 FreemanChain fc(fst);
543 std::string filenameImage = testPath +
"samples/contourS.png";
545 image.shiftDepth(500);
549 aBoard.
saveSVG(
"testDisplayFC.svg", Board::BoundingBox, 5000 );
550 aBoard.
saveEPS(
"testDisplayFC.eps", Board::BoundingBox, 5000 );
551 aBoard.
saveFIG(
"testDisplayFC.fig", Board::BoundingBox, 5000 );
554 aBoard.saveCairo(
"testDisplayFC-cairo.pdf", Board2D::CairoPDF, Board::BoundingBox, 5000);
555 aBoard.saveCairo(
"testDisplayFC-cairo.png", Board2D::CairoPNG, Board::BoundingBox, 5000);
556 aBoard.saveCairo(
"testDisplayFC-cairo.ps", Board2D::CairoPS, Board::BoundingBox, 5000);
557 aBoard.saveCairo(
"testDisplayFC-cairo.svg", Board2D::CairoSVG, Board::BoundingBox, 5000);
570 int main(
int argc,
char** argv )
574 for (
int i = 0; i < argc; ++i )
579 testConstructors() &&
580 testPublicSercives() &&
581 testPointsIterators() &&
582 testCodesIterators() &&
583 testStaticServices() &&
587 trace.
emphase() << ( res ?
"Passed." :
"Error." ) << endl;