DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testLengthEstimators.cpp
1 
30 
31 #include <cmath>
32 #include "DGtal/base/Common.h"
33 
34 //space / domain
35 #include "DGtal/kernel/SpaceND.h"
36 #include "DGtal/kernel/domains/HyperRectDomain.h"
37 #include "DGtal/topology/KhalimskySpaceND.h"
38 
39 //shape and digitizer
40 #include "DGtal/shapes/ShapeFactory.h"
41 #include "DGtal/shapes/Shapes.h"
42 #include "DGtal/helpers/StdDefs.h"
43 #include "DGtal/topology/helpers/Surfaces.h"
44 
45 #include "DGtal/shapes/GaussDigitizer.h"
46 #include "DGtal/geometry/curves/GridCurve.h"
47 
48 //estimators
49 #include "DGtal/geometry/curves/estimation/TrueLocalEstimatorOnPoints.h"
50 #include "DGtal/geometry/curves/estimation/TrueGlobalEstimatorOnPoints.h"
51 #include "DGtal/geometry/curves/estimation/ParametricShapeCurvatureFunctor.h"
52 #include "DGtal/geometry/curves/estimation/ParametricShapeTangentFunctor.h"
53 #include "DGtal/geometry/curves/estimation/ParametricShapeArcLengthFunctor.h"
54 
55 #include "DGtal/geometry/curves/estimation/L1LengthEstimator.h"
56 #include "DGtal/geometry/curves/estimation/TwoStepLocalLengthEstimator.h"
57 #include "DGtal/geometry/curves/estimation/BLUELocalLengthEstimator.h"
58 #include "DGtal/geometry/curves/estimation/RosenProffittLocalLengthEstimator.h"
59 
60 #include "DGtal/geometry/curves/estimation/MLPLengthEstimator.h"
61 #include "DGtal/geometry/curves/estimation/FPLengthEstimator.h"
62 #include "DGtal/geometry/curves/estimation/DSSLengthEstimator.h"
63 
64 #include "ConfigTest.h"
65 
66 #include "DGtal/io/boards/Board2D.h"
67 
69 
70 using namespace std;
71 using namespace DGtal;
72 
73 
75 // Functions for testing Length Estimator classes.
77 
78 bool testLengthEstimatorsOnBall(double radius, double h)
79 {
80 
81  // Types
82  typedef SpaceND<2,int> Space;
83  typedef Ball2D<Space> Shape;
84  typedef Space::Point Point;
85  typedef Space::RealPoint RealPoint;
86  typedef Space::Integer Integer;
89  typedef KSpace::SCell SCell;
90  typedef GridCurve<KSpace>::PointsRange PointsRange;
91  typedef GridCurve<KSpace>::ArrowsRange ArrowsRange;
92  typedef PointsRange::ConstIterator ConstIteratorOnPoints;
93 
94 
95  //Forme
96  Shape aShape(Point(0,0), radius);
97 
98  trace.info() << "#ball created, r=" << radius << endl;
99 
100  // Window for the estimation
101  RealPoint xLow ( -radius-1, -radius-1 );
102  RealPoint xUp( radius+1, radius+1 );
104  dig.attach( aShape ); // attaches the shape.
105  dig.init( xLow, xUp, h );
106  // The domain size is given by the digitizer according to the window
107  // and the step.
108  Domain domain = dig.getDomain();
109  // Create cellular space
110  KSpace K;
111  bool ok = K.init( dig.getLowerBound(), dig.getUpperBound(), true );
112  if ( ! ok )
113  {
114  std::cerr << " "
115  << " error in creating KSpace." << std::endl;
116  return false;
117  }
118  try {
119 
120  // Extracts shape boundary
122  SCell bel = Surfaces<KSpace>::findABel( K, dig, 10000 );
123  // Getting the consecutive surfels of the 2D boundary
124  std::vector<Point> points;
125  Surfaces<KSpace>::track2DBoundaryPoints( points, K, SAdj, dig, bel );
126  trace.info() << "# tracking..." << endl;
127  // Create GridCurve
128  GridCurve<KSpace> gridcurve;
129  gridcurve.initFromVector( points );
130  trace.info() << "#grid curve created, h=" << h << endl;
131 
132  //ranges
133  ArrowsRange ra = gridcurve.getArrowsRange();
134  PointsRange rp = gridcurve.getPointsRange();
135 
137  double trueValue = M_PI*2*radius;
139  l1length.init(h, ra.c(), ra.c());
141  locallength.init(h, ra.begin(), ra.end(), gridcurve.isClosed());
143  BLUElength.init(h, ra.begin(), ra.end(), gridcurve.isClosed());
145  RosenProffittlength.init(h, ra.begin(), ra.end(), gridcurve.isClosed());
147  DSSlength.init(h, rp.begin(), rp.end(), gridcurve.isClosed());
149  MLPlength.init(h, rp.begin(), rp.end(), gridcurve.isClosed());
151  FPlength.init(h, rp.begin(), rp.end(), gridcurve.isClosed());
152 
153  trace.info() << "#Estimations" <<std::endl;
154  trace.info() << "#h true naive 1-sqrt(2) BLUE RosenProffitt DSS MLP FP " <<std::endl;
155  trace.info() << h << " " << trueValue
156  << " " << l1length.eval()
157  << " " << locallength.eval()
158  << " " << BLUElength.eval()
159  << " " << RosenProffittlength.eval()
160  << " " << DSSlength.eval()
161  << " " << MLPlength.eval()
162  << " " << FPlength.eval() << std::endl;
163 
164  }
165  catch ( InputException e )
166  {
167  std::cerr << " "
168  << " error in finding a bel." << std::endl;
169  return false;
170  }
171 
172 
173 
174  return true;
175 }
176 
177 
178 
179 bool testDisplay(double radius, double h)
180 {
181 
182  // Types
183  typedef Ball2D<Z2i::Space> Shape;
184  typedef Z2i::Space::Point Point;
185  typedef Z2i::Space::RealPoint RealPoint;
186  typedef Z2i::Space::Integer Integer;
187  typedef HyperRectDomain<Z2i::Space> Domain;
189  typedef KSpace::SCell SCell;
190  typedef GridCurve<KSpace>::PointsRange PointsRange;
191  typedef GridCurve<KSpace>::ArrowsRange ArrowsRange;
192  typedef GridCurve<KSpace>::SCellsRange SCellsRange;
193  typedef PointsRange::ConstIterator ConstIteratorOnPoints;
194 
195 
196  //Forme
197  Shape aShape(Point(0,0), radius);
198 
199  trace.info() << "#ball created, r=" << radius << endl;
200 
201  // Window for the estimation
202  RealPoint xLow ( -radius-1, -radius-1 );
203  RealPoint xUp( radius+1, radius+1 );
205  dig.attach( aShape ); // attaches the shape.
206  dig.init( xLow, xUp, h );
207  // The domain size is given by the digitizer according to the window
208  // and the step.
209  Domain domain = dig.getDomain();
210  // Create cellular space
211  KSpace K;
212  bool ok = K.init( dig.getLowerBound(), dig.getUpperBound(), true );
213  if ( ! ok )
214  {
215  std::cerr << " "
216  << " error in creating KSpace." << std::endl;
217  return false;
218  }
219  try {
220 
221  // Extracts shape boundary
223  SCell bel = Surfaces<KSpace>::findABel( K, dig, 10000 );
224  // Getting the consecutive surfels of the 2D boundary
225  std::vector<Point> points;
226  Surfaces<KSpace>::track2DBoundaryPoints( points, K, SAdj, dig, bel );
227  trace.info() << "# tracking..." << endl;
228  // Create GridCurve
229  GridCurve<KSpace> gridcurve;
230  gridcurve.initFromVector( points );
231  trace.info() << "#grid curve created, h=" << h << endl;
232 
233  //ranges
234  ArrowsRange ra = gridcurve.getArrowsRange();
235  PointsRange rp = gridcurve.getPointsRange();
236  SCellsRange rc = gridcurve.getSCellsRange();
237 
238  //Explicit reshaping for drawing purposes
239  Z2i::DigitalSet set(domain);
240  Shapes<Z2i::Domain>::euclideanShaper( set, Shape(Point(0,0), radius/h));
241 
242  Board2D board;
243 
244  board << domain << set;
245  board.saveSVG( "Ranges-Set.svg" );
246 
247  board.clear();
248  board << domain;
249  board << rp;
250  // for( PointsRange::ConstIterator it =rp.begin(), ite=rp.end();
251  // it != ite; ++it)
252  // board << (*it);
253  board.saveSVG( "Ranges-Points.svg" );
254 
255 
256  board.clear();
257  board << domain;
258  board << rc;
259  // for( SCellsRange::ConstIterator it =rc.begin(), ite=rc.end();
260  // it != ite; ++it)
261  // board << (*it);
262  board.saveSVG( "Ranges-SCells.svg" );
263 
264 
265  board.clear();
266  board << domain;
267  board << ra;
268  // Z2i::Space::Vector shift;
269  // board.setPenColor( Color::Black );
270  // for( ArrowsRange::ConstIterator it = ra.begin(), itend = ra.end();
271  // it != itend;
272  // ++it)
273  // {
274  // shift = (*it).second ;
275  // draw(board, shift, (*it).first );
276  // }
277  board.saveSVG( "Ranges-Arrows.svg" );
278 
279  }
280  catch ( InputException e )
281  {
282  std::cerr << " "
283  << " error in finding a bel." << std::endl;
284  return false;
285  }
286 
287 
288 
289  return true;
290 }
291 
293 // Standard services - public :
294 
295 int main( int argc, char** argv )
296 {
297  trace.beginBlock ( "Testing class LengthEstimators" );
298  trace.info() << "Args:";
299  for ( int i = 0; i < argc; ++i )
300  trace.info() << " " << argv[ i ];
301  trace.info() << endl;
302 
303  double r = 5;
304  bool res = testLengthEstimatorsOnBall(r,1)
305  && testLengthEstimatorsOnBall(r,0.1)
306  && testLengthEstimatorsOnBall(r,0.01)
307  && testLengthEstimatorsOnBall(r,0.001)
308  && testDisplay(r,0.9);
309  ;
310 
311  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
312  trace.endBlock();
313  return res ? 0 : 1;
314 }
315 // //