44 #include <boost/program_options/options_description.hpp>    45 #include <boost/program_options/parsers.hpp>    46 #include <boost/program_options/variables_map.hpp>    48 #include "DGtal/base/Common.h"    49 #include "DGtal/base/Clock.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"    56 #include "DGtal/topology/DigitalSurface.h"    59 #include "DGtal/shapes/GaussDigitizer.h"    60 #include "DGtal/geometry/curves/GridCurve.h"    61 #include "DGtal/topology/LightImplicitDigitalSurface.h"    62 #include "DGtal/graph/DepthFirstVisitor.h"    63 #include "DGtal/graph/GraphVisitorRange.h"    64 #include "DGtal/geometry/volumes/KanungoNoise.h"    68 #include "DGtal/geometry/curves/estimation/TrueLocalEstimatorOnPoints.h"    69 #include "DGtal/geometry/curves/estimation/TrueGlobalEstimatorOnPoints.h"    70 #include "DGtal/geometry/curves/estimation/ParametricShapeCurvatureFunctor.h"    71 #include "DGtal/geometry/curves/estimation/ParametricShapeTangentFunctor.h"    72 #include "DGtal/geometry/curves/estimation/ParametricShapeArcLengthFunctor.h"    74 #include "DGtal/geometry/curves/BinomialConvolver.h"    75 #include "DGtal/geometry/curves/estimation/MostCenteredMaximalSegmentEstimator.h"    76 #include "DGtal/geometry/curves/estimation/SegmentComputerEstimators.h"    77 #include "DGtal/geometry/curves/ArithmeticalDSSComputer.h"    78 #include "DGtal/geometry/curves/StabbingCircleComputer.h"    80 #include "DGtal/images/ImageHelper.h"    81 #include "DGtal/geometry/surfaces/estimation/IIGeometricFunctors.h"    82 #include "DGtal/geometry/surfaces/estimation/IntegralInvariantVolumeEstimator.h"    84 #include "DGtal/kernel/BasicPointFunctors.h"    86 using namespace DGtal;
   173 std::vector<std::string> shapes2D;
   174 std::vector<std::string> shapesDesc;
   175 std::vector<std::string> shapesParam1;
   176 std::vector<std::string> shapesParam2;
   177 std::vector<std::string> shapesParam3;
   178 std::vector<std::string> shapesParam4;
   180 template< 
typename RealPo
int >
   181 struct OptionsIntegralInvariant
   186   bool lambda_optimized;
   196   shapes2D.push_back(
"ball");
   197   shapesDesc.push_back(
"Ball for the Euclidean metric.");
   198   shapesParam1.push_back(
"--radius [-R]");
   199   shapesParam2.push_back(
"");
   200   shapesParam3.push_back(
"");
   201   shapesParam4.push_back(
"");
   203   shapes2D.push_back(
"square");
   204   shapesDesc.push_back(
"square (no signature).");
   205   shapesParam1.push_back(
"--width [-w]");
   206   shapesParam2.push_back(
"");
   207   shapesParam3.push_back(
"");
   208   shapesParam4.push_back(
"");
   210   shapes2D.push_back(
"lpball");
   211   shapesDesc.push_back(
"Ball for the l_power metric (no signature).");
   212   shapesParam1.push_back(
"--radius [-R],");
   213   shapesParam2.push_back(
"--power [-p]");
   214   shapesParam3.push_back(
"");
   215   shapesParam4.push_back(
"");
   217   shapes2D.push_back(
"flower");
   218   shapesDesc.push_back(
"Flower with k petals with radius ranging from R+/-v.");
   219   shapesParam1.push_back(
"--radius [-R],");
   220   shapesParam2.push_back(
"--varsmallradius [-v],");
   221   shapesParam3.push_back(
"--k [-k],");
   222   shapesParam4.push_back(
"--phi");
   224   shapes2D.push_back(
"ngon");
   225   shapesDesc.push_back(
"Regular k-gon.");
   226   shapesParam1.push_back(
"--radius [-R],");
   227   shapesParam2.push_back(
"--k [-k],");
   228   shapesParam3.push_back(
"--phi");
   229   shapesParam4.push_back(
"");
   231   shapes2D.push_back(
"accflower");
   232   shapesDesc.push_back(
"Accelerated Flower with k petals.");
   233   shapesParam1.push_back(
"--radius [-R],");
   234   shapesParam2.push_back(
"--varsmallradius [-v],");
   235   shapesParam3.push_back(
"--k [-k],");
   236   shapesParam4.push_back(
"--phi");
   238   shapes2D.push_back(
"ellipse");
   239   shapesDesc.push_back(
"Ellipse.");
   240   shapesParam1.push_back(
"--axis1 [-A],");
   241   shapesParam2.push_back(
"--axis2 [-a],");
   242   shapesParam3.push_back(
"--phi");
   243   shapesParam4.push_back(
"");
   254   trace.emphase()<<
