47#include "DGtal/base/Common.h"
48#include "DGtal/base/Clock.h"
51#include "DGtal/shapes/ShapeFactory.h"
52#include "DGtal/shapes/Shapes.h"
53#include "DGtal/helpers/StdDefs.h"
54#include "DGtal/topology/helpers/Surfaces.h"
55#include "DGtal/topology/DigitalSurface.h"
58#include "DGtal/shapes/GaussDigitizer.h"
59#include "DGtal/geometry/curves/GridCurve.h"
60#include "DGtal/topology/LightImplicitDigitalSurface.h"
61#include "DGtal/graph/DepthFirstVisitor.h"
62#include "DGtal/graph/GraphVisitorRange.h"
63#include "DGtal/geometry/volumes/KanungoNoise.h"
67#include "DGtal/geometry/curves/estimation/TrueLocalEstimatorOnPoints.h"
68#include "DGtal/geometry/curves/estimation/TrueGlobalEstimatorOnPoints.h"
69#include "DGtal/geometry/curves/estimation/ParametricShapeCurvatureFunctor.h"
70#include "DGtal/geometry/curves/estimation/ParametricShapeTangentFunctor.h"
71#include "DGtal/geometry/curves/estimation/ParametricShapeArcLengthFunctor.h"
73#include "DGtal/geometry/curves/BinomialConvolver.h"
74#include "DGtal/geometry/curves/estimation/MostCenteredMaximalSegmentEstimator.h"
75#include "DGtal/geometry/curves/estimation/SegmentComputerEstimators.h"
76#include "DGtal/geometry/curves/ArithmeticalDSSComputer.h"
77#include "DGtal/geometry/curves/StabbingCircleComputer.h"
79#include "DGtal/images/ImageHelper.h"
80#include "DGtal/geometry/surfaces/estimation/IIGeometricFunctors.h"
81#include "DGtal/geometry/surfaces/estimation/IntegralInvariantVolumeEstimator.h"
83#include "DGtal/kernel/BasicPointFunctors.h"
169std::vector<std::string> shapes2D;
170std::vector<std::string> shapesDesc;
171std::vector<std::string> shapesParam1;
172std::vector<std::string> shapesParam2;
173std::vector<std::string> shapesParam3;
174std::vector<std::string> shapesParam4;
176template<
typename RealPo
int >
177struct OptionsIntegralInvariant
182 bool lambda_optimized;
192 shapes2D.push_back(
"ball");
193 shapesDesc.push_back(
"Ball for the Euclidean metric.");
194 shapesParam1.push_back(
"--radius [-R]");
195 shapesParam2.push_back(
"");
196 shapesParam3.push_back(
"");
197 shapesParam4.push_back(
"");
199 shapes2D.push_back(
"square");
200 shapesDesc.push_back(
"square (no signature).");
201 shapesParam1.push_back(
"--width [-w]");
202 shapesParam2.push_back(
"");
203 shapesParam3.push_back(
"");
204 shapesParam4.push_back(
"");
206 shapes2D.push_back(
"lpball");
207 shapesDesc.push_back(
"Ball for the l_power metric (no signature).");
208 shapesParam1.push_back(
"--radius [-R],");
209 shapesParam2.push_back(
"--power [-p]");
210 shapesParam3.push_back(
"");
211 shapesParam4.push_back(
"");
213 shapes2D.push_back(
"flower");
214 shapesDesc.push_back(
"Flower with k petals with radius ranging from R+/-v.");
215 shapesParam1.push_back(
"--radius [-R],");
216 shapesParam2.push_back(
"--varsmallradius [-v],");
217 shapesParam3.push_back(
"--k [-k],");
218 shapesParam4.push_back(
"--phi");
220 shapes2D.push_back(
"ngon");
221 shapesDesc.push_back(
"Regular k-gon.");
222 shapesParam1.push_back(
"--radius [-R],");
223 shapesParam2.push_back(
"--k [-k],");
224 shapesParam3.push_back(
"--phi");
225 shapesParam4.push_back(
"");
227 shapes2D.push_back(
"accflower");
228 shapesDesc.push_back(
"Accelerated Flower with k petals.");
229 shapesParam1.push_back(
"--radius [-R],");
230 shapesParam2.push_back(
"--varsmallradius [-v],");
231 shapesParam3.push_back(
"--k [-k],");
232 shapesParam4.push_back(
"--phi");
234 shapes2D.push_back(
"ellipse");
235 shapesDesc.push_back(
"Ellipse.");
236 shapesParam1.push_back(
"--axis1 [-A],");
237 shapesParam2.push_back(
"--axis2 [-a],");
238 shapesParam3.push_back(
"--phi");
239 shapesParam4.push_back(
"");
250 trace.emphase()<<
"2D Shapes:"<<std::endl;
251 for(
unsigned int i=0; i<shapes2D.size(); ++i)
252 trace.info()<<
"\t"<<shapes2D[i]<<
"\t"
253 <<shapesDesc[i]<<std::endl
254 <<
"\t\tRequired parameter(s): "
255 << shapesParam1[i]<<
" "
256 << shapesParam2[i]<<
" "
257 << shapesParam3[i]<<
" "
258 << shapesParam4[i]<<std::endl;
271unsigned int checkAndReturnIndex(
const std::string &shapeName)
275 while ((pos < shapes2D.size()) && (shapes2D[pos] != shapeName))
278 if (pos == shapes2D.size())
280 trace.error() <<
"The specified shape has not found.";
281 trace.info() << std::endl;
293void missingParam(std::string param)
295 trace.error() <<
" Parameter: "<<param<<
" is required.";
296 trace.info()<<std::endl;
306void estimationError(
int currentSize,
int expectedSize)
308 if (currentSize != expectedSize)
310 trace.error() <<
" error in the estimation"
311 <<
" (got " << currentSize <<
" values"
312 <<
" instead of " << expectedSize <<
")";
313 trace.info() << std::endl;
329template <
typename Estimator,
typename ConstIterator,
typename OutputIterator>
331estimation( Estimator & estimator,
double h,
332 const ConstIterator& itb,
const ConstIterator& ite,
const OutputIterator& ito )
336 estimator.eval( itb, ite, ito, h );
337 double time = c.stopClock();
338 std::cout <<
"# Time: " << time << std::endl;
346template<
typename ConstIteratorOnPo
ints,
typename RPo
int >
347unsigned int suggestedSizeIntegralInvariant(
const double h,
348 const RPoint& center,
349 const ConstIteratorOnPoints& itb,
350 const ConstIteratorOnPoints& ite )
352 ConstIteratorOnPoints it = itb;
354 RPoint distance = p - center;
355 auto minRadius = distance.norm();
358 for ( ; it != ite; ++it )
361 distance = p - center;
362 if ( distance.norm() < minRadius )
364 minRadius = distance.norm();
368 return minRadius * h;
384template <
typename Space,
typename Shape>
386computeLocalEstimations(
const std::string & filename,
389 struct OptionsIntegralInvariant< Z2i::RealPoint > optionsII,
390 const std::string & options,
391 const std::string & properties,
392 const std::string & outShape,
393 double noiseLevel = 0.0 )
396 typedef typename Space::Vector Vector;
397 typedef typename Space::RealPoint RealPoint;
398 typedef typename Space::Integer Integer;
399 typedef HyperRectDomain<Space> Domain;
400 typedef KhalimskySpaceND<Space::dimension,Integer> KSpace;
401 typedef typename KSpace::SCell SCell;
402 typedef GaussDigitizer<Space,Shape> Digitizer;
403 typedef KanungoNoise< Digitizer, Z2i::Domain > KanungoPredicate;
405 bool withNoise = ( noiseLevel <= 0.0 ) ?
false : true;
409 ASSERT (( noiseLevel < 1.0 ));
411 bool tangent = ( properties.at( 0 ) !=
'0' ) ?
true : false;
412 bool curvature = ( properties.at( 1 ) !=
'0' ) ?
true : false;
415 Digitizer* dig =
new Digitizer();
416 dig->attach( aShape );
417 Vector vlow(-1,-1); Vector vup(1,1);
418 dig->init( aShape.getLowerBound()+vlow, aShape.getUpperBound()+vup, h );
419 Domain domain = dig->getDomain();
427 bool ok = K.init( dig->getLowerBound(), dig->getUpperBound(),
true );
430 std::cerr <<
"[2dLocalEstimators]"
431 <<
" error in creating KSpace." << std::endl;
437 SurfelAdjacency< KSpace::dimension > SAdj(
true );
439 std::vector< SCell > points;
441 KanungoPredicate *noisifiedObject;
444 noisifiedObject =
new KanungoPredicate( *dig, domain, noiseLevel );
445 bel = Surfaces< KSpace >::findABel( K, *noisifiedObject, 10000 );
446 Surfaces< KSpace >::track2DBoundary( points, K, SAdj, *noisifiedObject, bel );
448 double minsize = dig->getUpperBound()[0] - dig->getLowerBound()[0];
449 while( points.size() < 2 * minsize )
452 bel = Surfaces< KSpace >::findABel( K, *noisifiedObject, 10000 );
453 Surfaces< KSpace >::track2DBoundary( points, K, SAdj, *noisifiedObject, bel );
458 bel = Surfaces< KSpace >::findABel( K, *dig, 10000 );
459 Surfaces< KSpace >::track2DBoundary( points, K, SAdj, *dig, bel );
463 GridCurve< KSpace > gridcurve;
464 gridcurve.initFromSCellsVector( points );
468 outS.open(outShape.c_str());
469 for(
const auto &p : points)
472 Dimension track = *( K.sDirs( p ) );
473 SCell pointel = K.sIndirectIncident( p, track );
474 outS << K.sCoords( pointel )[0] <<
" " << K.sCoords( pointel )[1] << std::endl;
479 typedef typename GridCurve< KSpace >::MidPointsRange PointsRange;
480 PointsRange pointsRange = gridcurve.getMidPointsRange();
483 if (gridcurve.isClosed())
485 if (options.at(0) !=
'0')
489 char full_filename[360];
490 sprintf( full_filename,
"%s%s", filename.c_str(),
"_True_tangeant.dat" );
491 std::ofstream file( full_filename );
493 file <<
"# h = " << h << std::endl;
494 file <<
"# True tangents computation" << std::endl;
495 file <<
"# range size = " << pointsRange.size() << std::endl;
498 file <<
"# noise level (init) = " << noiseLevel/h << std::endl;
499 file <<
"# noise level (current) = " << noiseLevel << std::endl;
502 std::ostream_iterator< RealPoint > out_it( file,
"\n" );
504 typedef ParametricShapeTangentFunctor< Shape > TangentFunctor;
505 typedef typename PointsRange::ConstCirculator C;
506 TrueLocalEstimatorOnPoints< C, Shape, TangentFunctor >
507 trueTangentEstimator;
508 trueTangentEstimator.attach( aShape );
509 estimation( trueTangentEstimator, h,
510 pointsRange.c(), pointsRange.c(),
519 char full_filename[360];
520 sprintf( full_filename,
"%s%s", filename.c_str(),
"_True_curvature.dat" );
521 std::ofstream file( full_filename );
523 file <<
"# h = " << h << std::endl;
524 file <<
"# True curvature computation" << std::endl;
525 file <<
"# range size = " << pointsRange.size() << std::endl;
528 file <<
"# noise level (init) = " << noiseLevel/h << std::endl;
529 file <<
"# noise level (current) = " << noiseLevel << std::endl;
532 std::ostream_iterator< double > out_it( file,
"\n" );
534 typedef ParametricShapeCurvatureFunctor< Shape > CurvatureFunctor;
535 typedef typename PointsRange::ConstCirculator C;
536 TrueLocalEstimatorOnPoints< C, Shape, CurvatureFunctor >
537 trueCurvatureEstimator;
538 trueCurvatureEstimator.attach( aShape );
539 estimation( trueCurvatureEstimator, h,
540 pointsRange.c(), pointsRange.c(),
548 if (options.at(1) !=
'0')
552 char full_filename[360];
553 sprintf( full_filename,
"%s%s", filename.c_str(),
"_MDSS_tangeant.dat" );
554 std::ofstream file( full_filename );
556 file <<
"# h = " << h << std::endl;
557 file <<
"# Most centered maximal DSS tangent estimation" << std::endl;
558 file <<
"# range size = " << pointsRange.size() << std::endl;
561 file <<
"# noise level (init) = " << noiseLevel/h << std::endl;
562 file <<
"# noise level (current) = " << noiseLevel << std::endl;
565 std::ostream_iterator< RealPoint > out_it( file,
"\n" );
567 typedef typename GridCurve< KSpace >::PointsRange PointsRange2;
568 PointsRange2 pointsRange2 = gridcurve.getPointsRange();
570 typedef typename PointsRange2::ConstCirculator C;
571 typedef ArithmeticalDSSComputer< C, int, 4 > SegmentComputer;
572 typedef TangentFromDSSEstimator<SegmentComputer> SCFunctor;
577 MostCenteredMaximalSegmentEstimator<SegmentComputer,SCFunctor> MDSSTangentEstimator(sc, f);
578 estimation( MDSSTangentEstimator, h,
579 pointsRange2.c(), pointsRange2.c(),
588 char full_filename[360];
589 sprintf( full_filename,
"%s%s", filename.c_str(),
"_MDSSl_curvature.dat" );
590 std::ofstream file( full_filename );
592 file <<
"# h = " << h << std::endl;
593 file <<
"# Most centered maximal DSS (length) curvature estimation" << std::endl;
594 file <<
"# range size = " << pointsRange.size() << std::endl;
597 file <<
"# noise level (init) = " << noiseLevel/h << std::endl;
598 file <<
"# noise level (current) = " << noiseLevel << std::endl;
601 std::ostream_iterator< double > out_it( file,
"\n" );
603 typedef typename GridCurve< KSpace >::PointsRange PointsRange2;
604 PointsRange2 pointsRange2 = gridcurve.getPointsRange();
606 typedef typename PointsRange2::ConstCirculator C;
607 typedef ArithmeticalDSSComputer< C, int, 4 > SegmentComputer;
608 typedef CurvatureFromDSSLengthEstimator<SegmentComputer> SCFunctor;
611 MostCenteredMaximalSegmentEstimator<SegmentComputer,SCFunctor> MDSSCurvatureEstimator(sc, f);
613 estimation( MDSSCurvatureEstimator, h,
614 pointsRange2.c(), pointsRange2.c(),
620 memset(&full_filename[0], 0,
sizeof(full_filename));
621 sprintf( full_filename,
"%s%s", filename.c_str(),
"_MDSSlw_curvature.dat" );
622 file.open( full_filename );
624 file <<
"# h = " << h << std::endl;
625 file <<
"# Most centered maximal DSS (length & width) curvature estimation" << std::endl;
626 file <<
"# range size = " << pointsRange.size() << std::endl;
629 file <<
"# noise level (init) = " << noiseLevel/h << std::endl;
630 file <<
"# noise level (current) = " << noiseLevel << std::endl;
633 std::ostream_iterator< double > out_it2( file,
"\n" );
635 typedef CurvatureFromDSSEstimator<SegmentComputer> SCFunctor2;
638 MostCenteredMaximalSegmentEstimator<SegmentComputer,SCFunctor2> MDSSCurvatureEstimator2(sc2, f2);
639 estimation( MDSSCurvatureEstimator2, h,
640 pointsRange2.c(), pointsRange2.c(),
643 double time = c.stopClock();
644 file <<
"# Time: " << time << std::endl;
652 if (options.at(2) !=
'0')
656 char full_filename[360];
657 sprintf( full_filename,
"%s%s", filename.c_str(),
"_MDCA_tangent.dat" );
658 std::ofstream file( full_filename );
660 file <<
"# h = " << h << std::endl;
661 file <<
"# Most centered maximal DCA tangents estimation" << std::endl;
662 file <<
"# range size = " << pointsRange.size() << std::endl;
665 file <<
"# noise level (init) = " << noiseLevel/h << std::endl;
666 file <<
"# noise level (current) = " << noiseLevel << std::endl;
669 std::ostream_iterator< RealPoint > out_it( file,
"\n" );
671 typedef typename GridCurve<KSpace>::IncidentPointsRange Range;
672 typedef typename Range::ConstCirculator C;
673 Range r = gridcurve.getIncidentPointsRange();
674 typedef StabbingCircleComputer<C> SegmentComputer;
675 typedef TangentFromDCAEstimator<SegmentComputer> SCFunctor;
678 MostCenteredMaximalSegmentEstimator<SegmentComputer,SCFunctor> MDCATangentEstimator(sc, f);
679 estimation( MDCATangentEstimator, h,
690 char full_filename[360];
691 sprintf( full_filename,
"%s%s", filename.c_str(),
"_MDCA_curvature.dat" );
692 std::ofstream file( full_filename );
694 file <<
"# h = " << h << std::endl;
695 file <<
"# Most centered maximal DCA curvature estimation" << std::endl;
696 file <<
"# range size = " << pointsRange.size() << std::endl;
699 file <<
"# noise level (init) = " << noiseLevel/h << std::endl;
700 file <<
"# noise level (current) = " << noiseLevel << std::endl;
703 std::ostream_iterator< double > out_it( file,
"\n" );
705 typedef typename GridCurve<KSpace>::IncidentPointsRange Range;
706 typedef typename Range::ConstCirculator C;
707 Range r = gridcurve.getIncidentPointsRange();
708 typedef StabbingCircleComputer<C> SegmentComputer;
709 typedef CurvatureFromDCAEstimator<SegmentComputer, false> SCFunctor;
712 MostCenteredMaximalSegmentEstimator<SegmentComputer,SCFunctor> MDCACurvatureEstimator(sc, f);
713 estimation( MDCACurvatureEstimator, h,
717 double time = c.stopClock();
718 file <<
"# Time: " << time << std::endl;
725 if (options.at(3) !=
'0')
731 char full_filename[360];
732 sprintf( full_filename,
"%s%s", filename.c_str(),
"_BC_tangeant.dat" );
733 std::ofstream file( full_filename );
735 file <<
"# h = " << h << std::endl;
736 file <<
"# Tangents estimation from binomial convolution" << std::endl;
737 file <<
"# range size = " << pointsRange.size() << std::endl;
740 file <<
"# noise level (init) = " << noiseLevel/h << std::endl;
741 file <<
"# noise level (current) = " << noiseLevel << std::endl;
744 typedef typename PointsRange::ConstIterator I;
745 typedef BinomialConvolver<I, double> MyBinomialConvolver;
746 file <<
"# mask size = " <<
747 MyBinomialConvolver::suggestedSize( h, pointsRange.begin(), pointsRange.end() ) << std::endl;
749 typedef TangentFromBinomialConvolverFunctor< MyBinomialConvolver, RealPoint >
751 BinomialConvolverEstimator< MyBinomialConvolver, TangentBCFct> BCTangentEstimator;
753 std::ostream_iterator< RealPoint > out_it( file,
"\n" );
755 BCTangentEstimator.init( h, pointsRange.begin(), pointsRange.end(),
true );
756 BCTangentEstimator.eval( pointsRange.begin(), pointsRange.end(), out_it );
758 double time = c.stopClock();
759 file <<
"# Time: " << time << std::endl;
768 char full_filename[360];
769 sprintf( full_filename,
"%s%s", filename.c_str(),
"_BC_curvature.dat" );
770 std::ofstream file( full_filename );
772 file <<
"# h = " << h << std::endl;
773 file <<
"# Curvature estimation from binomial convolution" << std::endl;
774 file <<
"# range size = " << pointsRange.size() << std::endl;
777 file <<
"# noise level (init) = " << noiseLevel/h << std::endl;
778 file <<
"# noise level (current) = " << noiseLevel << std::endl;
781 typedef typename PointsRange::ConstIterator I;
782 typedef BinomialConvolver<I, double> MyBinomialConvolver;
783 file <<
"# mask size = " <<
784 MyBinomialConvolver::suggestedSize( h, pointsRange.begin(), pointsRange.end() ) << std::endl;
786 std::ostream_iterator< double > out_it( file,
"\n" );
788 typedef CurvatureFromBinomialConvolverFunctor< MyBinomialConvolver, double >
790 BinomialConvolverEstimator< MyBinomialConvolver, CurvatureBCFct> BCCurvatureEstimator;
792 BCCurvatureEstimator.init( h, pointsRange.begin(), pointsRange.end(),
true );
793 BCCurvatureEstimator.eval( pointsRange.begin(), pointsRange.end(), out_it );
795 double time = c.stopClock();
796 file <<
"# Time: " << time << std::endl;
804 if (options.at(4) !=
'0')
810 char full_filename[360];
811 sprintf( full_filename,
"%s%s", filename.c_str(),
"_II_curvature.dat" );
812 std::ofstream file( full_filename );
814 file <<
"# h = " << h << std::endl;
815 file <<
"# Integral Invariant curvature estimation" << std::endl;
816 file <<
"# range size = " << pointsRange.size() << std::endl;
819 file <<
"# noise level (init) = " << noiseLevel/h << std::endl;
820 file <<
"# noise level (current) = " << noiseLevel << std::endl;
823 if( optionsII.radius <= 0.0 )
825 optionsII.radius = suggestedSizeIntegralInvariant( h, optionsII.center, pointsRange.begin(), pointsRange.end() );
826 file <<
"# Estimated radius: " << optionsII.radius << std::endl;
828 double re = optionsII.radius * std::pow( h, optionsII.alpha );
829 file <<
"# full kernel (digital) size (with alpha = " << optionsII.alpha <<
") = " <<
832 std::ostream_iterator< double > out_it( file,
"\n" );
836 typedef LightImplicitDigitalSurface< KSpace, KanungoPredicate > LightImplicitDigSurface;
837 typedef DigitalSurface< LightImplicitDigSurface > DigSurface;
839 LightImplicitDigSurface LightImplDigSurf( K, *noisifiedObject, SAdj, bel );
840 DigSurface surf( LightImplDigSurf );
842 typedef DepthFirstVisitor< DigSurface > Visitor;
843 typedef GraphVisitorRange< Visitor > VisitorRange;
844 typedef typename VisitorRange::ConstIterator VisitorConstIterator;
846 VisitorRange range(
new Visitor( surf, *surf.begin() ));
847 VisitorConstIterator ibegin = range.begin();
848 VisitorConstIterator iend = range.end();
850 typedef functors::IICurvatureFunctor<Z2i::Space> MyIICurvatureFunctor;
851 typedef IntegralInvariantVolumeEstimator< KSpace, KanungoPredicate, MyIICurvatureFunctor > MyIICurvatureEstimator;
853 MyIICurvatureFunctor curvatureFunctor;
854 curvatureFunctor.init( h, re );
856 MyIICurvatureEstimator curvatureEstimator( curvatureFunctor );
857 curvatureEstimator.attach( K, *noisifiedObject );
858 curvatureEstimator.setParams( re/h );
859 curvatureEstimator.init( h, ibegin, iend );
861 curvatureEstimator.eval( ibegin, iend, out_it );
865 typedef LightImplicitDigitalSurface< KSpace, Digitizer > LightImplicitDigSurface;
866 typedef DigitalSurface< LightImplicitDigSurface > DigSurface;
868 LightImplicitDigSurface LightImplDigSurf( K, *dig, SAdj, bel );
869 DigSurface surf( LightImplDigSurf );
871 typedef DepthFirstVisitor< DigSurface > Visitor;
872 typedef GraphVisitorRange< Visitor > VisitorRange;
873 typedef typename VisitorRange::ConstIterator VisitorConstIterator;
875 VisitorRange range(
new Visitor( surf, *surf.begin() ));
876 VisitorConstIterator ibegin = range.begin();
877 VisitorConstIterator iend = range.end();
879 typedef functors::IICurvatureFunctor<Z2i::Space> MyIICurvatureFunctor;
880 typedef IntegralInvariantVolumeEstimator< KSpace, Digitizer, MyIICurvatureFunctor > MyIICurvatureEstimator;
882 MyIICurvatureFunctor curvatureFunctor;
883 curvatureFunctor.init( h, re );
885 MyIICurvatureEstimator curvatureEstimator( curvatureFunctor );
886 curvatureEstimator.attach( K, *dig );
887 curvatureEstimator.setParams( re/h );
888 curvatureEstimator.init( h, ibegin, iend );
890 curvatureEstimator.eval( ibegin, iend, out_it );
893 double time = c.stopClock();
894 file <<
"# Time: " << time << std::endl;
907 std::cerr <<
"[computeLocalEstimations]"
908 <<
" error: open digital curve found." << std::endl;
912 catch ( InputException e )
914 std::cerr <<
"[computeLocalEstimations]"
915 <<
" error in finding a bel." << std::endl;
925int main(
int argc,
char** argv )
929 std::string shapeName;
930 std::string filename;
931 double radius, kernelradius;
933 double smallradius {5};
934 double varsmallradius {5};
935 double cx {0.0}, cy {0.0};
941 double alpha {1.0/3.0};
942 double noiseLevel {0.0};
943 std::string properties {
"11"};
944 std::string outShape {
""};
946 std::string options {
"1000"};
948 app.description(
"Compares local estimators on implicit shapes using DGtal library.\n Typical use example:\n \t 2dlocalEstimators --output <output> --shape <shapeName> [required parameters] --estimators <binaryWord> --properties <binaryWord>\n");
949 auto listOpt = app.add_flag(
"--list,-l",
"List all available shapes");
950 auto outputOpt = app.add_option(
"--output,-o", filename,
"Output")->required();
951 auto shapeNameOpt = app.add_option(
"--shape,-s", shapeName,
"Shape name")->required();
952 auto radiusOpt = app.add_option(
"--radius,-R", radius,
"Radius of the shape" );
953 auto kernelradiusOpt = app.add_option(
"--kernelradius,-K", radius,
"Radius of the convolution kernel (Integral invariants estimators)");
954 auto alphaOpt = app.add_option(
"--alpha", alpha,
"Alpha parameter for Integral Invariant computation");
955 auto axis1Opt = app.add_option(
"--axis1,-A", axis1,
"Half big axis of the shape (ellipse)" );
956 auto axis2Opt = app.add_option(
"--axis2,-a", axis2,
"Half small axis of the shape (ellipse)" );
957 auto smallradiusOpt = app.add_option(
"--smallradius,-r", smallradius,
"Small radius of the shape");
958 auto varsmallradiusOpt = app.add_option(
"--varsmallradius,-v", varsmallradius,
"Variable small radius of the shape" );
959 auto kOpt = app.add_option(
"-k", k,
"Number of branches or corners the shape (default 3)" );
960 auto phiOpt = app.add_option(
"--phi", phi,
"Phase of the shape (in radian)" );
961 auto widthOpt = app.add_option(
"--width,-w", width,
"Width of the shape" );
962 auto powerOpt = app.add_option(
"--power,-p", power,
"Power of the metric" );
963 app.add_option(
"--center_x,-x", cx,
"x-coordinate of the shape center" );
964 app.add_option(
"--center_y,-y", cy,
"y-coordinate of the shape center" );
965 app.add_option(
"--gridstep,-g", h,
"Gridstep for the digitization" );
966 app.add_option(
"--noise,-n", noiseLevel,
"Level of noise to perturb the shape");
967 app.add_option(
"--properties", properties,
"the i-th property is disabled iff there is a 0 at position i");
968 app.add_option(
"--estimators,-e", options,
"the i-th estimator is disabled iff there is a 0 at position i");
969 app.add_option(
"--exportShape,-E", outShape,
"Exports the contour of the source shape as a sequence of discrete points (.sdp)");
970 app.add_option(
"--lambda", lambda,
"Use the shape to get a better approximation of the surface (optional)");
972 app.get_formatter()->column_width(40);
973 CLI11_PARSE(app, argc, argv);
979 if ( listOpt->count() > 0 )
986 if (options.size() < nb)
988 trace.error() <<
" At least " << nb
989 <<
" characters are required "
990 <<
" with option --estimators.";
991 trace.info() << std::endl;
996 if (properties.size() < nb)
998 trace.error() <<
" At least " << nb
999 <<
" characters are required "
1000 <<
" with option --properties.";
1001 trace.info() << std::endl;
1006 unsigned int id = checkAndReturnIndex(shapeName);
1009 typedef Z2i::Space Space;
1010 typedef Space::RealPoint RealPoint;
1012 RealPoint center( cx, cy );
1014 struct OptionsIntegralInvariant< RealPoint > optII;
1015 optII.radius = kernelradius;
1016 optII.alpha = alpha;
1017 optII.lambda_optimized = lambda;
1018 optII.center = center;
1022 if (radiusOpt->count()==0) missingParam(
"--radius");
1025 Ball2D<Space> ball( center, radius );
1026 computeLocalEstimations<Space>( filename, ball, h, optII, options, properties, outShape, noiseLevel );
1032 ImplicitHyperCube<Space> object(Z2i::Point(0,0), width/2);
1033 trace.error()<<
"Not available.";
1034 trace.info()<<std::endl;
1039 if (radiusOpt->count()==0) missingParam(
"--radius");
1041 ImplicitRoundedHyperCube<Space> ball( Z2i::Point(0,0), radius, power );
1042 trace.error()<<
"Not available.";
1043 trace.info()<<std::endl;
1048 if (radiusOpt->count()==0) missingParam(
"--radius");
1053 Flower2D<Space> flower( center, radius, varsmallradius, k, phi );
1054 computeLocalEstimations<Space>( filename, flower, h, optII, options, properties, outShape, noiseLevel );
1058 if (radiusOpt->count()==0) missingParam(
"--radius");
1063 NGon2D<Space> object( center, radius, k, phi );
1064 computeLocalEstimations<Space>( filename,
object, h, optII, options, properties, outShape, noiseLevel );
1069 if (radiusOpt->count()==0) missingParam(
"--radius");
1074 AccFlower2D<Space> accflower( center, radius, varsmallradius, k, phi );
1075 computeLocalEstimations<Space>( filename, accflower, h, optII, options, properties, outShape, noiseLevel );
1079 if (axis1Opt->count()==0) missingParam(
"--axis1");
1080 if (axis2Opt->count()==0) missingParam(
"--axis2");
1085 Ellipse2D<Space> ellipse( center, axis1, axis2, phi );
1086 computeLocalEstimations<Space>( filename, ellipse, h, optII, options, properties, outShape, noiseLevel );