bool compareShapeEstimators( const string & name, Shape & aShape, double h ) { // Types typedef typename Space::Point Point; typedef typename Space::Vector Vector; typedef typename Space::RealPoint RealPoint; typedef typename Space::Integer Integer; typedef HyperRectDomain<Space> Domain; typedef KhalimskySpaceND<Space::dimension,Integer> KSpace; typedef typename KSpace::SCell SCell; typedef typename GridCurve<KSpace>::PointsRange PointsRange; typedef typename GridCurve<KSpace>::ArrowsRange ArrowsRange; typedef typename PointsRange::ConstIterator ConstIteratorOnPoints; // Digitizer GaussDigitizer<Space,Shape> dig; dig.attach( aShape ); // attaches the shape. Vector vlow(-1,-1); Vector vup(1,1); dig.init( aShape.getLowerBound()+vlow, aShape.getUpperBound()+vup, h ); Domain domain = dig.getDomain(); // Create cellular space KSpace K; bool ok = K.init( dig.getLowerBound(), dig.getUpperBound(), true ); if ( ! ok ) { std::cerr << "[compareShapeEstimators]" << " error in creating KSpace." << std::endl; return false; } try { // Extracts shape boundary SurfelAdjacency<KSpace::dimension> SAdj( true ); SCell bel = Surfaces<KSpace>::findABel( K, dig, 10000 ); // Getting the consecutive surfels of the 2D boundary std::vector<Point> points; Surfaces<KSpace>::track2DBoundaryPoints( points, K, SAdj, dig, bel ); // Create GridCurve GridCurve<KSpace> gridcurve; gridcurve.initFromVector( points ); // Ranges PointsRange r = gridcurve.getPointsRange(); std::cout << "# range size = " << r.size() << std::endl; // Estimations // True values std::cout << "# True values computation" << std::endl; typedef ParametricShapeTangentFunctor< Shape > TangentFunctor; typedef ParametricShapeCurvatureFunctor< Shape > CurvatureFunctor; TrueLocalEstimatorOnPoints< ConstIteratorOnPoints, Shape, TangentFunctor > trueTangentEstimator; TrueLocalEstimatorOnPoints< ConstIteratorOnPoints, Shape, CurvatureFunctor > trueCurvatureEstimator; trueTangentEstimator.init( h, r.begin(), r.end(), &aShape, gridcurve.isClosed()); std::vector<RealPoint> trueTangents = estimateQuantity( trueTangentEstimator, r.begin(), r.end() ); trueCurvatureEstimator.init( h, r.begin(), r.end(), &aShape, gridcurve.isClosed()); std::vector<double> trueCurvatures = estimateQuantity( trueCurvatureEstimator, r.begin(), r.end() ); // Maximal Segments std::cout << "# Maximal DSS tangent estimation" << std::endl; typedef ArithmeticalDSS<ConstIteratorOnPoints,Integer,4> SegmentComputer; typedef TangentFromDSSFunctor<SegmentComputer> SCFunctor; SegmentComputer sc; SCFunctor f; MostCenteredMaximalSegmentEstimator<SegmentComputer,SCFunctor> MSTangentEstimator(sc, f); Clock c; c.startClock(); MSTangentEstimator.init( h, r.begin(), r.end(), gridcurve.isClosed() ); std::vector<typename SCFunctor::Value> MSTangents = estimateQuantity( MSTangentEstimator, r.begin(), r.end() ); double TMST = c.stopClock(); // Binomial std::cout << "# Tangent and curvature estimation from binomial convolution" << std::endl; typedef BinomialConvolver<ConstIteratorOnPoints, double> MyBinomialConvolver; std::cout << "# mask size = " << MyBinomialConvolver::suggestedSize( h, r.begin(), r.end() ) << std::endl; typedef TangentFromBinomialConvolverFunctor< MyBinomialConvolver, RealPoint > TangentBCFct; typedef CurvatureFromBinomialConvolverFunctor< MyBinomialConvolver, double > CurvatureBCFct; BinomialConvolverEstimator< MyBinomialConvolver, TangentBCFct> BCTangentEstimator; BinomialConvolverEstimator< MyBinomialConvolver, CurvatureBCFct> BCCurvatureEstimator; c.startClock(); BCTangentEstimator.init( h, r.begin(), r.end(), gridcurve.isClosed() ); std::vector<RealPoint> BCTangents = estimateQuantity( BCTangentEstimator, r.begin(), r.end() ); double TBCTan = c.stopClock(); c.startClock(); BCCurvatureEstimator.init( h, r.begin(), r.end(), gridcurve.isClosed() ); std::vector<double> BCCurvatures = estimateQuantity( BCCurvatureEstimator, r.begin(), r.end() ); double TBCCurv = c.stopClock(); // Output std::cout << "# Shape = "<< name <<std::endl << "# Time-BCtangent = "<<TBCTan <<std::endl << "# Time-BCcurvature = "<<TBCCurv<<std::endl << "# Time-MStangent = "<<TMST<<std::endl << "# id x y tangentx tangenty curvature" << " BCtangentx BCtangenty BCcurvature" << " MStangentx MStangenty" << std::endl; unsigned int i = 0; for ( ConstIteratorOnPoints it = r.begin(), it_end = r.end(); it != it_end; ++it, ++i ) { Point p = *it; std::cout << i << setprecision( 15 ) << " " << p[ 0 ] << " " << p[ 1 ] << " " << trueTangents[ i ][ 0 ] << " " << trueTangents[ i ][ 1 ] << " " << trueCurvatures[ i ] << " " << BCTangents[ i ][ 0 ] << " " << BCTangents[ i ][ 1 ] << " " << BCCurvatures[ i ] << " " << MSTangents[ i ][ 0 ] << " " << MSTangents[ i ][ 1 ] << std::endl; } return true; } catch ( InputException e ) { std::cerr << "[compareShapeEstimators]" << " error in finding a bel." << std::endl; return false; } }
bool lengthEstimators( const std::string & /*name*/, Shape & aShape, double h ) { // Types typedef typename Space::Point Point; typedef typename Space::Vector Vector; typedef typename Space::RealPoint RealPoint; typedef typename Space::Integer Integer; typedef HyperRectDomain<Space> Domain; typedef KhalimskySpaceND<Space::dimension,Integer> KSpace; typedef typename KSpace::SCell SCell; typedef typename GridCurve<KSpace>::PointsRange PointsRange; typedef typename GridCurve<KSpace>::ArrowsRange ArrowsRange; // Digitizer GaussDigitizer<Space,Shape> dig; dig.attach( aShape ); // attaches the shape. Vector vlow(-1,-1); Vector vup(1,1); dig.init( aShape.getLowerBound()+vlow, aShape.getUpperBound()+vup, h ); Domain domain = dig.getDomain(); // Create cellular space KSpace K; bool ok = K.init( dig.getLowerBound(), dig.getUpperBound(), true ); if ( ! ok ) { std::cerr << "[lengthEstimators]" << " error in creating KSpace." << std::endl; return false; } try { // Extracts shape boundary SurfelAdjacency<KSpace::dimension> SAdj( true ); SCell bel = Surfaces<KSpace>::findABel( K, dig, 10000 ); // Getting the consecutive surfels of the 2D boundary std::vector<Point> points; Surfaces<KSpace>::track2DBoundaryPoints( points, K, SAdj, dig, bel ); // Create GridCurve GridCurve<KSpace> gridcurve; gridcurve.initFromVector( points ); // Ranges ArrowsRange ra = gridcurve.getArrowsRange(); PointsRange rp = gridcurve.getPointsRange(); // Estimations typedef typename PointsRange::ConstIterator ConstIteratorOnPoints; typedef ParametricShapeArcLengthFunctor< Shape > Length; TrueGlobalEstimatorOnPoints< ConstIteratorOnPoints, Shape, Length > trueLengthEstimator; trueLengthEstimator.init( h, rp.begin(), rp.end(), &aShape, gridcurve.isClosed()); L1LengthEstimator< typename ArrowsRange::ConstCirculator > l1length; DSSLengthEstimator< typename PointsRange::ConstCirculator > DSSlength; MLPLengthEstimator< typename PointsRange::ConstIterator > MLPlength; FPLengthEstimator< typename PointsRange::ConstIterator > FPlength; BLUELocalLengthEstimator< typename ArrowsRange::ConstIterator > BLUElength; RosenProffittLocalLengthEstimator< typename ArrowsRange::ConstIterator > RosenProffittlength; // Output double trueValue = trueLengthEstimator.eval(); double l1, blue, rosen,dss,mlp,fp; double Tl1, Tblue, Trosen,Tdss,Tmlp,Tfp; Clock c; //Length evaluation & timing c.startClock(); l1length.init(h, ra.c(), ra.c()); l1 = l1length.eval(); Tl1 = c.stopClock(); c.startClock(); BLUElength.init(h, ra.begin(), ra.end(), gridcurve.isClosed()); blue = BLUElength.eval(); Tblue = c.stopClock(); c.startClock(); RosenProffittlength.init(h, ra.begin(), ra.end(), gridcurve.isClosed()); rosen = RosenProffittlength.eval(); Trosen = c.stopClock(); c.startClock(); DSSlength.init(h, rp.c(), rp.c()); dss = DSSlength.eval(); Tdss = c.stopClock(); c.startClock(); MLPlength.init(h, rp.begin(), rp.end(), gridcurve.isClosed()); mlp = MLPlength.eval(); Tmlp = c.stopClock(); c.startClock(); FPlength.init(h, rp.begin(), rp.end(), gridcurve.isClosed()); fp = FPlength.eval(); Tfp = c.stopClock(); std::cout << std::setprecision( 15 ) << h << " " << rp.size() << " " << trueValue << " " << l1 << " " << blue << " " << rosen << " " << dss << " " << mlp << " " << fp << " " << Tl1 << " " << Tblue << " " << Trosen << " " << Tdss << " " << Tmlp << " " << Tfp << std::endl; return true; } catch ( InputException e ) { std::cerr << "[lengthEstimators]" << " error in finding a bel." << std::endl; return false; } }
GridCurve<TKSpace> ballGenerator(double aCx, double aCy, double aR, bool aFlagIsCW) { // Types typedef TKSpace KSpace; typedef typename KSpace::SCell SCell; typedef GridCurve<KSpace> GridCurve; typedef typename KSpace::Space Space; typedef Ball2D<Space> Shape; typedef typename Space::Point Point; typedef typename Space::RealPoint RealPoint; typedef HyperRectDomain<Space> Domain; //Forme Shape aShape(Point(aCx,aCy), aR); // Window for the estimation RealPoint xLow ( -aR-1, -aR-1 ); RealPoint xUp( aR+1, aR+1 ); GaussDigitizer<Space,Shape> dig; dig.attach( aShape ); // attaches the shape. dig.init( xLow, xUp, 1 ); Domain domain = dig.getDomain(); // Create cellular space KSpace K; bool ok = K.init( dig.getLowerBound(), dig.getUpperBound(), true ); if ( ! ok ) { std::cerr << " " << " error in creating KSpace." << std::endl; return GridCurve(); } try { // Extracts shape boundary SurfelAdjacency<KSpace::dimension> SAdj( true ); SCell bel = Surfaces<KSpace>::findABel( K, dig, 10000 ); // Getting the consecutive surfels of the 2D boundary std::vector<Point> points, points2; Surfaces<KSpace>::track2DBoundaryPoints( points, K, SAdj, dig, bel ); //counter-clockwise oriented by default GridCurve c; if (aFlagIsCW) { points2.assign( points.rbegin(), points.rend() ); c.initFromVector(points2); } else { c.initFromVector(points); } return c; } catch ( InputException& e ) { std::cerr << " " << " error in finding a bel." << std::endl; return GridCurve(); } }
bool testCompareEstimator(const std::string &name, Shape & aShape, double h) { using namespace Z2i; trace.beginBlock ( ( "Testing CompareEstimator on digitization of " + name ). c_str() ); // Creates a digitizer on the window (xLow, xUp). typedef Space::RealPoint RealPoint; RealPoint xLow( -10.0, -10.0 ); RealPoint xUp( 10.0, 10.0 ); GaussDigitizer<Space,Shape> dig; dig.attach( aShape ); // attaches the shape. dig.init( xLow, xUp, h ); // The domain size is given by the digitizer according to the window // and the step. Domain domain = dig.getDomain(); // Create cellular space KSpace K; bool ok = K.init( dig.getLowerBound(), dig.getUpperBound(), true ); if ( ! ok ) { std::cerr << "[testCompareEstimators]" << " error in creating KSpace." << std::endl; } else try { // Extracts shape boundary SurfelAdjacency<KSpace::dimension> SAdj( true ); SCell bel = Surfaces<KSpace>::findABel( K, dig, 10000 ); // Getting the consecutive surfels of the 2D boundary std::vector<Point> points; Surfaces<KSpace>::track2DBoundaryPoints( points, K, SAdj, dig, bel ); // Create GridCurve GridCurve<KSpace> gridcurve; gridcurve.initFromVector( points ); typedef GridCurve<KhalimskySpaceND<2> >::PointsRange Range; typedef Range::ConstIterator ConstIteratorOnPoints; Range r = gridcurve.getPointsRange();//building range unsigned int nb = 0; unsigned int nbok = 0; //curvature typedef ParametricShapeCurvatureFunctor< Shape > Curvature; typedef TrueLocalEstimatorOnPoints< ConstIteratorOnPoints, Shape, Curvature > TrueCurvature; TrueCurvature curvatureEstimator; TrueCurvature curvatureEstimatorBis; curvatureEstimator.init( h, r.begin(), r.end() ); curvatureEstimator.attach( &aShape ); curvatureEstimatorBis.init( h, r.begin(), r.end() ); curvatureEstimatorBis.attach( &aShape ); typedef CompareLocalEstimators< TrueCurvature, TrueCurvature> Comparator; trace.info()<< "True curvature comparison at "<< *r.begin() << " = " << Comparator::compare(curvatureEstimator,curvatureEstimatorBis, r.begin()) << std::endl; typename Comparator::OutputStatistic error =Comparator::compare(curvatureEstimator, curvatureEstimatorBis, r.begin(), r.end()); trace.info() << "Nb samples= "<< error.samples()<<std::endl; trace.info() << "Error mean= "<< error.mean()<<std::endl; trace.info() << "Error max= "<< error.max()<<std::endl; nbok += ( (error.samples() == r.size())&&(error.max() == 0) )?1:0; nb++; trace.info() << nbok << "/" << nb << std::endl; //tangents typedef ParametricShapeTangentFunctor< Shape > Tangent; typedef TrueLocalEstimatorOnPoints< ConstIteratorOnPoints, Shape, Tangent > TrueTangent; typedef ArithmeticalDSS<ConstIteratorOnPoints,KSpace::Integer,4> SegmentComputer; typedef TangentFromDSSEstimator<SegmentComputer> Functor; typedef MostCenteredMaximalSegmentEstimator<SegmentComputer,Functor> MSTangentEstimator; SegmentComputer sc; Functor f; TrueTangent tang1; MSTangentEstimator tang2(sc, f); tang1.init( h, r.begin(), r.end() ); tang1.attach( &aShape ); tang2.init( h, r.begin(), r.end() ); typedef CompareLocalEstimators< TrueTangent, MSTangentEstimator> ComparatorTan; trace.info()<< "Tangent comparison at "<< *r.begin() << " = " << ComparatorTan::compareVectors( tang1, tang2, r.begin()) << std::endl; typename ComparatorTan::OutputVectorStatistic error2 =ComparatorTan::compareVectors(tang1, tang2, r.begin(), r.end()); trace.info()<< "Nb samples= "<< error2.samples()<<std::endl; trace.info()<< "Error mean= "<< error2.mean()<<std::endl; trace.info()<< "Error max= "<< error2.max()<<std::endl; nbok += (error.samples() == r.size())?1:0; nb++; trace.info() << nbok << "/" << nb << std::endl; ok += (nb == nbok); } catch ( InputException e ) { std::cerr << "[testCompareEstimator]" << " error in finding a bel." << std::endl; ok = false; } trace.emphase() << ( ok ? "Passed." : "Error." ) << endl; trace.endBlock(); return ok; }
bool generateContour( Shape & aShape, double h, const std::string & outputFormat, bool withGeom, const std::string & outputFileName ) { // Types typedef typename Space::Point Point; typedef typename Space::Vector Vector; typedef typename Space::RealPoint RealPoint; typedef typename Space::Integer Integer; typedef HyperRectDomain<Space> Domain; typedef KhalimskySpaceND<Space::dimension,Integer> KSpace; typedef typename KSpace::SCell SCell; typedef typename GridCurve<KSpace>::PointsRange Range; typedef typename Range::ConstIterator ConstIteratorOnPoints; typedef typename GridCurve<KSpace>::MidPointsRange MidPointsRange; // Digitizer GaussDigitizer<Space,Shape> dig; dig.attach( aShape ); // attaches the shape. Vector vlow(-1,-1); Vector vup(1,1); dig.init( aShape.getLowerBound()+vlow, aShape.getUpperBound()+vup, h ); Domain domain = dig.getDomain(); // Create cellular space KSpace K; bool ok = K.init( dig.getLowerBound(), dig.getUpperBound(), true ); if ( ! ok ) { std::cerr << "[generateContour]" << " error in creating KSpace." << std::endl; return false; } try { // Extracts shape boundary SurfelAdjacency<KSpace::dimension> SAdj( true ); SCell bel = Surfaces<KSpace>::findABel( K, dig, 10000 ); // Getting the consecutive surfels of the 2D boundary std::vector<Point> points; Surfaces<KSpace>::track2DBoundaryPoints( points, K, SAdj, dig, bel ); // Create GridCurve GridCurve<KSpace> gridcurve; gridcurve.initFromVector( points ); // gridcurve contains the digital boundary to analyze. Range r = gridcurve.getPointsRange(); //building range if ( outputFormat == "pts" ) { for ( ConstIteratorOnPoints it = r.begin(), it_end = r.end(); it != it_end; ++it ) { Point p = *it; std::cout << p[ 0 ] << " " << p[ 1 ] << std::endl; } } else if ( outputFormat == "fc" ) { ConstIteratorOnPoints it = r.begin(); Point p = *it++; std::cout << p[ 0 ] << " " << p[ 1 ] << " "; for ( ConstIteratorOnPoints it_end = r.end(); it != it_end; ++it ) { Point p2 = *it; Vector v = p2 - p; if ( v[0 ]== 1 ) std::cout << '0'; if ( v[ 1 ] == 1 ) std::cout << '1'; if ( v[ 0 ] == -1 ) std::cout << '2'; if ( v[ 1 ] == -1 ) std::cout << '3'; p = p2; } // close freemanchain if necessary. Point p2= *(r.begin()); Vector v = p2 - p; if ( v.norm1() == 1 ) { if ( v[ 0 ] == 1 ) std::cout << '0'; if ( v[ 1 ] == 1 ) std::cout << '1'; if ( v[ 0 ] == -1 ) std::cout << '2'; if ( v[ 1 ] == -1 ) std::cout << '3'; } std::cout << std::endl; } if (withGeom) { // write geometry of the shape std::stringstream s; s << outputFileName << ".geom"; std::ofstream outstream(s.str().c_str()); //output stream if (!outstream.is_open()) return false; else { outstream << "# " << outputFileName << std::endl; outstream << "# Pointel (x,y), Midpoint of the following linel (x',y')" << std::endl; outstream << "# id x y tangentx tangenty curvaturexy" << " x' y' tangentx' tangenty' curvaturex'y'" << std::endl; std::vector<RealPoint> truePoints, truePoints2; std::vector<RealPoint> trueTangents, trueTangents2; std::vector<double> trueCurvatures, trueCurvatures2; estimateGeometry<Shape, Range, RealPoint, double> (aShape, h, r, truePoints, trueTangents, trueCurvatures); estimateGeometry<Shape, MidPointsRange, RealPoint, double> (aShape, h, gridcurve.getMidPointsRange(), truePoints2, trueTangents2, trueCurvatures2); unsigned int n = (unsigned int)r.size(); for (unsigned int i = 0; i < n; ++i ) { outstream << std::setprecision( 15 ) << i << " " << truePoints[ i ][ 0 ] << " " << truePoints[ i ][ 1 ] << " " << trueTangents[ i ][ 0 ] << " " << trueTangents[ i ][ 1 ] << " " << trueCurvatures[ i ] << " " << truePoints2[ i ][ 0 ] << " " << truePoints2[ i ][ 1 ] << " " << trueTangents2[ i ][ 0 ] << " " << trueTangents2[ i ][ 1 ] << " " << trueCurvatures2[ i ] << std::endl; } } outstream.close(); } ///////////////// } catch ( InputException e ) { std::cerr << "[generateContour]" << " error in finding a bel." << std::endl; return false; } return true; }
bool estimatorOnShapeDigitization( const string& name, Shape & aShape, const RealPoint& low, const RealPoint& up, double h ) { using namespace Z2i; trace.beginBlock ( ( "Curvature estimation on digitization of " + name ). c_str() ); // Creates a digitizer on the window (low, up). GaussDigitizer<Space,Shape> dig; dig.attach( aShape ); // attaches the shape. dig.init( low, up, h ); // The domain size is given by the digitizer // according to the window and the step. Domain domain = dig.getDomain(); // Create cellular space KSpace K; bool ok = K.init( dig.getLowerBound(), dig.getUpperBound(), true ); if ( ! ok ) { std::cerr << "[estimatorOnShapeDigitization]" << " error in creating KSpace." << std::endl; } else try { // Extracts shape boundary SurfelAdjacency<KSpace::dimension> SAdj( true ); SCell bel = Surfaces<KSpace>::findABel( K, dig, 10000 ); // Getting the consecutive surfels of the 2D boundary std::vector<Point> points; Surfaces<KSpace>::track2DBoundaryPoints( points, K, SAdj, dig, bel ); // Create GridCurve GridCurve<KSpace> gridcurve( K ); gridcurve.initFromVector( points ); // Create range of incident points typedef GridCurve<KSpace>::IncidentPointsRange Range; typedef Range::ConstIterator ClassicIterator; typedef Range::ConstCirculator CircularIterator; Range r = gridcurve.getIncidentPointsRange();//building range // Estimation std::vector<double> estimations; if (gridcurve.isOpen()) { typedef StabbingCircleComputer<ClassicIterator> SegmentComputer; typedef CurvatureFromDCAEstimator<SegmentComputer> SCEstimator; typedef MostCenteredMaximalSegmentEstimator<SegmentComputer,SCEstimator> CurvatureEstimator; SegmentComputer sc; SCEstimator sce; CurvatureEstimator estimator(sc, sce); std::cout << "# open grid curve" << endl; estimator.init( h, r.begin(), r.end() ); estimator.eval( r.begin(), r.end(), std::back_inserter(estimations) ); } else { typedef StabbingCircleComputer<CircularIterator> SegmentComputer; typedef CurvatureFromDCAEstimator<SegmentComputer> SCEstimator; typedef MostCenteredMaximalSegmentEstimator<SegmentComputer,SCEstimator> CurvatureEstimator; SegmentComputer sc; SCEstimator sce; CurvatureEstimator estimator(sc, sce); std::cout << "# closed grid curve" << endl; estimator.init( h, r.c(), r.c() ); estimator.eval( r.c(), r.c(), std::back_inserter(estimations) ); } // Print (standard output) std::cout << "# idx kappa" << endl; unsigned int i = 0; for ( ClassicIterator it = r.begin(), ite = r.end(); it != ite; ++it, ++i ) { std::cout << i << " " << estimations.at(i) << std::endl; } } catch ( InputException e ) { std::cerr << "[estimatorOnShapeDigitization]" << " error in finding a bel." << std::endl; ok = false; } trace.emphase() << ( ok ? "Passed." : "Error." ) << endl; trace.endBlock(); return ok; }
bool testTrueLocalEstimatorOnShapeDigitization( const string & name, Shape & aShape, double h ) { using namespace Z2i; trace.beginBlock ( ( "Testing TrueLocalEstimator on digitization of " + name ). c_str() ); // Creates a digitizer on the window (xLow, xUp). typedef Space::RealPoint RealPoint; RealPoint xLow( -10.0, -10.0 ); RealPoint xUp( 10.0, 10.0 ); GaussDigitizer<Space,Shape> dig; dig.attach( aShape ); // attaches the shape. dig.init( xLow, xUp, h ); // The domain size is given by the digitizer according to the window // and the step. Domain domain = dig.getDomain(); // Create cellular space KSpace K; bool ok = K.init( dig.getLowerBound(), dig.getUpperBound(), true ); if ( ! ok ) { std::cerr << "[testTrueLocalEstimatorOnShapeDigitization]" << " error in creating KSpace." << std::endl; } else try { // Extracts shape boundary SurfelAdjacency<KSpace::dimension> SAdj( true ); SCell bel = Surfaces<KSpace>::findABel( K, dig, 10000 ); // Getting the consecutive surfels of the 2D boundary std::vector<Point> points; Surfaces<KSpace>::track2DBoundaryPoints( points, K, SAdj, dig, bel ); // Create GridCurve GridCurve<KSpace> gridcurve; gridcurve.initFromVector( points ); typedef GridCurve<KhalimskySpaceND<2> >::PointsRange Range; typedef Range::ConstIterator ConstIteratorOnPoints; typedef ParametricShapeCurvatureFunctor< Shape > Curvature; TrueLocalEstimatorOnPoints< ConstIteratorOnPoints, Shape, Curvature > curvatureEstimator; Range r = gridcurve.getPointsRange();//building range curvatureEstimator.init( h, r.begin(), r.end(), &aShape, true); std::cout << "# idx x y kappa" << endl; unsigned int i = 0; for ( ConstIteratorOnPoints it = r.begin(), ite = r.end(); it != ite; ++it, ++i ) { RealPoint x = *it; double kappa = curvatureEstimator.eval( it ); std::cout << i << " " << x.at( 0 ) << " " << x.at( 1 ) << " " << kappa << std::endl; } } catch ( InputException e ) { std::cerr << "[testTrueLocalEstimatorOnShapeDigitization]" << " error in finding a bel." << std::endl; ok = false; } trace.emphase() << ( ok ? "Passed." : "Error." ) << endl; trace.endBlock(); return ok; }
bool testDigitization( const Shape & aShape, double h, const string & fileName ) { typedef typename Space::Point Point; typedef typename Space::RealPoint RealPoint; typedef HyperRectDomain<Space> Domain; typedef typename DigitalSetSelector < Domain, BIG_DS + HIGH_ITER_DS + HIGH_BEL_DS >::Type MySet; // Creates a digitizer on the window (xLow, xUp). RealPoint xLow( -5.3, -4.3 ); RealPoint xUp( 7.4, 4.7 ); GaussDigitizer<Space,Shape> dig; dig.attach( aShape ); // attaches the shape. dig.init( xLow, xUp, h ); // The domain size is given by the digitizer according to the window // and the step. Domain domain = dig.getDomain(); // ( dig.getLowerBound(), dig.getUpperBound() ); MySet aSet( domain ); // Creates a set from the digitizer. Shapes<Domain>::shaper( aSet, dig ); // Create cellular space typedef Z2i::KSpace KSpace; typedef Z2i::SCell SCell; KSpace K; bool ok = K.init( dig.getLowerBound(), dig.getUpperBound(), true ); ASSERT( ok ); SurfelAdjacency<KSpace::dimension> SAdj( true ); // Extracts shape boundary SCell bel = Surfaces<KSpace>::findABel( K, dig, 10000 ); // Getting the consecutive surfels of the 2D boundary std::vector<Point> points; Surfaces<KSpace>::track2DBoundaryPoints( points, K, SAdj, dig, bel ); GridCurve<KSpace> gridcurve; gridcurve.initFromVector( points ); // Display all Board2D board; board.setUnit( LibBoard::Board::UCentimeter ); board << SetMode( domain.styleName(), "Paving" ) << domain << aSet; board << SetMode( gridcurve.styleName(), "Edges" ) << CustomStyle( bel.styleName(), new CustomColors( DGtal::Color( 0, 0, 0 ), DGtal::Color( 0, 192, 0 ) ) ) << gridcurve; board << SetMode( gridcurve.styleName(), "Points" ) << CustomStyle( bel.styleName(), new CustomColors( DGtal::Color( 255, 0, 0 ), DGtal::Color( 200, 0, 0 ) ) ) << gridcurve; board.saveEPS( ( fileName + ".eps" ).c_str() ); board.saveSVG( ( fileName + ".svg" ).c_str() ); return true; }