"2D Shapes:"<<std::endl;
   255   for(
unsigned int i=0; i<shapes2D.size(); ++i)
   256     trace.info()<<
"\t"<<shapes2D[i]<<
"\t"   257                <<shapesDesc[i]<<std::endl
   258               <<
"\t\tRequired parameter(s): "   259              << shapesParam1[i]<<
" "   260              << shapesParam2[i]<<
" "   261              << shapesParam3[i]<<
" "   262              << shapesParam4[i]<<std::endl;
   275 unsigned int checkAndReturnIndex(
const std::string &shapeName)
   279   while ((pos < shapes2D.size()) && (shapes2D[pos] != shapeName))
   282   if (pos == shapes2D.size())
   284     trace.error() << 
"The specified shape has not found.";
   285     trace.info() << std::endl;
   297 void missingParam(std::string param)
   299   trace.error() <<
" Parameter: "<<param<<
" is required.";
   300   trace.info()<<std::endl;
   310 void estimationError(
int currentSize, 
int expectedSize)
   312   if (currentSize != expectedSize)
   314     trace.error() << 
" error in the estimation"   315                   << 
" (got " << currentSize << 
" values"   316                   << 
" instead of " << expectedSize << 
")";
   317     trace.info() << std::endl;
   333 template <
typename Estimator, 
typename ConstIterator, 
typename OutputIterator>
   335 estimation( Estimator & estimator, 
double h,
   336             const ConstIterator& itb, 
const ConstIterator& ite, 
const OutputIterator& ito )
   340   estimator.init( h, itb, ite );
   341   estimator.eval( itb, ite, ito );
   342   double time = c.stopClock();
   343   std::cout << 
"# Time: " << time << std::endl;
   351 template< 
typename ConstIteratorOnPo
ints, 
typename Po
int >
   352 unsigned int suggestedSizeIntegralInvariant( 
const double h,
   354                                              const ConstIteratorOnPoints& itb,
   355                                              const ConstIteratorOnPoints& ite )
   357   typedef typename Point::Component TValue;
   359   ConstIteratorOnPoints it = itb;
   361   Point distance = p - center;
   362   TValue minRadius = distance.norm();
   365   for ( ; it != ite; ++it )
   368     distance = p - center;
   369     if ( distance.norm() < minRadius )
   371       minRadius = distance.norm();
   375   return minRadius * h;
   391 template <
typename Space, 
typename Shape>
   393 computeLocalEstimations( 
const std::string & filename,
   396                          struct OptionsIntegralInvariant< Z2i::RealPoint > optionsII,
   397                          const std::string & options,
   398                          const std::string & properties,
   399                          double noiseLevel = 0.0 )
   402   typedef typename Space::Point Point;
   403   typedef typename Space::Vector Vector;
   404   typedef typename Space::RealPoint RealPoint;
   405   typedef typename Space::Integer Integer;
   406   typedef HyperRectDomain<Space> Domain;
   407   typedef KhalimskySpaceND<Space::dimension,Integer> KSpace;
   408   typedef typename KSpace::SCell SCell;
   409   typedef GaussDigitizer<Space,Shape> Digitizer;
   410   typedef KanungoNoise< Digitizer, Z2i::Domain > KanungoPredicate;
   412   bool withNoise = ( noiseLevel <= 0.0 ) ? 
false : 
true;
   416   ASSERT (( noiseLevel < 1.0 ));
   418   bool tangent = ( properties.at( 0 ) != 
'0' ) ? 
true : 
false;
   419   bool curvature = ( properties.at( 1 ) != 
'0' ) ? 
true : 
false;
   422   Digitizer* dig = 
new Digitizer();
   423   dig->attach( *aShape ); 
   424   Vector vlow(-1,-1); Vector vup(1,1);
   425   dig->init( aShape->getLowerBound()+vlow, aShape->getUpperBound()+vup, h );
   426   Domain domain = dig->getDomain();
   434   bool ok = K.init( dig->getLowerBound(), dig->getUpperBound(), true );
   437     std::cerr << 
"[2dLocalEstimators]"   438               << 
" error in creating KSpace." << std::endl;
   444     SurfelAdjacency< KSpace::dimension > SAdj( 
true );
   446     std::vector< SCell > points;
   448     KanungoPredicate  *noisifiedObject;
   451       noisifiedObject = 
