41#include "DGtal/base/Common.h"
42#include "DGtal/base/Clock.h"
45#include "DGtal/kernel/SpaceND.h"
46#include "DGtal/kernel/domains/HyperRectDomain.h"
47#include "DGtal/topology/KhalimskySpaceND.h"
50#include "DGtal/shapes/ShapeFactory.h"
51#include "DGtal/shapes/Shapes.h"
52#include "DGtal/helpers/StdDefs.h"
53#include "DGtal/topology/helpers/Surfaces.h"
55#include "DGtal/shapes/GaussDigitizer.h"
56#include "DGtal/geometry/curves/GridCurve.h"
59#include "DGtal/geometry/curves/estimation/TrueLocalEstimatorOnPoints.h"
60#include "DGtal/geometry/curves/estimation/TrueGlobalEstimatorOnPoints.h"
61#include "DGtal/geometry/curves/estimation/ParametricShapeArcLengthFunctor.h"
63#include "DGtal/geometry/curves/estimation/L1LengthEstimator.h"
64#include "DGtal/geometry/curves/estimation/BLUELocalLengthEstimator.h"
65#include "DGtal/geometry/curves/estimation/RosenProffittLocalLengthEstimator.h"
66#include "DGtal/geometry/curves/estimation/MLPLengthEstimator.h"
67#include "DGtal/geometry/curves/estimation/FPLengthEstimator.h"
68#include "DGtal/geometry/curves/estimation/DSSLengthEstimator.h"
151std::vector<std::string> shapes2D;
152std::vector<std::string> shapesDesc;
153std::vector<std::string> shapesParam1;
154std::vector<std::string> shapesParam2;
155std::vector<std::string> shapesParam3;
156std::vector<std::string> shapesParam4;
165 shapes2D.push_back(
"ball");
166 shapesDesc.push_back(
"Ball for the Euclidean metric.");
167 shapesParam1.push_back(
"--radius [-R]");
168 shapesParam2.push_back(
"");
169 shapesParam3.push_back(
"");
170 shapesParam4.push_back(
"");
172 shapes2D.push_back(
"square");
173 shapesDesc.push_back(
"square (no signature).");
174 shapesParam1.push_back(
"--width [-w]");
175 shapesParam2.push_back(
"");
176 shapesParam3.push_back(
"");
177 shapesParam4.push_back(
"");
179 shapes2D.push_back(
"lpball");
180 shapesDesc.push_back(
"Ball for the l_power metric (no signature).");
181 shapesParam1.push_back(
"--radius [-R],");
182 shapesParam2.push_back(
"--power [-p]");
183 shapesParam3.push_back(
"");
184 shapesParam4.push_back(
"");
186 shapes2D.push_back(
"flower");
187 shapesDesc.push_back(
"Flower with k petals.");
188 shapesParam1.push_back(
"--radius [-R],");
189 shapesParam2.push_back(
"--varsmallradius [-v],");
190 shapesParam3.push_back(
"--k [-k],");
191 shapesParam4.push_back(
"--phi");
193 shapes2D.push_back(
"ngon");
194 shapesDesc.push_back(
"Regular k-gon.");
195 shapesParam1.push_back(
"--radius [-R],");
196 shapesParam2.push_back(
"--k [-k],");
197 shapesParam3.push_back(
"--phi");
198 shapesParam4.push_back(
"");
200 shapes2D.push_back(
"accflower");
201 shapesDesc.push_back(
"Accelerated Flower with k petals.");
202 shapesParam1.push_back(
"--radius [-R],");
203 shapesParam2.push_back(
"--varsmallradius [-v],");
204 shapesParam3.push_back(
"--k [-k],");
205 shapesParam4.push_back(
"--phi");
207 shapes2D.push_back(
"ellipse");
208 shapesDesc.push_back(
"Ellipse.");
209 shapesParam1.push_back(
"--axis1 [-A],");
210 shapesParam2.push_back(
"--axis2 [-a],");
211 shapesParam3.push_back(
"--phi");
212 shapesParam4.push_back(
"");
223 trace.emphase()<<
"2D Shapes:"<<std::endl;
224 for(
unsigned int i=0; i<shapes2D.size(); ++i)
225 trace.info()<<
"\t"<<shapes2D[i]<<
"\t"
226 << shapesDesc[i]<<std::endl
227 <<
"\t\tRequired parameter(s): "
228 << shapesParam1[i]<<
" "
229 << shapesParam2[i]<<
" "
230 << shapesParam3[i]<<
" "
231 << shapesParam4[i]<<std::endl;
244unsigned int checkAndRetrunIndex(
const std::string &shapeName)
248 while ((pos < shapes2D.size()) && (shapes2D[pos] != shapeName))
251 if (pos == shapes2D.size())
253 trace.error() <<
"The specified shape has not found.";
254 trace.info()<<std::endl;
266void missingParam(std::string param)
268 trace.error() <<
" Parameter: "<<param<<
" is required..";
269 trace.info()<<std::endl;
274template <
typename Shape,
typename Space>
276lengthEstimators(
const std::string & ,
281 typedef typename Space::Point Point;
282 typedef typename Space::Vector Vector;
283 typedef typename Space::Integer Integer;
284 typedef HyperRectDomain<Space> Domain;
285 typedef KhalimskySpaceND<Space::dimension,Integer> KSpace;
286 typedef typename KSpace::SCell SCell;
287 typedef typename GridCurve<KSpace>::PointsRange PointsRange;
288 typedef typename GridCurve<KSpace>::ArrowsRange ArrowsRange;
291 GaussDigitizer<Space,Shape> dig;
292 dig.attach( aShape );
293 Vector vlow(-1,-1); Vector vup(1,1);
294 dig.init( aShape.getLowerBound()+vlow, aShape.getUpperBound()+vup, h );
295 Domain domain = dig.getDomain();
299 bool ok = K.init( dig.getLowerBound(), dig.getUpperBound(),
true );
302 std::cerr <<
"[lengthEstimators]"
303 <<
" error in creating KSpace." << std::endl;
309 SurfelAdjacency<KSpace::dimension> SAdj(
true );
310 SCell bel = Surfaces<KSpace>::findABel( K, dig, 10000 );
312 std::vector<Point> points;
313 Surfaces<KSpace>::track2DBoundaryPoints( points, K, SAdj, dig, bel );
315 GridCurve<KSpace> gridcurve;
316 gridcurve.initFromPointsVector( points );
318 ArrowsRange ra = gridcurve.getArrowsRange();
319 PointsRange rp = gridcurve.getPointsRange();
322 typedef typename PointsRange::ConstIterator ConstIteratorOnPoints;
323 typedef ParametricShapeArcLengthFunctor< Shape > Length;
324 TrueGlobalEstimatorOnPoints< ConstIteratorOnPoints, Shape, Length > trueLengthEstimator;
325 trueLengthEstimator.attach( aShape );
327 L1LengthEstimator< typename PointsRange::ConstCirculator > l1length;
328 DSSLengthEstimator< typename PointsRange::ConstCirculator > DSSlength;
329 MLPLengthEstimator< typename PointsRange::ConstCirculator > MLPlength;
330 FPLengthEstimator< typename PointsRange::ConstCirculator > FPlength;
331 BLUELocalLengthEstimator< typename ArrowsRange::ConstCirculator > BLUElength;
332 RosenProffittLocalLengthEstimator< typename ArrowsRange::ConstCirculator > RosenProffittlength;
335 double trueValue = trueLengthEstimator.eval();
336 double l1, blue, rosen,dss,mlp,fp;
337 double Tl1, Tblue, Trosen,Tdss,Tmlp,Tfp;
343 l1 = l1length.eval( rp.c(), rp.c(), h );
347 blue = BLUElength.eval( ra.c(), ra.c(), h );
348 Tblue = c.stopClock();
351 rosen = RosenProffittlength.eval( ra.c(), ra.c(), h );
352 Trosen = c.stopClock();
355 dss = DSSlength.eval( rp.c(), rp.c(), h );
356 Tdss = c.stopClock();
359 mlp = MLPlength.eval( rp.c(), rp.c(), h );
360 Tmlp = c.stopClock();
363 fp = FPlength.eval( rp.c(), rp.c(), h );
366 std::cout << std::setprecision( 15 ) << h <<
" " << rp.size() <<
" " << trueValue
382 catch ( InputException e )
384 std::cerr <<
"[lengthEstimators]"
385 <<
" error in finding a bel." << std::endl;
391int main(
int argc,
char** argv )
395 std::string shapeName;
396 double hMin {0.0001};
400 double smallradius {5};
401 double varsmallradius {5};
407 app.description(
"Generates multigrid contours of 2d digital shapes using DGtal library.\n Typical use example:\n \t contourGenerator --shape <shapeName> [requiredParam] [otherOptions]\n");
408 auto listOpt = app.add_flag(
"--list,-l",
"List all available shapes");
409 auto shapeNameOpt = app.add_option(
"--shape,-s", shapeName,
"Shape name");
410 auto radiusOpt = app.add_option(
"--radius,-R", radius,
"Radius of the shape" );
411 auto axis1Opt = app.add_option(
"--axis1,-A", axis1,
"Half big axis of the shape (ellipse)" );
412 auto axis2Opt = app.add_option(
"--axis2,-a", axis2,
"Half small axis of the shape (ellipse)" );
413 auto smallradiusOpt = app.add_option(
"--smallradius,-r", smallradius,
"Small radius of the shape (default 5)");
414 auto varsmallradiusOpt = app.add_option(
"--varsmallradius,-v", varsmallradius,
"Variable small radius of the shape (default 5)" );
415 auto kOpt = app.add_option(
"-k", k,
"Number of branches or corners the shape (default 3)" );
416 auto phiOpt = app.add_option(
"--phi", phi,
"Phase of the shape (in radian, default 0.0)" );
417 auto widthOpt = app.add_option(
"--width,-w", width,
"Width of the shape (default 10.0)" );
418 auto powerOpt = app.add_option(
"--power,-p", power,
"Power of the metric (default 2.0)" );
419 app.add_option(
"--hMin", hMin,
"Minimum value for the grid step h (double, default 0.0001)" );
420 app.add_option(
"--steps", nbSteps,
"Number of multigrid steps between 1 and hMin (integer, default 32)" );
422 app.get_formatter()->column_width(40);
423 CLI11_PARSE(app, argc, argv);
429 if ( listOpt->count() > 0 )
436 if(shapeNameOpt->count()==0) missingParam(
"--shape");
439 unsigned int id = checkAndRetrunIndex(shapeName);
443 std::cout <<
"#h nbPoints true-length L1 BLUE RosenProffit "
444 <<
"DSS MLP FP Time-L1 Time-BLUE Time-RosenProffitt "
445 <<
"Time-DSS Time-MLP Time-FP" << std::endl;
446 std::cout <<
"# timings are given in msec." << std::endl;
449 double step = exp( log(hMin) / (
double)nbSteps);
454 if (radiusOpt->count()==0) missingParam(
"--radius");
456 Ball2D<Z2i::Space> ball(Z2i::Point(0,0), radius);
458 lengthEstimators<Ball2D<Z2i::Space>,Z2i::Space>(
"ball",ball,h);
465 ImplicitHyperCube<Z2i::Space> object(Z2i::Point(0,0), width/2);
467 trace.error()<<
"Not available.";
468 trace.info()<<std::endl;
474 if (radiusOpt->count()==0) missingParam(
"--radius");
476 ImplicitRoundedHyperCube<Z2i::Space> ball(Z2i::Point(0,0), radius, power);
478 trace.error()<<
"Not available.";
479 trace.info()<<std::endl;
485 if (radiusOpt->count()==0) missingParam(
"--radius");
489 Flower2D<Z2i::Space> flower(Z2i::Point(0,0), radius, varsmallradius,k,phi);
491 lengthEstimators<Flower2D<Z2i::Space>,Z2i::Space>(
"flower",flower,h);
496 if (radiusOpt->count()==0) missingParam(
"--radius");
500 NGon2D<Z2i::Space> object(Z2i::Point(0,0), radius,k,phi);
502 lengthEstimators<NGon2D<Z2i::Space>,Z2i::Space>(
"NGon",object,h);
509 if (radiusOpt->count()==0) missingParam(
"--radius");
513 AccFlower2D<Z2i::Space> flower(Z2i::Point(0,0), radius, varsmallradius,k,phi);
514 lengthEstimators<AccFlower2D<Z2i::Space>,Z2i::Space>(
"accFlower",flower,h);
520 if (axis1Opt->count()==0) missingParam(
"--axis1");
521 if (axis2Opt->count()==0) missingParam(
"--axis2");
524 Ellipse2D<Z2i::Space> ell(Z2i::Point(0,0), axis1, axis2,phi);
526 lengthEstimators<Ellipse2D<Z2i::Space>,Z2i::Space>(
"Ellipse",ell,h);