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"
150std::vector<std::string> shapes2D;
151std::vector<std::string> shapesDesc;
152std::vector<std::string> shapesParam1;
153std::vector<std::string> shapesParam2;
154std::vector<std::string> shapesParam3;
155std::vector<std::string> shapesParam4;
164 shapes2D.push_back(
"ball");
165 shapesDesc.push_back(
"Ball for the Euclidean metric.");
166 shapesParam1.push_back(
"--radius [-R]");
167 shapesParam2.push_back(
"");
168 shapesParam3.push_back(
"");
169 shapesParam4.push_back(
"");
171 shapes2D.push_back(
"square");
172 shapesDesc.push_back(
"square (no signature).");
173 shapesParam1.push_back(
"--width [-w]");
174 shapesParam2.push_back(
"");
175 shapesParam3.push_back(
"");
176 shapesParam4.push_back(
"");
178 shapes2D.push_back(
"lpball");
179 shapesDesc.push_back(
"Ball for the l_power metric (no signature).");
180 shapesParam1.push_back(
"--radius [-R],");
181 shapesParam2.push_back(
"--power [-p]");
182 shapesParam3.push_back(
"");
183 shapesParam4.push_back(
"");
185 shapes2D.push_back(
"flower");
186 shapesDesc.push_back(
"Flower with k petals.");
187 shapesParam1.push_back(
"--radius [-R],");
188 shapesParam2.push_back(
"--varsmallradius [-v],");
189 shapesParam3.push_back(
"--k [-k],");
190 shapesParam4.push_back(
"--phi");
192 shapes2D.push_back(
"ngon");
193 shapesDesc.push_back(
"Regular k-gon.");
194 shapesParam1.push_back(
"--radius [-R],");
195 shapesParam2.push_back(
"--k [-k],");
196 shapesParam3.push_back(
"--phi");
197 shapesParam4.push_back(
"");
199 shapes2D.push_back(
"accflower");
200 shapesDesc.push_back(
"Accelerated Flower with k petals.");
201 shapesParam1.push_back(
"--radius [-R],");
202 shapesParam2.push_back(
"--varsmallradius [-v],");
203 shapesParam3.push_back(
"--k [-k],");
204 shapesParam4.push_back(
"--phi");
206 shapes2D.push_back(
"ellipse");
207 shapesDesc.push_back(
"Ellipse.");
208 shapesParam1.push_back(
"--axis1 [-A],");
209 shapesParam2.push_back(
"--axis2 [-a],");
210 shapesParam3.push_back(
"--phi");
211 shapesParam4.push_back(
"");
222 trace.emphase()<<
"2D Shapes:"<<std::endl;
223 for(
unsigned int i=0; i<shapes2D.size(); ++i)
224 trace.info()<<
"\t"<<shapes2D[i]<<
"\t"
225 << shapesDesc[i]<<std::endl
226 <<
"\t\tRequired parameter(s): "
227 << shapesParam1[i]<<
" "
228 << shapesParam2[i]<<
" "
229 << shapesParam3[i]<<
" "
230 << shapesParam4[i]<<std::endl;
243unsigned int checkAndRetrunIndex(
const std::string &shapeName)
247 while ((pos < shapes2D.size()) && (shapes2D[pos] != shapeName))
250 if (pos == shapes2D.size())
252 trace.error() <<
"The specified shape has not found.";
253 trace.info()<<std::endl;
265void missingParam(std::string param)
267 trace.error() <<
" Parameter: "<<param<<
" is required..";
268 trace.info()<<std::endl;
273template <
typename Shape,
typename Space>
275lengthEstimators(
const std::string & ,
280 typedef typename Space::Point Point;
281 typedef typename Space::Vector Vector;
282 typedef typename Space::Integer Integer;
283 typedef HyperRectDomain<Space> Domain;
284 typedef KhalimskySpaceND<Space::dimension,Integer> KSpace;
285 typedef typename KSpace::SCell SCell;
286 typedef typename GridCurve<KSpace>::PointsRange PointsRange;
287 typedef typename GridCurve<KSpace>::ArrowsRange ArrowsRange;
290 GaussDigitizer<Space,Shape> dig;
291 dig.attach( aShape );
292 Vector vlow(-1,-1); Vector vup(1,1);
293 dig.init( aShape.getLowerBound()+vlow, aShape.getUpperBound()+vup, h );
294 Domain domain = dig.getDomain();
298 bool ok = K.init( dig.getLowerBound(), dig.getUpperBound(),
true );
301 std::cerr <<
"[lengthEstimators]"
302 <<
" error in creating KSpace." << std::endl;
308 SurfelAdjacency<KSpace::dimension> SAdj(
true );
309 SCell bel = Surfaces<KSpace>::findABel( K, dig, 10000 );
311 std::vector<Point> points;
312 Surfaces<KSpace>::track2DBoundaryPoints( points, K, SAdj, dig, bel );
314 GridCurve<KSpace> gridcurve;
315 gridcurve.initFromPointsVector( points );
317 ArrowsRange ra = gridcurve.getArrowsRange();
318 PointsRange rp = gridcurve.getPointsRange();
321 typedef typename PointsRange::ConstIterator ConstIteratorOnPoints;
322 typedef ParametricShapeArcLengthFunctor< Shape > Length;
323 TrueGlobalEstimatorOnPoints< ConstIteratorOnPoints, Shape, Length > trueLengthEstimator;
324 trueLengthEstimator.attach( aShape );
326 L1LengthEstimator< typename PointsRange::ConstCirculator > l1length;
327 DSSLengthEstimator< typename PointsRange::ConstCirculator > DSSlength;
328 MLPLengthEstimator< typename PointsRange::ConstCirculator > MLPlength;
329 FPLengthEstimator< typename PointsRange::ConstCirculator > FPlength;
330 BLUELocalLengthEstimator< typename ArrowsRange::ConstCirculator > BLUElength;
331 RosenProffittLocalLengthEstimator< typename ArrowsRange::ConstCirculator > RosenProffittlength;
334 double trueValue = trueLengthEstimator.eval();
335 double l1, blue, rosen,dss,mlp,fp;
336 double Tl1, Tblue, Trosen,Tdss,Tmlp,Tfp;
342 l1 = l1length.eval( rp.c(), rp.c(), h );
346 blue = BLUElength.eval( ra.c(), ra.c(), h );
347 Tblue = c.stopClock();
350 rosen = RosenProffittlength.eval( ra.c(), ra.c(), h );
351 Trosen = c.stopClock();
354 dss = DSSlength.eval( rp.c(), rp.c(), h );
355 Tdss = c.stopClock();
358 mlp = MLPlength.eval( rp.c(), rp.c(), h );
359 Tmlp = c.stopClock();
362 fp = FPlength.eval( rp.c(), rp.c(), h );
365 std::cout << std::setprecision( 15 ) << h <<
" " << rp.size() <<
" " << trueValue
381 catch ( InputException e )
383 std::cerr <<
"[lengthEstimators]"
384 <<
" error in finding a bel." << std::endl;
390int main(
int argc,
char** argv )
394 std::string shapeName;
395 double hMin {0.0001};
399 double smallradius {5};
400 double varsmallradius {5};
406 app.description(
"Generates multigrid contours of 2d digital shapes using DGtal library.\n Typical use example:\n \t contourGenerator --shape <shapeName> [requiredParam] [otherOptions]\n");
407 auto listOpt = app.add_flag(
"--list,-l",
"List all available shapes");
408 auto shapeNameOpt = app.add_option(
"--shape,-s", shapeName,
"Shape name");
409 auto radiusOpt = app.add_option(
"--radius,-R", radius,
"Radius of the shape" );
410 auto axis1Opt = app.add_option(
"--axis1,-A", axis1,
"Half big axis of the shape (ellipse)" );
411 auto axis2Opt = app.add_option(
"--axis2,-a", axis2,
"Half small axis of the shape (ellipse)" );
412 auto smallradiusOpt = app.add_option(
"--smallradius,-r", smallradius,
"Small radius of the shape (default 5)");
413 auto varsmallradiusOpt = app.add_option(
"--varsmallradius,-v", varsmallradius,
"Variable small radius of the shape (default 5)" );
414 auto kOpt = app.add_option(
"-k", k,
"Number of branches or corners the shape (default 3)" );
415 auto phiOpt = app.add_option(
"--phi", phi,
"Phase of the shape (in radian, default 0.0)" );
416 auto widthOpt = app.add_option(
"--width,-w", width,
"Width of the shape (default 10.0)" );
417 auto powerOpt = app.add_option(
"--power,-p", power,
"Power of the metric (default 2.0)" );
418 app.add_option(
"--hMin", hMin,
"Minimum value for the grid step h (double, default 0.0001)" );
419 app.add_option(
"--steps", nbSteps,
"Number of multigrid steps between 1 and hMin (integer, default 32)" );
421 app.get_formatter()->column_width(40);
422 CLI11_PARSE(app, argc, argv);
428 if ( listOpt->count() > 0 )
435 if(shapeNameOpt->count()==0) missingParam(
"--shape");
438 unsigned int id = checkAndRetrunIndex(shapeName);
442 std::cout <<
"#h nbPoints true-length L1 BLUE RosenProffit "
443 <<
"DSS MLP FP Time-L1 Time-BLUE Time-RosenProffitt "
444 <<
"Time-DSS Time-MLP Time-FP" << std::endl;
445 std::cout <<
"# timings are given in msec." << std::endl;
448 double step = exp( log(hMin) / (
double)nbSteps);
453 if (radiusOpt->count()==0) missingParam(
"--radius");
455 Ball2D<Z2i::Space> ball(Z2i::Point(0,0), radius);
457 lengthEstimators<Ball2D<Z2i::Space>,Z2i::Space>(
"ball",ball,h);
464 ImplicitHyperCube<Z2i::Space> object(Z2i::Point(0,0), width/2);
466 trace.error()<<
"Not available.";
467 trace.info()<<std::endl;
473 if (radiusOpt->count()==0) missingParam(
"--radius");
475 ImplicitRoundedHyperCube<Z2i::Space> ball(Z2i::Point(0,0), radius, power);
477 trace.error()<<
"Not available.";
478 trace.info()<<std::endl;
484 if (radiusOpt->count()==0) missingParam(
"--radius");
488 Flower2D<Z2i::Space> flower(Z2i::Point(0,0), radius, varsmallradius,k,phi);
490 lengthEstimators<Flower2D<Z2i::Space>,Z2i::Space>(
"flower",flower,h);
495 if (radiusOpt->count()==0) missingParam(
"--radius");
499 NGon2D<Z2i::Space> object(Z2i::Point(0,0), radius,k,phi);
501 lengthEstimators<NGon2D<Z2i::Space>,Z2i::Space>(
"NGon",object,h);
508 if (radiusOpt->count()==0) missingParam(
"--radius");
512 AccFlower2D<Z2i::Space> flower(Z2i::Point(0,0), radius, varsmallradius,k,phi);
513 lengthEstimators<AccFlower2D<Z2i::Space>,Z2i::Space>(
"accFlower",flower,h);
519 if (axis1Opt->count()==0) missingParam(
"--axis1");
520 if (axis2Opt->count()==0) missingParam(
"--axis2");
523 Ellipse2D<Z2i::Space> ell(Z2i::Point(0,0), axis1, axis2,phi);
525 lengthEstimators<Ellipse2D<Z2i::Space>,Z2i::Space>(
"Ellipse",ell,h);