new KanungoPredicate( *dig, domain, noiseLevel );
   452       bel = Surfaces< KSpace >::findABel( K, *noisifiedObject, 10000 );
   453       Surfaces< KSpace >::track2DBoundary( points, K, SAdj, *noisifiedObject, bel );
   455       double minsize = dig->getUpperBound()[0] - dig->getLowerBound()[0];
   456       while( points.size() < 2 * minsize )
   459         bel = Surfaces< KSpace >::findABel( K, *noisifiedObject, 10000 );
   460         Surfaces< KSpace >::track2DBoundary( points, K, SAdj, *noisifiedObject, bel );
   465       bel = Surfaces< KSpace >::findABel( K, *dig, 10000 );
   466       Surfaces< KSpace >::track2DBoundary( points, K, SAdj, *dig, bel );
   470     GridCurve< KSpace > gridcurve;
   471     gridcurve.initFromSCellsVector( points );
   474     typedef typename GridCurve< KSpace >::MidPointsRange PointsRange;
   475     PointsRange pointsRange = gridcurve.getMidPointsRange();
   478     if (gridcurve.isClosed())
   480       if (options.at(0) != 
'0')
   484           char full_filename[360];
   485           sprintf( full_filename, 
"%s%s", filename.c_str(), 
"_True_tangeant.dat" );
   486           std::ofstream file( full_filename );
   488           file << 
"# h = " << h << std::endl;
   489           file << 
"# True tangents computation" << std::endl;
   490           file << 
"# range size = " << pointsRange.size() << std::endl;
   493             file << 
"# noise level (init) = " << noiseLevel/h << std::endl;
   494             file << 
