39 #include <boost/program_options/options_description.hpp>
40 #include <boost/program_options/parsers.hpp>
41 #include <boost/program_options/variables_map.hpp>
43 #include "DGtal/base/Common.h"
44 #include "DGtal/base/Clock.h"
47 #include "DGtal/kernel/SpaceND.h"
48 #include "DGtal/kernel/domains/HyperRectDomain.h"
49 #include "DGtal/topology/KhalimskySpaceND.h"
52 #include "DGtal/shapes/ShapeFactory.h"
53 #include "DGtal/shapes/Shapes.h"
54 #include "DGtal/helpers/StdDefs.h"
55 #include "DGtal/topology/helpers/Surfaces.h"
57 #include "DGtal/shapes/GaussDigitizer.h"
58 #include "DGtal/geometry/curves/GridCurve.h"
61 #include "DGtal/geometry/curves/estimation/TrueLocalEstimatorOnPoints.h"
62 #include "DGtal/geometry/curves/estimation/TrueGlobalEstimatorOnPoints.h"
63 #include "DGtal/geometry/curves/estimation/ParametricShapeArcLengthFunctor.h"
65 #include "DGtal/geometry/curves/estimation/L1LengthEstimator.h"
66 #include "DGtal/geometry/curves/estimation/BLUELocalLengthEstimator.h"
67 #include "DGtal/geometry/curves/estimation/RosenProffittLocalLengthEstimator.h"
68 #include "DGtal/geometry/curves/estimation/MLPLengthEstimator.h"
69 #include "DGtal/geometry/curves/estimation/FPLengthEstimator.h"
70 #include "DGtal/geometry/curves/estimation/DSSLengthEstimator.h"
73 using namespace DGtal;
153 std::vector<std::string> shapes2D;
154 std::vector<std::string> shapesDesc;
155 std::vector<std::string> shapesParam1;
156 std::vector<std::string> shapesParam2;
157 std::vector<std::string> shapesParam3;
158 std::vector<std::string> shapesParam4;
167 shapes2D.push_back(
"ball");
168 shapesDesc.push_back(
"Ball for the Euclidean metric.");
169 shapesParam1.push_back(
"--radius [-R]");
170 shapesParam2.push_back(
"");
171 shapesParam3.push_back(
"");
172 shapesParam4.push_back(
"");
174 shapes2D.push_back(
"square");
175 shapesDesc.push_back(
"square (no signature).");
176 shapesParam1.push_back(
"--width [-w]");
177 shapesParam2.push_back(
"");
178 shapesParam3.push_back(
"");
179 shapesParam4.push_back(
"");
181 shapes2D.push_back(
"lpball");
182 shapesDesc.push_back(
"Ball for the l_power metric (no signature).");
183 shapesParam1.push_back(
"--radius [-R],");
184 shapesParam2.push_back(
"--power [-p]");
185 shapesParam3.push_back(
"");
186 shapesParam4.push_back(
"");
188 shapes2D.push_back(
"flower");
189 shapesDesc.push_back(
"Flower with k petals.");
190 shapesParam1.push_back(
"--radius [-R],");
191 shapesParam2.push_back(
"--varsmallradius [-v],");
192 shapesParam3.push_back(
"--k [-k],");
193 shapesParam4.push_back(
"--phi");
195 shapes2D.push_back(
"ngon");
196 shapesDesc.push_back(
"Regular k-gon.");
197 shapesParam1.push_back(
"--radius [-R],");
198 shapesParam2.push_back(
"--k [-k],");
199 shapesParam3.push_back(
"--phi");
200 shapesParam4.push_back(
"");
202 shapes2D.push_back(
"accflower");
203 shapesDesc.push_back(
"Accelerated Flower with k petals.");
204 shapesParam1.push_back(
"--radius [-R],");
205 shapesParam2.push_back(
"--varsmallradius [-v],");
206 shapesParam3.push_back(
"--k [-k],");
207 shapesParam4.push_back(
"--phi");
209 shapes2D.push_back(
"ellipse");
210 shapesDesc.push_back(
"Ellipse.");
211 shapesParam1.push_back(
"--axis1 [-A],");
212 shapesParam2.push_back(
"--axis2 [-a],");
213 shapesParam3.push_back(
"--phi");
214 shapesParam4.push_back(
"");
226 for(
unsigned int i=0; i<shapes2D.size(); ++i)
228 <<shapesDesc[i]<<std::endl
229 <<
"\t\tRequired parameter(s): "
230 << shapesParam1[i]<<
" "
231 << shapesParam2[i]<<
" "
232 << shapesParam3[i]<<
" "
233 << shapesParam4[i]<<std::endl;
246 unsigned int checkAndRetrunIndex(
const std::string &shapeName)
250 while ((pos < shapes2D.size()) && (shapes2D[pos] != shapeName))
253 if (pos == shapes2D.size())
255 trace.
error() <<
"The specified shape has not found.";
268 void missingParam(std::string param)
270 trace.
error() <<
" Parameter: "<<param<<
" is required..";
276 template <
typename Shape,
typename Space>
278 lengthEstimators(
const std::string & ,
283 typedef typename Space::Point
Point;
284 typedef typename Space::Vector
Vector;
285 typedef typename Space::Integer
Integer;
295 Vector vlow(-1,-1); Vector vup(1,1);
296 dig.
init( aShape.getLowerBound()+vlow, aShape.getUpperBound()+vup, h );
304 std::cerr <<
"[lengthEstimators]"
305 <<
" error in creating KSpace." << std::endl;
313 std::vector<Point> points;
324 typedef typename PointsRange::ConstIterator ConstIteratorOnPoints;
327 trueLengthEstimator.
init( h, rp.begin(), rp.end(), &aShape, gridcurve.
isClosed());
337 double trueValue = trueLengthEstimator.
eval();
338 double l1, blue, rosen,dss,mlp,fp;
339 double Tl1, Tblue, Trosen,Tdss,Tmlp,Tfp;
345 l1length.
init(h, ra.c(), ra.c());
346 l1 = l1length.
eval();
350 BLUElength.
init(h, ra.begin(), ra.end(), gridcurve.
isClosed());
351 blue = BLUElength.
eval();
355 RosenProffittlength.
init(h, ra.begin(), ra.end(), gridcurve.
isClosed());
356 rosen = RosenProffittlength.
eval();
360 DSSlength.
init(h, rp.c(), rp.c());
361 dss = DSSlength.
eval();
365 MLPlength.
init(h, rp.begin(), rp.end(), gridcurve.
isClosed());
366 mlp = MLPlength.
eval();
370 FPlength.
init(h, rp.begin(), rp.end(), gridcurve.
isClosed());
371 fp = FPlength.
eval();
374 std::cout << std::setprecision( 15 ) << h <<
" " << rp.size() <<
" " << trueValue
392 std::cerr <<
"[lengthEstimators]"
393 <<
" error in finding a bel." << std::endl;
398 namespace po = boost::program_options;
400 int main(
int argc,
char** argv )
403 po::options_description general_opt(
"Allowed options are: ");
404 general_opt.add_options()
405 (
"help,h",
"display this message")
406 (
"shape,s", po::value<std::string>(),
"Shape name")
407 (
"list,l",
"List all available shapes")
408 (
"radius,R", po::value<double>(),
"Radius of the shape" )
409 (
"axis1,A", po::value<double>(),
"Half big axis of the shape (ellipse)" )
410 (
"axis2,a", po::value<double>(),
"Half small axis of the shape (ellipse)" )
411 (
"smallradius,r", po::value<double>()->default_value(5),
"Small radius of the shape" )
412 (
"varsmallradius,v", po::value<double>()->default_value(5),
"Variable small radius of the shape" )
413 (
"k,k", po::value<unsigned int>()->default_value(3),
"Number of branches or corners the shape" )
414 (
"phi", po::value<double>()->default_value(0.0),
"Phase of the shape (in radian)" )
415 (
"width,w", po::value<double>()->default_value(10.0),
"Width of the shape" )
416 (
"power,p", po::value<double>()->default_value(2.0),
"Power of the metric (double)" )
417 (
"hMin", po::value<double>()->default_value(0.0001),
"Minimum value for the grid step h (double)" )
418 (
"steps", po::value<int>()->default_value(32),
"Number of multigrid steps between 1 and hMin (integer)" );
421 po::variables_map vm;
423 po::store(po::parse_command_line(argc, argv, general_opt), vm);
424 }
catch(
const std::exception& ex){
426 trace.
info()<<
"Error checking program options: "<< ex.what()<< std::endl;
429 if(!parseOK || vm.count(
"help")||argc<=1)
431 trace.
info()<<
"Generate multigrid length estimations of paramteric shapes using DGtal library. It will output length estimations (and timings) using several algorithms for decreasing grid steps." <<std::endl <<
"Basic usage: "<<std::endl
432 <<
"\tLengthEstimators [options] --shape <shapeName>"<<std::endl
433 << general_opt <<
"\n";
440 if (vm.count(
"list"))
447 if (!(vm.count(
"shape"))) missingParam(
"--shape");
448 std::string shapeName = vm[
"shape"].as<std::string>();
449 double hMin = vm[
"hMin"].as<
double>();
450 int nbSteps = vm[
"steps"].as<
int>();
453 unsigned int id = checkAndRetrunIndex(shapeName);
457 std::cout <<
"#h nbPoints true-length L1 BLUE RosenProffit "
458 <<
"DSS MLP FP Time-L1 Time-BLUE Time-RosenProffitt "
459 <<
"Time-DSS Time-MLP Time-FP" <<std::endl;
460 std::cout <<
"# timings are given in msec." <<std::endl;
463 double step = exp( log(hMin) / (
double)nbSteps);
468 if (!(vm.count(
"radius"))) missingParam(
"--radius");
469 double radius = vm[
"radius"].as<
double>();
473 lengthEstimators<Ball2D<Z2i::Space>,
Z2i::Space>(
"ball",ball,h);
478 if (!(vm.count(
"width"))) missingParam(
"--width");
479 double width = vm[
"width"].as<
double>();
489 if (!(vm.count(
"power"))) missingParam(
"--power");
490 if (!(vm.count(
"radius"))) missingParam(
"--radius");
491 double radius = vm[
"radius"].as<
double>();
492 double power = vm[
"power"].as<
double>();
502 if (!(vm.count(
"varsmallradius"))) missingParam(
"--varsmallradius");
503 if (!(vm.count(
"radius"))) missingParam(
"--radius");
504 if (!(vm.count(
"k"))) missingParam(
"--k");
505 if (!(vm.count(
"phi"))) missingParam(
"--phi");
506 double radius = vm[
"radius"].as<
double>();
507 double varsmallradius = vm[
"varsmallradius"].as<
double>();
508 unsigned int k = vm[
"k"].as<
unsigned int>();
509 double phi = vm[
"phi"].as<
double>();
513 lengthEstimators<Flower2D<Z2i::Space>,
Z2i::Space>(
"flower",flower,h);
518 if (!(vm.count(
"radius"))) missingParam(
"--radius");
519 if (!(vm.count(
"k"))) missingParam(
"--k");
520 if (!(vm.count(
"phi"))) missingParam(
"--phi");
521 double radius = vm[
"radius"].as<
double>();
522 unsigned int k = vm[
"k"].as<
unsigned int>();
523 double phi = vm[
"phi"].as<
double>();
527 lengthEstimators<NGon2D<Z2i::Space>,
Z2i::Space>(
"NGon",object,h);
533 if (!(vm.count(
"varsmallradius"))) missingParam(
"--varsmallradius");
534 if (!(vm.count(
"radius"))) missingParam(
"--radius");
535 if (!(vm.count(
"k"))) missingParam(
"--k");
536 if (!(vm.count(
"phi"))) missingParam(
"--phi");
537 double radius = vm[
"radius"].as<
double>();
538 double varsmallradius = vm[
"varsmallradius"].as<
double>();
539 unsigned int k = vm[
"k"].as<
unsigned int>();
540 double phi = vm[
"phi"].as<
double>();
543 lengthEstimators<AccFlower2D<Z2i::Space>,
Z2i::Space>(
"accFlower",flower,h);
549 if (!(vm.count(
"axis1"))) missingParam(
"--axis1");
550 if (!(vm.count(
"axis2"))) missingParam(
"--axis2");
551 if (!(vm.count(
"phi"))) missingParam(
"--phi");
552 double a1 = vm[
"axis1"].as<
double>();
553 double a2 = vm[
"axis2"].as<
double>();
554 double phi = vm[
"phi"].as<
double>();
558 lengthEstimators<Ellipse2D<Z2i::Space>,
Z2i::Space>(
"Ellipse",ell,h);
PointsRange getPointsRange() const
const Point & getUpperBound() const
ArrowsRange getArrowsRange() const
T power(const T &aVal, const unsigned int exponent)
static SCell findABel(const KSpace &K, const PointPredicate &pp, unsigned int nbtries=1000)
void attach(const EuclideanShape &shape)
bool initFromVector(const std::vector< Point > &aVectorOfPoints)
void init(const RealPoint &xLow, const RealPoint &xUp, typename RealVector::Component gridStep)
void init(const double h, const ConstIterator &itb, const ConstIterator &ite, const bool &isClosed)
bool init(const Point &lower, const Point &upper, bool isClosed)
void init(const double h, const ConstIterator &itb, const ConstIterator &ite)
void init(const double h, const ConstIterator &itb, const ConstIterator &ite)
void init(const double h, const ConstIteratorOnPoints &itb, const ConstIteratorOnPoints &ite, ParametricShape *aShape, const bool &isClosed)
Trace trace(traceWriterTerm)
const Point & getLowerBound() const
void init(const double h, const ConstIterator &itb, const ConstIterator &ite, const bool &isClosed)
static void track2DBoundaryPoints(std::vector< Point > &aVectorOfPoints, const KSpace &K, const SurfelAdjacency< KSpace::dimension > &surfel_adj, const PointPredicate &pp, const SCell &start_surfel)
typename Self::Point Point
void init(const double h, const ConstIterator &itb, const ConstIterator &ite, const bool &isClosed)
typename Self::Domain Domain