35#include "DGtal/base/Common.h"
36#include "DGtal/base/Clock.h"
37#include "DGtal/helpers/StdDefs.h"
43#include "DGtal/shapes/implicit/ImplicitBall.h"
44#include "DGtal/math/MPolynomial.h"
45#include "DGtal/io/readers/MPolynomialReader.h"
46#include "DGtal/shapes/implicit/ImplicitPolynomial3Shape.h"
49#include "DGtal/shapes/GaussDigitizer.h"
50#include "DGtal/topology/LightImplicitDigitalSurface.h"
51#include "DGtal/topology/DigitalSurface.h"
52#include "DGtal/graph/DepthFirstVisitor.h"
53#include "DGtal/geometry/volumes/KanungoNoise.h"
54#include "DGtal/topology/CanonicSCellEmbedder.h"
58#include "DGtal/kernel/BasicPointFunctors.h"
59#include "DGtal/geometry/surfaces/FunctorOnCells.h"
60#include "DGtal/geometry/volumes/distance/LpMetric.h"
62#include "DGtal/geometry/curves/estimation/TrueLocalEstimatorOnPoints.h"
63#include "DGtal/geometry/surfaces/estimation/IIGeometricFunctors.h"
64#include "DGtal/geometry/surfaces/estimation/IntegralInvariantVolumeEstimator.h"
65#include "DGtal/geometry/surfaces/estimation/IntegralInvariantCovarianceEstimator.h"
67#include "DGtal/geometry/surfaces/estimation/LocalEstimatorFromSurfelFunctorAdapter.h"
68#include "DGtal/geometry/surfaces/estimation/estimationFunctors/MongeJetFittingMeanCurvatureEstimator.h"
69#include "DGtal/geometry/surfaces/estimation/estimationFunctors/MongeJetFittingGaussianCurvatureEstimator.h"
70#include "DGtal/geometry/surfaces/estimation/estimationFunctors/MongeJetFittingPrincipalCurvaturesEstimator.h"
73using namespace functors;
124typedef std::pair<double,double> PrincipalCurvatures;
125template <
typename Shape,
typename KSpace,
typename ConstIterator,
typename OutputIterator >
127estimateTrueMeanCurvatureQuantity(
const ConstIterator & it_begin,
128 const ConstIterator & it_end,
129 OutputIterator & output,
134 typedef typename KSpace::Space::RealPoint RealPoint;
135 typedef CanonicSCellEmbedder< KSpace > Embedder;
137 Embedder embedder( K );
138 RealPoint currentRealPoint;
140 for ( ConstIterator it = it_begin; it != it_end; ++it )
142 currentRealPoint = embedder( *it_begin ) * h;
143 *output = aShape->meanCurvature( currentRealPoint );
149template <
typename Shape,
typename KSpace,
typename ConstIterator,
typename OutputIterator >
151estimateTrueGaussianCurvatureQuantity(
const ConstIterator & it_begin,
152 const ConstIterator & it_end,
153 OutputIterator & output,
158 typedef typename KSpace::Space::RealPoint RealPoint;
159 typedef CanonicSCellEmbedder< KSpace > Embedder;
161 Embedder embedder( K );
162 RealPoint currentRealPoint;
164 for ( ConstIterator it = it_begin; it != it_end; ++it )
166 currentRealPoint = embedder( *it_begin ) * h;
167 *output = aShape->gaussianCurvature( currentRealPoint );
172template <
typename Shape,
typename KSpace,
typename ConstIterator,
typename OutputIterator >
174estimateTruePrincipalCurvaturesQuantity(
const ConstIterator & it_begin,
175 const ConstIterator & it_end,
176 OutputIterator & output,
181 typedef typename KSpace::Space::RealPoint RealPoint;
182 typedef CanonicSCellEmbedder< KSpace > Embedder;
184 Embedder embedder( K );
185 RealPoint currentRealPoint;
187 for ( ConstIterator it = it_begin; it != it_end; ++it )
189 currentRealPoint = embedder( *it_begin ) * h;
191 aShape->principalCurvatures( currentRealPoint, k1, k2 );
192 PrincipalCurvatures result;
200template <
typename Space,
typename Shape>
202compareShapeEstimators(
const std::string & filename,
203 const Shape * aShape,
204 const typename Space::RealPoint & border_min,
205 const typename Space::RealPoint & border_max,
207 const double & radius_kernel,
208 const double & alpha,
209 const std::string & options,
210 const std::string & properties,
211 const bool & lambda_optimized,
212 double noiseLevel = 0.0 )
214 typedef typename Space::RealPoint RealPoint;
215 typedef GaussDigitizer< Z3i::Space, Shape > DigitalShape;
216 typedef Z3i::KSpace KSpace;
217 typedef typename KSpace::SCell SCell;
218 typedef typename KSpace::Surfel Surfel;
220 bool withNoise = ( noiseLevel <= 0.0 ) ?
false : true;
222 ASSERT (( noiseLevel < 1.0 ));
225 dshape.attach( *aShape );
226 dshape.init( border_min, border_max, h );
229 if ( ! K.init( dshape.getLowerBound(), dshape.getUpperBound(),
true ) )
231 std::cerr <<
"[3dLocalEstimators] error in creating KSpace." << std::endl;
239 typedef KanungoNoise< DigitalShape, Z3i::Domain > KanungoPredicate;
240 typedef LightImplicitDigitalSurface< KSpace, KanungoPredicate > Boundary;
241 typedef DigitalSurface< Boundary > MyDigitalSurface;
242 typedef typename MyDigitalSurface::ConstIterator ConstIterator;
244 typedef DepthFirstVisitor< MyDigitalSurface > Visitor;
245 typedef GraphVisitorRange< Visitor > VisitorRange;
246 typedef typename VisitorRange::ConstIterator VisitorConstIterator;
252 auto d = dshape.getDomain();
253 KanungoPredicate noisifiedObject ( dshape, d, noiseLevel );
254 SCell bel = Surfaces< KSpace >::findABel( K, noisifiedObject, 10000 );
255 Boundary * boundary =
new Boundary( K, noisifiedObject, SurfelAdjacency< KSpace::dimension >(
true ), bel );
256 MyDigitalSurface surf ( *boundary );
258 double minsize = dshape.getUpperBound()[0] - dshape.getLowerBound()[0];
259 unsigned int tries = 0;
260 while( surf.size() < 2 * minsize || tries > 150 )
263 bel = Surfaces< KSpace >::findABel( K, noisifiedObject, 10000 );
264 boundary =
new Boundary( K, noisifiedObject, SurfelAdjacency< KSpace::dimension >(
true ), bel );
265 surf = MyDigitalSurface( *boundary );
271 std::cerr <<
"Can't found a proper bel. So .... I ... just ... kill myself." << std::endl;
275 VisitorRange * range;
276 VisitorConstIterator ibegin;
277 VisitorConstIterator iend;
283 if( options.at( 0 ) !=
'0' )
286 if( properties.at( 0 ) !=
'0' )
288 trace.beginBlock(
"True mean curvature" );
290 char full_filename[360];
291 sprintf( full_filename,
"%s%s", filename.c_str(),
"_True_mean.dat" );
292 std::ofstream file( full_filename );
293 file <<
"# h = " << h << std::endl;
294 file <<
"# True Mean Curvature estimation" << std::endl;
296 std::ostream_iterator< double > out_it_true_mean( file,
"\n" );
298 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
299 ibegin = range->begin();
304 estimateTrueMeanCurvatureQuantity( ibegin,
311 double TTrueMeanCurv = c.stopClock();
312 file <<
"# time = " << TTrueMeanCurv << std::endl;
321 if( properties.at( 1 ) !=
'0' )
323 trace.beginBlock(
"True Gausian curvature" );
325 char full_filename[360];
326 sprintf( full_filename,
"%s%s", filename.c_str(),
"_True_gaussian.dat" );
327 std::ofstream file( full_filename );
328 file <<
"# h = " << h << std::endl;
329 file <<
"# True Gaussian Curvature estimation" << std::endl;
331 std::ostream_iterator< double > out_it_true_gaussian( file,
"\n" );
333 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
334 ibegin = range->begin();
339 estimateTrueGaussianCurvatureQuantity( ibegin,
341 out_it_true_gaussian,
346 double TTrueGaussianCurv = c.stopClock();
347 file <<
"# time = " << TTrueGaussianCurv << std::endl;
356 if( properties.at( 2 ) !=
'0' )
358 trace.beginBlock(
"True principal curvatures" );
360 char full_filename[360];
361 sprintf( full_filename,
"%s%s", filename.c_str(),
"_True_principal.dat" );
362 std::ofstream file( full_filename );
363 file <<
"# h = " << h << std::endl;
364 file <<
"# True Gaussian Curvature estimation" << std::endl;
366 std::ostream_iterator< std::string > out_it_true_pc( file,
"\n" );
368 std::vector<PrincipalCurvatures> v_results;
369 std::back_insert_iterator< std::vector<PrincipalCurvatures> > bkIt(v_results);
370 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
371 ibegin = range->begin();
376 estimateTruePrincipalCurvaturesQuantity( ibegin,
383 for(
unsigned int ii = 0; ii < v_results.size(); ++ii )
385 std::stringstream ss;
386 ss << v_results[ii].first <<
" " << v_results[ii].second;
387 *out_it_true_pc = ss.str();
390 double TTruePrincCurv = c.stopClock();
391 file <<
"# time = " << TTruePrincCurv << std::endl;
401 double re = radius_kernel * std::pow( h, alpha );
404 if( options.at( 1 ) !=
'0' )
407 if( properties.at( 0 ) !=
'0' )
409 trace.beginBlock(
"II mean curvature" );
411 char full_filename[360];
412 sprintf( full_filename,
"%s%s", filename.c_str(),
"_II_mean.dat" );
413 std::ofstream file( full_filename );
414 file <<
"# h = " << h << std::endl;
415 file <<
"# Mean Curvature estimation from the Integral Invariant" << std::endl;
416 file <<
"# computed kernel radius = " << re << std::endl;
418 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
419 ibegin = range->begin();
424 typedef functors::IIMeanCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor;
425 typedef IntegralInvariantVolumeEstimator< KSpace, KanungoPredicate, MyIICurvatureFunctor > MyIICurvatureEstimator;
427 MyIICurvatureFunctor curvatureFunctor;
428 curvatureFunctor.init( h, re );
430 MyIICurvatureEstimator curvatureEstimator( curvatureFunctor );
431 curvatureEstimator.attach( K, noisifiedObject );
432 curvatureEstimator.setParams( re/h );
433 curvatureEstimator.init( h, ibegin, iend );
435 std::ostream_iterator< double > out_it_ii_mean( file,
"\n" );
436 curvatureEstimator.eval( ibegin, iend, out_it_ii_mean );
438 double TIIMeanCurv = c.stopClock();
439 file <<
"# time = " << TIIMeanCurv << std::endl;
448 if( properties.at( 1 ) !=
'0' )
450 trace.beginBlock(
"II Gaussian curvature" );
452 char full_filename[360];
453 sprintf( full_filename,
"%s%s", filename.c_str(),
"_II_gaussian.dat" );
454 std::ofstream file( full_filename );
455 file <<
"# h = " << h << std::endl;
456 file <<
"# Gaussian Curvature estimation from the Integral Invariant" << std::endl;
457 file <<
"# computed kernel radius = " << re << std::endl;
459 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
460 ibegin = range->begin();
465 typedef functors::IIGaussianCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor;
466 typedef IntegralInvariantCovarianceEstimator< KSpace, KanungoPredicate, MyIICurvatureFunctor > MyIICurvatureEstimator;
468 MyIICurvatureFunctor curvatureFunctor;
469 curvatureFunctor.init( h, re );
471 MyIICurvatureEstimator curvatureEstimator( curvatureFunctor );
472 curvatureEstimator.attach( K, noisifiedObject );
473 curvatureEstimator.setParams( re/h );
474 curvatureEstimator.init( h, ibegin, iend );
476 std::ostream_iterator< double > out_it_ii_gaussian( file,
"\n" );
477 curvatureEstimator.eval( ibegin, iend, out_it_ii_gaussian );
479 double TIIGaussCurv = c.stopClock();
480 file <<
"# time = " << TIIGaussCurv << std::endl;
489 if( properties.at( 2 ) !=
'0' )
491 trace.beginBlock(
"II Principal curvatures" );
493 char full_filename[360];
494 sprintf( full_filename,
"%s%s", filename.c_str(),
"_II_principal.dat" );
495 std::ofstream file( full_filename );
496 file <<
"# h = " << h << std::endl;
497 file <<
"# Gaussian Curvature estimation from the Integral Invariant" << std::endl;
498 file <<
"# computed kernel radius = " << re << std::endl;
500 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
501 ibegin = range->begin();
506 typedef functors::IIPrincipalCurvatures3DFunctor<Z3i::Space> MyIICurvatureFunctor;
507 typedef IntegralInvariantCovarianceEstimator< KSpace, KanungoPredicate, MyIICurvatureFunctor > MyIICurvatureEstimator;
509 MyIICurvatureFunctor curvatureFunctor;
510 curvatureFunctor.init( h, re );
512 MyIICurvatureEstimator curvatureEstimator( curvatureFunctor );
513 curvatureEstimator.attach( K, noisifiedObject );
514 curvatureEstimator.setParams( re/h );
515 curvatureEstimator.init( h, ibegin, iend );
517 std::vector<PrincipalCurvatures> v_results;
518 std::back_insert_iterator< std::vector<PrincipalCurvatures> > bkIt(v_results);
520 curvatureEstimator.eval( ibegin, iend, bkIt );
522 std::ostream_iterator< std::string > out_it_ii_principal( file,
"\n" );
523 for(
unsigned int ii = 0; ii < v_results.size(); ++ii )
525 std::stringstream ss;
526 ss << v_results[ii].first <<
" " << v_results[ii].second;
527 *out_it_ii_principal = ss.str();
528 ++out_it_ii_principal;
531 double TIIGaussCurv = c.stopClock();
532 file <<
"# time = " << TIIGaussCurv << std::endl;
542 if( options.at( 2 ) !=
'0' )
545 if( properties.at( 0 ) !=
'0' )
547 trace.beginBlock(
"Monge mean curvature" );
548 typedef LpMetric<Space> L2Metric;
549 typedef functors::MongeJetFittingMeanCurvatureEstimator<Surfel, CanonicSCellEmbedder<KSpace> > FunctorMean;
550 typedef functors::ConstValue< double > ConvFunctor;
551 typedef LocalEstimatorFromSurfelFunctorAdapter<typename MyDigitalSurface::DigitalSurfaceContainer, L2Metric, FunctorMean, ConvFunctor> ReporterH;
552 CanonicSCellEmbedder<KSpace> embedder( K );
553 FunctorMean estimatorH( embedder, h );
554 ConvFunctor convFunc(1.0);
557 reporterH.attach( surf );
558 reporterH.setParams( l2, estimatorH, convFunc, re/h );
561 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
562 ibegin = range->begin();
565 reporterH.init( h , ibegin, iend );
567 char full_filename[360];
568 sprintf( full_filename,
"%s%s", filename.c_str(),
"_MongeJetFitting_mean.dat" );
569 std::ofstream file( full_filename );
570 file <<
"# h = " << h << std::endl;
571 file <<
"# Mean Curvature estimation from CGAL Monge from and Jet Fitting" << std::endl;
572 file <<
"# computed kernel radius = " << re << std::endl;
573 std::ostream_iterator< double > out_it_monge_mean( file,
"\n" );
576 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
577 ibegin = range->begin();
579 reporterH.eval(ibegin, iend, out_it_monge_mean);
580 double TMongeMeanCurv = c.stopClock();
581 file <<
"# time = " << TMongeMeanCurv << std::endl;
590 if( properties.at( 1 ) !=
'0' )
592 trace.beginBlock(
"Monge Gaussian curvature" );
594 typedef functors::MongeJetFittingGaussianCurvatureEstimator<Surfel, CanonicSCellEmbedder<KSpace> > FunctorGaussian;
595 typedef functors::ConstValue< double > ConvFunctor;
596 typedef LpMetric<Space> L2Metric;
597 typedef LocalEstimatorFromSurfelFunctorAdapter<typename MyDigitalSurface::DigitalSurfaceContainer, L2Metric, FunctorGaussian, ConvFunctor> ReporterK;
598 CanonicSCellEmbedder<KSpace> embedder( K );
599 FunctorGaussian estimatorK( embedder, h );
600 ConvFunctor convFunc(1.0);
602 reporterK.attach( surf );
604 reporterK.setParams( l2, estimatorK, convFunc, re/h );
607 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
608 ibegin = range->begin();
611 reporterK.init( h , ibegin, iend );
614 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
615 ibegin = range->begin();
618 char full_filename[360];
619 sprintf( full_filename,
"%s%s", filename.c_str(),
"_MongeJetFitting_gaussian.dat" );
620 std::ofstream file( full_filename );
621 file <<
"# h = " << h << std::endl;
622 file <<
"# Gaussian Curvature estimation from CGAL Monge from and Jet Fitting" << std::endl;
623 file <<
"# computed kernel radius = " << re << std::endl;
624 std::ostream_iterator< double > out_it_monge_gaussian( file,
"\n" );
625 reporterK.eval(ibegin, iend , out_it_monge_gaussian);
626 double TMongeGaussCurv = c.stopClock();
627 file <<
"# time = " << TMongeGaussCurv << std::endl;
636 if( properties.at( 2 ) !=
'0' )
638 trace.beginBlock(
"Monge Principal Curvature" );
639 typedef LpMetric<Space> L2Metric;
640 typedef functors::MongeJetFittingPrincipalCurvaturesEstimator<Surfel, CanonicSCellEmbedder<KSpace> > FunctorPrincCurv;
641 typedef functors::ConstValue< double > ConvFunctor;
642 typedef LocalEstimatorFromSurfelFunctorAdapter<typename MyDigitalSurface::DigitalSurfaceContainer, L2Metric, FunctorPrincCurv, ConvFunctor> ReporterK;
643 CanonicSCellEmbedder<KSpace> embedder( K );
644 FunctorPrincCurv estimatorK( embedder, h );
645 ConvFunctor convFunc(1.0);
648 reporterK.attach( surf );
649 reporterK.setParams( l2, estimatorK, convFunc, re/h );
653 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
654 ibegin = range->begin();
656 reporterK.init( h , ibegin, iend );
658 char full_filename[360];
659 sprintf( full_filename,
"%s%s", filename.c_str(),
"_MongeJetFitting_principal.dat" );
660 std::ofstream file( full_filename );
661 file <<
"# h = " << h << std::endl;
662 file <<
"# Gaussian Curvature estimation from CGAL Monge from and Jet Fitting" << std::endl;
663 file <<
"# computed kernel radius = " << re << std::endl;
664 std::ostream_iterator< std::string > out_it_monge_principal( file,
"\n" );
666 std::vector<PrincipalCurvatures> v_results;
667 std::back_insert_iterator<std::vector<PrincipalCurvatures> > bkIt(v_results);
670 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
671 ibegin = range->begin();
673 reporterK.eval(ibegin, iend , bkIt);
675 for(
unsigned int ii = 0; ii < v_results.size(); ++ii )
677 std::stringstream ss;
678 ss << v_results[ii].first <<
" " << v_results[ii].second;
679 *out_it_monge_principal = ss.str();
680 ++out_it_monge_principal;
683 double TMongeGaussCurv = c.stopClock();
684 file <<
"# time = " << TMongeGaussCurv << std::endl;
695 typedef LightImplicitDigitalSurface< KSpace, DigitalShape > Boundary;
696 typedef DigitalSurface< Boundary > MyDigitalSurface;
697 typedef typename MyDigitalSurface::ConstIterator ConstIterator;
699 typedef DepthFirstVisitor< MyDigitalSurface > Visitor;
700 typedef GraphVisitorRange< Visitor > VisitorRange;
701 typedef typename VisitorRange::ConstIterator VisitorConstIterator;
704 SCell bel = Surfaces<KSpace>::findABel ( K, dshape, 10000 );
705 Boundary boundary( K, dshape, SurfelAdjacency< KSpace::dimension >(
true ), bel );
706 MyDigitalSurface surf ( boundary );
708 VisitorRange * range;
709 VisitorConstIterator ibegin;
710 VisitorConstIterator iend;
712 unsigned int cntIn = 0;
713 for(
typename Z3i::Domain::ConstIterator it = dshape.getDomain().begin(), ite = dshape.getDomain().end(); it != ite; ++it )
715 if( dshape.operator ()(*it))
721 std::cout <<
"boundary:" << surf.size() << std::endl;
722 std::cout <<
"full:" << cntIn << std::endl;
728 if( options.at( 0 ) !=
'0' )
731 if( properties.at( 0 ) !=
'0' )
733 trace.beginBlock(
"True mean curvature" );
735 char full_filename[360];
736 sprintf( full_filename,
"%s%s", filename.c_str(),
"_True_mean.dat" );
737 std::ofstream file( full_filename );
738 file <<
"# h = " << h << std::endl;
739 file <<
"# True Mean Curvature estimation" << std::endl;
741 std::ostream_iterator< double > out_it_true_mean( file,
"\n" );
743 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
744 ibegin = range->begin();
749 estimateTrueMeanCurvatureQuantity( ibegin,
756 double TTrueMeanCurv = c.stopClock();
757 file <<
"# time = " << TTrueMeanCurv << std::endl;
766 if( properties.at( 1 ) !=
'0' )
768 trace.beginBlock(
"True Gaussian curvature" );
770 char full_filename[360];
771 sprintf( full_filename,
"%s%s", filename.c_str(),
"_True_gaussian.dat" );
772 std::ofstream file( full_filename );
773 file <<
"# h = " << h << std::endl;
774 file <<
"# True Gaussian Curvature estimation" << std::endl;
776 std::ostream_iterator< double > out_it_true_gaussian( file,
"\n" );
778 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
779 ibegin = range->begin();
784 estimateTrueGaussianCurvatureQuantity( ibegin,
786 out_it_true_gaussian,
791 double TTrueGaussianCurv = c.stopClock();
792 file <<
"# time = " << TTrueGaussianCurv << std::endl;
802 if( properties.at( 2 ) !=
'0' )
804 trace.beginBlock(
"True principal curvatures" );
806 char full_filename[360];
807 sprintf( full_filename,
"%s%s", filename.c_str(),
"_True_principal.dat" );
808 std::ofstream file( full_filename );
809 file <<
"# h = " << h << std::endl;
810 file <<
"# True Gaussian Curvature estimation" << std::endl;
812 std::ostream_iterator< std::string > out_it_true_pc( file,
"\n" );
814 std::vector<PrincipalCurvatures> v_results;
815 std::back_insert_iterator< std::vector<PrincipalCurvatures> > bkIt(v_results);
817 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
818 ibegin = range->begin();
823 estimateTruePrincipalCurvaturesQuantity( ibegin,
831 for(
unsigned int ii = 0; ii < v_results.size(); ++ii )
833 std::stringstream ss;
834 ss << v_results[ii].first <<
" " << v_results[ii].second;
835 *out_it_true_pc = ss.str();
839 double TTruePrincCurv = c.stopClock();
840 file <<
"# time = " << TTruePrincCurv << std::endl;
850 double re = radius_kernel * std::pow( h, alpha );
853 if( options.at( 1 ) !=
'0' )
856 if( properties.at( 0 ) !=
'0' )
858 trace.beginBlock(
"II mean curvature" );
859 char full_filename[360];
860 sprintf( full_filename,
"%s%s", filename.c_str(),
"_II_mean.dat" );
861 std::ofstream file( full_filename );
862 file <<
"# h = " << h << std::endl;
863 file <<
"# Mean Curvature estimation from the Integral Invariant" << std::endl;
864 file <<
"# computed kernel radius = " << re << std::endl;
866 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
867 ibegin = range->begin();
872 typedef functors::IIMeanCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor;
873 typedef IntegralInvariantVolumeEstimator< KSpace, DigitalShape, MyIICurvatureFunctor > MyIICurvatureEstimator;
875 MyIICurvatureFunctor curvatureFunctor;
876 curvatureFunctor.init( h, re );
878 MyIICurvatureEstimator curvatureEstimator( curvatureFunctor );
879 curvatureEstimator.attach( K, dshape );
880 curvatureEstimator.setParams( re/h );
881 curvatureEstimator.init( h, ibegin, iend );
883 std::ostream_iterator< double > out_it_ii_mean( file,
"\n" );
884 curvatureEstimator.eval( ibegin, iend, out_it_ii_mean );
886 double TIIMeanCurv = c.stopClock();
887 file <<
"# time = " << TIIMeanCurv << std::endl;
896 if( properties.at( 1 ) !=
'0' )
898 trace.beginBlock(
"II Gaussian curvature" );
900 char full_filename[360];
901 sprintf( full_filename,
"%s%s", filename.c_str(),
"_II_gaussian.dat" );
902 std::ofstream file( full_filename );
903 file <<
"# h = " << h << std::endl;
904 file <<
"# Gaussian Curvature estimation from the Integral Invariant" << std::endl;
905 file <<
"# computed kernel radius = " << re << std::endl;
907 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
908 ibegin = range->begin();
913 typedef functors::IIGaussianCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor;
914 typedef IntegralInvariantCovarianceEstimator< KSpace, DigitalShape, MyIICurvatureFunctor > MyIICurvatureEstimator;
916 MyIICurvatureFunctor curvatureFunctor;
917 curvatureFunctor.init( h, re );
919 MyIICurvatureEstimator curvatureEstimator( curvatureFunctor );
920 curvatureEstimator.attach( K, dshape );
921 curvatureEstimator.setParams( re/h );
922 curvatureEstimator.init( h, ibegin, iend );
924 std::ostream_iterator< double > out_it_ii_gaussian( file,
"\n" );
925 curvatureEstimator.eval( ibegin, iend, out_it_ii_gaussian );
927 double TIIGaussCurv = c.stopClock();
928 file <<
"# time = " << TIIGaussCurv << std::endl;
937 if( properties.at( 2 ) !=
'0' )
939 trace.beginBlock(
"II Principal curvatures" );
941 char full_filename[360];
942 sprintf( full_filename,
"%s%s", filename.c_str(),
"_II_principal.dat" );
943 std::ofstream file( full_filename );
944 file <<
"# h = " << h << std::endl;
945 file <<
"# Gaussian Curvature estimation from the Integral Invariant" << std::endl;
946 file <<
"# computed kernel radius = " << re << std::endl;
948 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
949 ibegin = range->begin();
954 typedef functors::IIPrincipalCurvatures3DFunctor<Z3i::Space> MyIICurvatureFunctor;
955 typedef IntegralInvariantCovarianceEstimator< KSpace, DigitalShape, MyIICurvatureFunctor > MyIICurvatureEstimator;
957 MyIICurvatureFunctor curvatureFunctor;
958 curvatureFunctor.init( h, re );
960 MyIICurvatureEstimator curvatureEstimator( curvatureFunctor );
961 curvatureEstimator.attach( K, dshape );
962 curvatureEstimator.setParams( re/h );
963 curvatureEstimator.init( h, ibegin, iend );
965 std::vector<PrincipalCurvatures> v_results;
966 std::back_insert_iterator< std::vector<PrincipalCurvatures> > bkIt(v_results);
968 curvatureEstimator.eval( ibegin, iend, bkIt );
970 std::ostream_iterator< std::string > out_it_ii_principal( file,
"\n" );
971 for(
unsigned int ii = 0; ii < v_results.size(); ++ii )
973 std::stringstream ss;
974 ss << v_results[ii].first <<
" " << v_results[ii].second;
975 *out_it_ii_principal = ss.str();
976 ++out_it_ii_principal;
979 double TIIGaussCurv = c.stopClock();
980 file <<
"# time = " << TIIGaussCurv << std::endl;
990 if( options.at( 2 ) !=
'0' )
993 if( properties.at( 0 ) !=
'0' )
995 trace.beginBlock(
"Monge mean curvature" );
996 typedef LpMetric<Space> L2Metric;
997 typedef functors::MongeJetFittingMeanCurvatureEstimator<Surfel, CanonicSCellEmbedder<KSpace> > FunctorMean;
998 typedef functors::ConstValue< double > ConvFunctor;
999 typedef LocalEstimatorFromSurfelFunctorAdapter<typename MyDigitalSurface::DigitalSurfaceContainer, L2Metric, FunctorMean, ConvFunctor> ReporterH;
1000 CanonicSCellEmbedder<KSpace> embedder( K );
1001 FunctorMean estimatorH( embedder, h );
1002 ConvFunctor convFunc(1.0);
1004 ReporterH reporterH;
1005 reporterH.attach( surf );
1006 reporterH.setParams( l2, estimatorH, convFunc, re/h );
1009 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
1010 ibegin = range->begin();
1011 iend = range->end();
1012 reporterH.init( h , ibegin, iend );
1014 char full_filename[360];
1015 sprintf( full_filename,
"%s%s", filename.c_str(),
"_MongeJetFitting_mean.dat" );
1016 std::ofstream file( full_filename );
1017 file <<
"# h = " << h << std::endl;
1018 file <<
"# Mean Curvature estimation from CGAL Monge from and Jet Fitting" << std::endl;
1019 file <<
"# computed kernel radius = " << re << std::endl;
1020 std::ostream_iterator< double > out_it_monge_mean( file,
"\n" );
1023 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
1024 ibegin = range->begin();
1025 iend = range->end();
1027 reporterH.eval(ibegin, iend , out_it_monge_mean);
1028 double TMongeMeanCurv = c.stopClock();
1029 file <<
"# time = " << TMongeMeanCurv << std::endl;
1038 if( properties.at( 1 ) !=
'0' )
1040 trace.beginBlock(
"Monge Gaussian curvature" );
1041 typedef LpMetric<Space> L2Metric;
1042 typedef functors::MongeJetFittingGaussianCurvatureEstimator<Surfel, CanonicSCellEmbedder<KSpace> > FunctorGaussian;
1043 typedef functors::ConstValue< double > ConvFunctor;
1044 typedef LocalEstimatorFromSurfelFunctorAdapter<typename MyDigitalSurface::DigitalSurfaceContainer, L2Metric, FunctorGaussian, ConvFunctor> ReporterK;
1045 CanonicSCellEmbedder<KSpace> embedder( K );
1046 FunctorGaussian estimatorK( embedder, h );
1047 ConvFunctor convFunc(1.0);
1048 ReporterK reporterK;
1049 reporterK.attach( surf );
1051 reporterK.setParams( l2, estimatorK, convFunc, re/h );
1055 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
1056 ibegin = range->begin();
1057 iend = range->end();
1058 reporterK.init( h , ibegin, iend );
1061 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
1062 ibegin = range->begin();
1063 iend = range->end();
1065 char full_filename[360];
1066 sprintf( full_filename,
"%s%s", filename.c_str(),
"_MongeJetFitting_gaussian.dat" );
1067 std::ofstream file( full_filename );
1068 file <<
"# h = " << h << std::endl;
1069 file <<
"# Gaussian Curvature estimation from CGAL Monge from and Jet Fitting" << std::endl;
1070 file <<
"# computed kernel radius = " << re << std::endl;
1071 std::ostream_iterator< double > out_it_monge_gaussian( file,
"\n" );
1072 reporterK.eval(ibegin, iend , out_it_monge_gaussian);
1073 double TMongeGaussCurv = c.stopClock();
1074 file <<
"# time = " << TMongeGaussCurv << std::endl;
1083 if( properties.at( 2 ) !=
'0' )
1085 trace.beginBlock(
"Monge Principal Curvature" );
1086 typedef LpMetric<Space> L2Metric;
1088 typedef functors::MongeJetFittingPrincipalCurvaturesEstimator<Surfel, CanonicSCellEmbedder<KSpace> > FunctorPrincCurv;
1089 typedef functors::ConstValue< double > ConvFunctor;
1090 typedef LocalEstimatorFromSurfelFunctorAdapter<typename MyDigitalSurface::DigitalSurfaceContainer, L2Metric, FunctorPrincCurv, ConvFunctor> ReporterK;
1091 CanonicSCellEmbedder<KSpace> embedder( K );
1092 FunctorPrincCurv estimatorK( embedder, h );
1093 ConvFunctor convFunc(1.0);
1094 ReporterK reporterK;
1095 reporterK.attach(surf);
1097 reporterK.setParams(l2, estimatorK, convFunc, re/h);
1099 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
1100 ibegin = range->begin();
1101 iend = range->end();
1102 reporterK.init( h , ibegin, iend );
1105 range =
new VisitorRange(
new Visitor( surf, *surf.begin() ));
1106 ibegin = range->begin();
1107 iend = range->end();
1109 char full_filename[360];
1110 sprintf( full_filename,
"%s%s", filename.c_str(),
"_MongeJetFitting_principal.dat" );
1111 std::ofstream file( full_filename );
1112 file <<
"# h = " << h << std::endl;
1113 file <<
"# Gaussian Curvature estimation from CGAL Monge from and Jet Fitting" << std::endl;
1114 file <<
"# computed kernel radius = " << re << std::endl;
1115 std::ostream_iterator< std::string > out_it_monge_principal( file,
"\n" );
1117 std::vector<PrincipalCurvatures> v_results;
1118 std::back_insert_iterator<std::vector<PrincipalCurvatures> > bkIt(v_results);
1119 reporterK.eval(ibegin, iend , bkIt);
1121 for(
unsigned int ii = 0; ii < v_results.size(); ++ii )
1123 std::stringstream ss;
1124 ss << v_results[ii].first <<
" " << v_results[ii].second;
1125 *out_it_monge_principal = ss.str();
1126 ++out_it_monge_principal;
1129 double TMongeGaussCurv = c.stopClock();
1130 file <<
"# time = " << TMongeGaussCurv << std::endl;
1141 catch ( InputException e )
1143 std::cerr <<
"[estimatorCurvatureComparator3D]"
1148 << border_min[0] <<
" "
1149 << border_max[0] <<
" "
1151 << radius_kernel <<
" "
1152 << lambda_optimized <<
" "
1166void missingParam( std::string param )
1168 trace.error() <<
" Parameter: " << param <<
" is required.";
1169 trace.info() << std::endl;
1174int main(
int argc,
char** argv )
1176#ifndef DGTAL_WITH_CGAL
1177#error You need to have activated CGAL (DGTAL_WITH_CGAL) to include this file.
1179#ifndef DGTAL_WITH_EIGEN
1180#error You need to have activated EIGEN (DGTAL_WITH_EIGEN) to include this file.
1187 app.description(
"Compare local estimators on implicit shapes using DGtal library\n Basic usage:\n \t3dlocalEstimators --shape <shape> --h <h> --radius <radius> --estimators <binaryWord> --output <output> \n \n Below are the different available families of estimators: \n \t - Integral Invariant Mean \n \t - Integral Invariant Gaussian\n \t - Monge Jet Fitting Mean\n\t - Monge Jet Fitting Gaussian\n The i-th family of estimators is enabled if the i-th character of the binary word is not 0. The default binary word is '1100'. This means that the first family of estimators, ie. Integral Invariant, is enabled, whereas the next ones are disabled. Below are the different available properties:\n \t - Mean Curvature\n \t - Gaussian Curvature\n \t - k1/k2 \n \n Example: \n ./estimators/3dlocalEstimators --shape \"z^2-x^2-y^2\" --output result --h 0.4 --radius 1.0" );
1190 std::string poly_str;
1191 std::string file_export {
"result.dat"};
1192 std::string properties {
"110"};
1193 std::string options {
"110"};
1197 double alpha {1.0/3.0};
1198 double border_minV {-10.0};
1199 double border_maxV {10.0};
1200 double noiseLevel {0.0};
1201 bool lambda_optimized {
false};
1203 app.add_option(
"--shape,-s", poly_str,
"Shape") ->required();
1204 app.add_option(
"--output,-o", file_export,
"Output file") ->required();
1206 app.add_option(
"--radius,-r", radius,
"Kernel radius for IntegralInvariant") ->required();
1207 app.add_option(
"--alpha",alpha,
"Alpha parameter for Integral Invariant computation" );
1208 app.add_option(
"--h", h,
"Grid step") ->required();
1209 app.add_option(
"--minAABB,-a", border_minV,
"Min value of the AABB bounding box (domain)");
1210 app.add_option(
"--maxAABB,-A", border_maxV,
"Max value of the AABB bounding box (domain)");
1211 app.add_option(
"--noise,-n", noiseLevel,
"Level of noise to perturb the shape" );
1213 app.add_flag(
"--lambda,-l", lambda_optimized,
"Use the shape to get a better approximation of the surface (optional)");
1214 app.add_option(
"--properties", properties,
"the i-th property is disabled iff there is a 0 at position i");
1215 app.add_option(
"--estimators,-e", options,
"the i-th estimator is disabled iff there is a 0 at position i");
1217 app.get_formatter()->column_width(40);
1218 CLI11_PARSE(app, argc, argv);
1224 if (properties.size() < nb)
1226 trace.error() <<
" At least " << nb
1227 <<
" characters are required "
1228 <<
" with option --properties.";
1229 trace.info() << std::endl;
1233 typedef Z3i::Space::RealPoint RealPoint;
1234 typedef Z3i::Space::RealPoint::Coordinate Ring;
1236 RealPoint border_min( border_minV, border_minV, border_minV );
1237 RealPoint border_max( border_maxV, border_maxV, border_maxV );
1241 typedef MPolynomial< 3, Ring > Polynomial3;
1242 typedef MPolynomialReader<3, Ring> Polynomial3Reader;
1243 typedef ImplicitPolynomial3Shape<Z3i::Space> ImplicitShape;
1246 Polynomial3Reader reader;
1247 std::string::const_iterator iter = reader.read( poly, poly_str.begin(), poly_str.end() );
1248 if ( iter != poly_str.end() )
1250 std::cerr <<
"ERROR: I read only <"
1251 << poly_str.substr( 0, iter - poly_str.begin() )
1252 <<
">, and I built P=" << poly << std::endl;
1256 ImplicitShape* shape =
new ImplicitShape( poly );
1258 compareShapeEstimators< Z3i::Space, ImplicitShape > (
1261 border_min, border_max,