"# noise level (current) = " << noiseLevel << std::endl;
   497           std::ostream_iterator< RealPoint > out_it( file, 
"\n" );
   499           typedef ParametricShapeTangentFunctor< Shape > TangentFunctor;
   500           typedef typename PointsRange::ConstCirculator C;
   501           TrueLocalEstimatorOnPoints< C, Shape, TangentFunctor >
   502               trueTangentEstimator;
   503           trueTangentEstimator.attach( aShape );
   504           estimation( trueTangentEstimator, h,
   505                       pointsRange.c(), pointsRange.c(),
   514           char full_filename[360];
   515           sprintf( full_filename, 
"%s%s", filename.c_str(), 
"_True_curvature.dat" );
   516           std::ofstream file( full_filename );
   518           file << 
"# h = " << h << std::endl;
   519           file << 
"# True curvature computation" << std::endl;
   520           file << 
"# range size = " << pointsRange.size() << std::endl;
   523             file << 
"# noise level (init) = " << noiseLevel/h << std::endl;
   524             file << 
"# noise level (current) = " << noiseLevel << std::endl;
   527           std::ostream_iterator< double > out_it( file, 
"\n" );
   529           typedef ParametricShapeCurvatureFunctor< Shape > CurvatureFunctor;
   530           typedef typename PointsRange::ConstCirculator C;
   531           TrueLocalEstimatorOnPoints< C, Shape, CurvatureFunctor >
   532               trueCurvatureEstimator;
   533           trueCurvatureEstimator.attach( aShape );
   534           estimation( trueCurvatureEstimator, h,
   535                       pointsRange.c(), pointsRange.c(),
   543       if (options.at(1) != 
'0')
   547           char full_filename[360];
   548           sprintf( full_filename, 
"%s%s", filename.c_str(), 
"_MDSS_tangeant.dat" );
   549           std::ofstream file( full_filename );
   551           file << 
"# h = " << h << std::endl;
   552           file << 
"# Most centered maximal DSS tangent estimation" << std::endl;
   553           file << 
"# range size = " << pointsRange.size() << std::endl;
   556             file << 
"# noise level (init) = " << noiseLevel/h << std::endl;
   557             file << 
"# noise level (current) = " << noiseLevel << std::endl;
   560           std::ostream_iterator< RealPoint > out_it( file, 
"\n" );
   562           typedef typename GridCurve< KSpace >::PointsRange PointsRange2;
   563           PointsRange2 pointsRange2 = gridcurve.getPointsRange();
   565           typedef typename PointsRange2::ConstCirculator C;
   566           typedef ArithmeticalDSSComputer< C, int, 4 > SegmentComputer;
   567           typedef TangentFromDSSEstimator<SegmentComputer> SCFunctor;
   572           MostCenteredMaximalSegmentEstimator<SegmentComputer,SCFunctor> MDSSTangentEstimator(sc, f);
   573           estimation( MDSSTangentEstimator, h,
   574                       pointsRange2.c(), pointsRange2.c(),
   583           char full_filename[360];
   584           sprintf( full_filename, 
"%s%s", filename.c_str(), 
"_MDSSl_curvature.dat" );
   585           std::ofstream file( full_filename );
   587           file << 
"# h = " << h << std::endl;
   588           file << 
"# Most centered maximal DSS (length) curvature estimation" << std::endl;
   589           file << 
"# range size = " << pointsRange.size() << std::endl;
   592             file << 
"# noise level (init) = " << noiseLevel/h << std::endl;
   593             file << 
"# noise level (current) = " << noiseLevel << std::endl;
   596           std::ostream_iterator< double > out_it( file, 
"\n" );
   598           typedef typename GridCurve< KSpace >::PointsRange PointsRange2;
   599           PointsRange2 pointsRange2 = gridcurve.getPointsRange();
   601           typedef typename PointsRange2::ConstCirculator C;
   602           typedef ArithmeticalDSSComputer< C, int, 4 > SegmentComputer;
   603           typedef CurvatureFromDSSLengthEstimator<SegmentComputer> SCFunctor;
   606           MostCenteredMaximalSegmentEstimator<SegmentComputer,SCFunctor> MDSSCurvatureEstimator(sc, f);
   608           estimation( MDSSCurvatureEstimator, h,
   609                       pointsRange2.c(), pointsRange2.c(),
   615           memset(&full_filename[0], 0, 
sizeof(full_filename));
   616           sprintf( full_filename, 
"%s%s", filename.c_str(), 
"_MDSSlw_curvature.dat" );
   617           file.open( full_filename );
   619           file << 
"# h = " << h << std::endl;
   620           file << 
"# Most centered maximal DSS (length & width) curvature estimation" << std::endl;
   621           file << 
"# range size = " << pointsRange.size() << std::endl;
   624             file << 
"# noise level (init) = " << noiseLevel/h << std::endl;
   625             file << 
"# noise level (current) = " << noiseLevel << std::endl;
   628           std::ostream_iterator< double > out_it2( file, 
"\n" );
   630           typedef CurvatureFromDSSEstimator<SegmentComputer> SCFunctor2;
   633           MostCenteredMaximalSegmentEstimator<SegmentComputer,SCFunctor2> MDSSCurvatureEstimator2(sc2, f2);
   634           estimation( MDSSCurvatureEstimator2, h,
   635                       pointsRange2.c(), pointsRange2.c(),
   638           double time = c.stopClock();
   639           file << 
"# Time: " << time << std::endl;
   647       if (options.at(2) != 
'0')
   651           char full_filename[360];
   652           sprintf( full_filename, 
"%s%s", filename.c_str(), 
"_MDCA_tangent.dat" );
   653           std::ofstream file( full_filename );
   655           file << 
"# h = " << h << std::endl;
   656           file << 
"# Most centered maximal DCA tangents estimation" << std::endl;
   657           file << 
"# range size = " << pointsRange.size() << std::endl;
   660             file << 
"# noise level (init) = " << noiseLevel/h << std::endl;
   661             file << 
"# noise level (current) = " << noiseLevel << std::endl;
   664           std::ostream_iterator< RealPoint > out_it( file, 
"\n" );
   666           typedef typename GridCurve<KSpace>::IncidentPointsRange Range;
   667           typedef typename Range::ConstCirculator C;
   668           Range r = gridcurve.getIncidentPointsRange();
   669           typedef StabbingCircleComputer<C> SegmentComputer;
   670           typedef TangentFromDCAEstimator<SegmentComputer> SCFunctor;
   673           MostCenteredMaximalSegmentEstimator<SegmentComputer,SCFunctor> MDCATangentEstimator(sc, f);
   674           estimation( MDCATangentEstimator, h,
   685           char full_filename[360];
   686           sprintf( full_filename, 
"%s%s", filename.c_str(), 
"_MDCA_curvature.dat" );
   687           std::ofstream file( full_filename );
   689           file << 
"# h = " << h << std::endl;
   690           file << 
"# Most centered maximal DCA curvature estimation" << std::endl;
   691           file << 
"# range size = " << pointsRange.size() << std::endl;
   694             file << 
"# noise level (init) = " << noiseLevel/h << std::endl;
   695             file << 
"# noise level (current) = " << noiseLevel << std::endl;
   698           std::ostream_iterator< double > out_it( file, 
"\n" );
   700           typedef typename GridCurve<KSpace>::IncidentPointsRange Range;
   701           typedef typename Range::ConstCirculator C;
   702           Range r = gridcurve.getIncidentPointsRange();
   703           typedef StabbingCircleComputer<C> SegmentComputer;
   704           typedef CurvatureFromDCAEstimator<SegmentComputer, false> SCFunctor;
   707           MostCenteredMaximalSegmentEstimator<SegmentComputer,SCFunctor> MDCACurvatureEstimator(sc, f);
   708           estimation( MDCACurvatureEstimator, h,
   712           double time = c.stopClock();
   713           file << 
"# Time: " << time << std::endl;
   720       if (options.at(3) != 
'0')
   726           char full_filename[360];
   727           sprintf( full_filename, 
"%s%s", filename.c_str(), 
"_BC_tangeant.dat" );
   728           std::ofstream file( full_filename );
   730           file << 
"# h = " << h << std::endl;
   731           file << 
"# Tangents estimation from binomial convolution" << std::endl;
   732           file << 
"# range size = " << pointsRange.size() << std::endl;
   735             file << 
"# noise level (init) = " << noiseLevel/h << std::endl;
   736             file << 
"# noise level (current) = " << noiseLevel << std::endl;
   739           typedef typename PointsRange::ConstIterator I;
   740           typedef BinomialConvolver<I, double> MyBinomialConvolver;
   741           file << 
"# mask size = " <<
   742                   MyBinomialConvolver::suggestedSize( h, pointsRange.begin(), pointsRange.end() ) << std::endl;
   744           typedef TangentFromBinomialConvolverFunctor< MyBinomialConvolver, RealPoint >
   746           BinomialConvolverEstimator< MyBinomialConvolver, TangentBCFct> BCTangentEstimator;
   748           std::ostream_iterator< RealPoint > out_it( file, 
"\n" );
   750           BCTangentEstimator.init( h, pointsRange.begin(), pointsRange.end(), true );
   751           BCTangentEstimator.eval( pointsRange.begin(), pointsRange.end(), out_it );
   753           double time = c.stopClock();
   754           file << 
"# Time: " << time << std::endl;
   763           char full_filename[360];
   764           sprintf( full_filename, 
"%s%s", filename.c_str(), 
"_BC_curvature.dat" );
   765           std::ofstream file( full_filename );
   767           file << 
"# h = " << h << std::endl;
   768           file << 
"# Curvature estimation from binomial convolution" << std::endl;
   769           file << 
"# range size = " << pointsRange.size() << std::endl;
   772             file << 
"# noise level (init) = " << noiseLevel/h << std::endl;
   773             file << 
"# noise level (current) = " << noiseLevel << std::endl;
   776           typedef typename PointsRange::ConstIterator I;
   777           typedef BinomialConvolver<I, double> MyBinomialConvolver;
   778           file << 
"# mask size = " <<
   779                   MyBinomialConvolver::suggestedSize( h, pointsRange.begin(), pointsRange.end() ) << std::endl;
   781           std::ostream_iterator< double > out_it( file, 
"\n" );
   783           typedef CurvatureFromBinomialConvolverFunctor< MyBinomialConvolver, double >
   785           BinomialConvolverEstimator< MyBinomialConvolver, CurvatureBCFct> BCCurvatureEstimator;
   787           BCCurvatureEstimator.init( h, pointsRange.begin(), pointsRange.end(), true );
   788           BCCurvatureEstimator.eval( pointsRange.begin(), pointsRange.end(), out_it );
   790           double time = c.stopClock();
   791           file << 
"# Time: " << time << std::endl;
   799       if (options.at(4) != 
'0')
   805           char full_filename[360];
   806           sprintf( full_filename, 
"%s%s", filename.c_str(), 
"_II_curvature.dat" );
   807           std::ofstream file( full_filename );
   809           file << 
"# h = " << h << std::endl;
   810           file << 
"# Integral Invariant curvature estimation" << std::endl;
   811           file << 
"# range size = " << pointsRange.size() << std::endl;
   814             file << 
"# noise level (init) = " << noiseLevel/h << std::endl;
   815             file << 
"# noise level (current) = " << noiseLevel << std::endl;
   818           if( optionsII.radius <= 0.0 )
   820             optionsII.radius = suggestedSizeIntegralInvariant( h, dig->round( optionsII.center ), pointsRange.begin(), pointsRange.end() );
   821             file << 
"# Estimated radius: " << optionsII.radius << std::endl;
   823           double re = optionsII.radius * std::pow( h, optionsII.alpha );
   824           file << 
"# full kernel (digital) size (with alpha = " << optionsII.alpha << 
") = " <<
   827           std::ostream_iterator< double > out_it( file, 
"\n" );
   831             typedef LightImplicitDigitalSurface< KSpace, KanungoPredicate > LightImplicitDigSurface;
   832             typedef DigitalSurface< LightImplicitDigSurface > DigSurface;
   834             LightImplicitDigSurface LightImplDigSurf( K, *noisifiedObject, SAdj, bel );
   835             DigSurface surf( LightImplDigSurf );
   837             typedef DepthFirstVisitor< DigSurface > Visitor;
   838             typedef GraphVisitorRange< Visitor > VisitorRange;
   839             typedef typename VisitorRange::ConstIterator VisitorConstIterator;
   841             VisitorRange range( 
new Visitor( surf, *surf.begin() ));
   842             VisitorConstIterator ibegin = range.begin();
   843             VisitorConstIterator iend = range.end();
   845             typedef functors::IICurvatureFunctor<Z2i::Space> MyIICurvatureFunctor;
   846             typedef IntegralInvariantVolumeEstimator< KSpace, KanungoPredicate, MyIICurvatureFunctor > MyIICurvatureEstimator;
   848             MyIICurvatureFunctor curvatureFunctor;
   849             curvatureFunctor.init( h, re );
   851             MyIICurvatureEstimator curvatureEstimator( curvatureFunctor );
   852             curvatureEstimator.attach( K, *noisifiedObject );
   853             curvatureEstimator.setParams( re/h );
   854             curvatureEstimator.init( h, ibegin, iend );
   856             curvatureEstimator.eval( ibegin, iend, out_it );
   860             typedef LightImplicitDigitalSurface< KSpace, Digitizer > LightImplicitDigSurface;
   861             typedef DigitalSurface< LightImplicitDigSurface > DigSurface;
   863             LightImplicitDigSurface LightImplDigSurf( K, *dig, SAdj, bel );
   864             DigSurface surf( LightImplDigSurf );
   866             typedef DepthFirstVisitor< DigSurface > Visitor;
   867             typedef GraphVisitorRange< Visitor > VisitorRange;
   868             typedef typename VisitorRange::ConstIterator VisitorConstIterator;
   870             VisitorRange range( 
new Visitor( surf, *surf.begin() ));
   871             VisitorConstIterator ibegin = range.begin();
   872             VisitorConstIterator iend = range.end();
   874             typedef functors::IICurvatureFunctor<Z2i::Space> MyIICurvatureFunctor;
   875             typedef IntegralInvariantVolumeEstimator< KSpace, Digitizer, MyIICurvatureFunctor > MyIICurvatureEstimator;
   877             MyIICurvatureFunctor curvatureFunctor;
   878             curvatureFunctor.init( h, re );
   880             MyIICurvatureEstimator curvatureEstimator( curvatureFunctor );
   881             curvatureEstimator.attach( K, *dig );
   882             curvatureEstimator.setParams( re/h );
   883             curvatureEstimator.init( h, ibegin, iend );
   885             curvatureEstimator.eval( ibegin, iend, out_it );
   888           double time = c.stopClock();
   889           file << 
"# Time: " << time << std::endl;
   902       std::cerr << 
"[computeLocalEstimations]"   903                 << 
" error: open digital curve found." << std::endl;
   907   catch ( InputException e )
   909     std::cerr << 
"[computeLocalEstimations]"   910               << 
" error in finding a bel." << std::endl;
   918 namespace po = boost::program_options;
   920 int main( 
int argc, 
char** argv )
   923   po::options_description general_opt(
"Allowed options are");
   924   general_opt.add_options()
   925       (
"help,h", 
"display this message")
   926       (
"list,l",  
"List all available shapes")
   927       (
"output,o", po::value<std::string>(), 
"Output")
   928       (
"shape,s", po::value<std::string>(), 
"Shape name")
   929       (
"radius,R",  po::value<double>(), 
"Radius of the shape" )
   930       (
"kernelradius,K",  po::value<double>()->default_value(0.0), 
"Radius of the convolution kernel (Integral invariants estimators)" )
   931       (
"alpha",  po::value<double>()->default_value(1.0/3.0), 
"Alpha parameter for Integral Invariant computation" )
   932       (
"axis1,A",  po::value<double>(), 
"Half big axis of the shape (ellipse)" )
   933       (
"axis2,a",  po::value<double>(), 
"Half small axis of the shape (ellipse)" )
   934       (
"smallradius,r",  po::value<double>()->default_value(5), 
"Small radius of the shape" )
   935       (
"varsmallradius,v",  po::value<double>()->default_value(5), 
"Variable small radius of the shape" )
   936       (
"k,k",  po::value<unsigned int>()->default_value(3), 
"Number of branches or corners the shape" )
   937       (
"phi",  po::value<double>()->default_value(0.0), 
"Phase of the shape (in radian)" )
   938       (
"width,w",  po::value<double>()->default_value(10.0), 
"Width of the shape" )
   939       (
"power,p",   po::value<double>()->default_value(2.0), 
"Power of the metric (double)" )
   940       (
"center_x,x",   po::value<double>()->default_value(0.0), 
"x-coordinate of the shape center (double)" )
   941       (
"center_y,y",   po::value<double>()->default_value(0.0), 
"y-coordinate of the shape center (double)" )
   942       (
"gridstep,g",  po::value<double>()->default_value(1.0), 
"Grid step for the digitization" )
   943       (
"noise,n",  po::value<double>()->default_value(0.0), 
"Level of noise to perturb the shape" )
   944       (
"properties",  po::value<std::string>()->default_value(
"11"), 
"the i-th property is disabled iff there is a 0 at position i" )
   945       (
"estimators,e",  po::value<std::string>()->default_value(
"10000"), 
"the i-th estimator is disabled iff there is a 0 at position i" )
   946       (
"lambda,l",  po::value< bool >()->default_value( 
false ), 
"Use the shape to get a better approximation of the surface (optional)" );
   950   po::variables_map vm;
   952     po::store(po::parse_command_line(argc, argv, general_opt), vm);
   953   }
catch(
const std::exception& ex){
   955     trace.info()<< 
"Error checking program options: "<< ex.what()<< std::endl;
   958   if(!parseOK || vm.count(
"help")||argc<=1)
   960     trace.info()<< 
"Compare local estimators on implicit shapes using DGtal library" <<std::endl
   961                 << 
"Basic usage: "<<std::endl
   962                 << 
"\t2dlocalEstimators --output <output> --shape <shapeName> [required parameters] --estimators <binaryWord> --properties <binaryWord>"<<std::endl
   964                 << 
"Below are the different available families of estimators: " << std::endl
   965                 << 
"\t - True estimators" << std::endl
   966                 << 
"\t - Maximal DSS based estimators" << std::endl
   967                 << 
"\t - Maximal DCA based estimators" << std::endl
   968                 << 
"\t - Binomial convolver based estimators" << std::endl
   969                 << 
"\t - Integral Invariants based estimators" << std::endl
   971                 << 
"The i-th family of estimators is enabled if the i-th character of the binary word is not 0. "   972                 << 
"The default binary word is '10000'. This means that the first family of estimators, "   973                 << 
"ie. true estimators, is enabled, whereas the next ones are disabled. "   975                 << 
"Below are the different available properties: " << std::endl
   976                 << 
"\t - Tangent" << std::endl
   977                 << 
"\t - Curvature" << std::endl
   979                 << 
"Example: "<<std::endl
   980                 << 
"\t2dlocalEstimators --output curvature --shape ellipse --axis1 20 --axis2 7 --gridstep 0.1 --kernelradius 5 --estimators 10001 --properties 01"<<std::endl
   982                 << general_opt << std::endl;
   989   if (vm.count(
"list"))
   996   if (!(vm.count(
"shape"))) missingParam(
"--shape");
   997   if (!(vm.count(
"output"))) missingParam(
"--output");
   999   std::string shapeName = vm[
"shape"].as<std::string>();
  1000   std::string filename = vm[
"output"].as<std::string>();
  1002   unsigned int nb = 4; 
  1003   std::string options = vm[
"estimators"].as< std::string >();
  1004   if (options.size() < nb)
  1006     trace.error() << 
" At least " << nb
  1007                   << 
" characters are required "  1008                   << 
" with option --estimators.";
  1009     trace.info() << std::endl;
  1014   std::string properties = vm[
"properties"].as<std::string>();
  1015   if (properties.size() < nb)
  1017     trace.error() << 
" At least " << nb
  1018                   << 
" characters are required "  1019                   << 
" with option --properties.";
  1020     trace.info() << std::endl;
  1025   unsigned int id = checkAndReturnIndex(shapeName);
  1028   typedef Z2i::Space Space;
  1029   typedef Space::Point Point;
  1030   typedef Space::RealPoint RealPoint;
  1032   RealPoint center( vm[
"center_x"].as<double>(),
  1033       vm[
"center_y"].as<double>() );
  1034   double h = vm[
"gridstep"].as<
double>();
  1036   struct OptionsIntegralInvariant< RealPoint > optII;
  1037   optII.radius = vm[
"kernelradius"].as<
double>();
  1038   optII.alpha = vm[
"alpha"].as<
double>();
  1039   optII.lambda_optimized = vm[
"lambda"].as< 
bool >();
  1040   optII.center = center;
  1042   double noiseLevel = vm[
"noise"].as<
double>();
  1046     if (!(vm.count(
"radius"))) missingParam(
"--radius");
  1048     double radius = vm[
"radius"].as<
double>();
  1050     Ball2D<Space> * ball = 
new Ball2D<Space>( center, radius);
  1051     computeLocalEstimations<Space>( filename, ball, h, optII, options, properties, noiseLevel );
  1056     if (!(vm.count(
"width"))) missingParam(
"--width");
  1057     double width = vm[
"width"].as<
double>();
  1059     ImplicitHyperCube<Space> object(Z2i::Point(0,0), width/2);
  1060     trace.error()<< 
"Not available.";
  1061     trace.info()<<std::endl;
  1065     if (!(vm.count(
"power"))) missingParam(
"--power");
  1066     if (!(vm.count(
"radius"))) missingParam(
"--radius");
  1067     double radius = vm[
"radius"].as<
double>();
  1068     double power = vm[
"power"].as<
double>();
  1070     ImplicitRoundedHyperCube<Space> ball( Z2i::Point(0,0), radius, power );
  1071     trace.error()<< 
"Not available.";
  1072     trace.info()<<std::endl;
  1076     if (!(vm.count(
"varsmallradius"))) missingParam(
"--varsmallradius");
  1077     if (!(vm.count(
"radius"))) missingParam(
"--radius");
  1078     if (!(vm.count(
"k"))) missingParam(
"--k");
  1079     if (!(vm.count(
"phi"))) missingParam(
"--phi");
  1081     double radius = vm[
"radius"].as<
double>();
  1082     double varsmallradius = vm[
"varsmallradius"].as<
double>();
  1083     unsigned int k = vm[
"k"].as<
unsigned int>();
  1084     double phi = vm[
"phi"].as<
double>();
  1086     Flower2D<Space> * flower = 
new Flower2D<Space>( center, radius, varsmallradius, k, phi );
  1087     computeLocalEstimations<Space>( filename, flower, h, optII, options, properties, noiseLevel );
  1092     if (!(vm.count(
"radius"))) missingParam(
"--radius");
  1093     if (!(vm.count(
"k"))) missingParam(
"--k");
  1094     if (!(vm.count(
"phi"))) missingParam(
"--phi");
  1096     double radius = vm[
"radius"].as<
double>();
  1097     unsigned int k = vm[
"k"].as<
unsigned int>();
  1098     double phi = vm[
"phi"].as<
double>();
  1100     NGon2D<Space> * 
object = 
new NGon2D<Space>( center, radius, k, phi );
  1101     computeLocalEstimations<Space>( filename, object, h, optII, options, properties, noiseLevel );
  1106     if (!(vm.count(
"varsmallradius"))) missingParam(
"--varsmallradius");
  1107     if (!(vm.count(
"radius"))) missingParam(
"--radius");
  1108     if (!(vm.count(
"k"))) missingParam(
"--k");
  1109     if (!(vm.count(
"phi"))) missingParam(
"--phi");
  1111     double radius = vm[
"radius"].as<
double>();
  1112     double varsmallradius = vm[
"varsmallradius"].as<
double>();
  1113     unsigned int k = vm[
"k"].as<
unsigned int>();
  1114     double phi = vm[
"phi"].as<
double>();
  1116     AccFlower2D<Space> * accflower = 
new AccFlower2D<Space>( center, radius, varsmallradius, k, phi );
  1117     computeLocalEstimations<Space>( filename, accflower, h, optII, options, properties, noiseLevel );
  1122     if (!(vm.count(
"axis1"))) missingParam(
"--axis1");
  1123     if (!(vm.count(
"axis2"))) missingParam(
"--axis2");
  1124     if (!(vm.count(
"phi"))) missingParam(
"--phi");
  1126     double a1 = vm[
"axis1"].as<
double>();
  1127     double a2 = vm[
"axis2"].as<
double>();
  1128     double phi = vm[
"phi"].as<
double>();
  1130     Ellipse2D<Space> * ellipse = 
new Ellipse2D<Space>( center, a1, a2, phi );
  1131     computeLocalEstimations<Space>( filename, ellipse, h, optII, options, properties, noiseLevel );