int main() { const std::string examplesPath= "/home/remi/pred/DGtal_PRED/Source/Experience/"; std::string filename = examplesPath + "samples/contourS.pgm"; Image image = DGtal::PNMReader<Image>::importPGM(filename); DGtal::trace.info() << "Imported image: "<<image<<endl; DGtal::Board2D aBoard; aBoard << image.domain(); aBoard.saveSVG("imageDomainTuto.svg"); aBoard.clear(); Display2DFactory::drawImage<Gray>(aBoard, image, (unsigned char)0, (unsigned char)255); aBoard.saveEPS("imageDomainTuto2.eps"); typedef IntervalForegroundPredicate<Image> Binarizer; Binarizer b(image,1, 135); typedef DGtal::DistanceTransformation<Z2i::Space, Binarizer, 2> DTL2; typedef DTL2::OutputImage OutputImage; DTL2 dt(image.domain(),b); OutputImage result = dt.compute(); OutputImage::Value maxDT = (*std::max_element(result.begin(), result.end())); typedef DGtal::HueShadeColorMap<OutputImage::Value,2> HueTwice; aBoard.clear(); Display2DFactory::drawImage<HueTwice>(aBoard, result, (OutputImage::Value)0, (OutputImage::Value)maxDT); aBoard.saveEPS("imageDomainTuto3.eps"); }
void distanceTransformation() { /** Read a file **/ typedef DGtal::ImageContainerBySTLVector< DGtal::Z2i::Domain, unsigned char> Image; typedef DGtal::GrayscaleColorMap<unsigned char> Gray; std::string filename = examplesPath + "contourS.pgm"; Image image = DGtal::PGMReader<Image>::importPGM(filename); DGtal::trace.info() << "Imported image: "<<image<<std::endl; /** Saving domain and image **/ DGtal::Board2D aBoard; aBoard << image.domain(); aBoard.saveSVG("imageDomainTuto.svg"); aBoard.clear(); DGtal::Display2DFactory::drawImage<Gray>(aBoard, image, (unsigned char)0, (unsigned char)255); aBoard.saveEPS("imageDomainTuto2.eps"); /** Creating binarization and euclidean DT **/ typedef DGtal::functors::IntervalForegroundPredicate<Image> Binarizer; //Threshold to 135 Binarizer b(image,1, 135); typedef DGtal::DistanceTransformation<DGtal::Z2i::Space, Binarizer, DGtal::Z2i::L2Metric> DTL2; DTL2 dt(&image.domain(),&b, &DGtal::Z2i::l2Metric ); DTL2::Value maxDT = (*std::max_element(dt.constRange().begin(), dt.constRange().end())); typedef DGtal::HueShadeColorMap<DTL2::Value,2> HueTwice; aBoard.clear(); DGtal::Display2DFactory::drawImage<HueTwice>(aBoard, dt, (DTL2::Value)0, (DTL2::Value)maxDT); aBoard.saveEPS("imageDomainTuto3.eps"); }
void tutoGridCurve() { DGtal::Z2i::Curve c; std::string square = examplesPath + "smallSquare.dat"; std::fstream inputStream; //read file inputStream.open (square.c_str(), std::ios::in); //line drawn with coordinates x y c.initFromVectorStream(inputStream); inputStream.close(); //Allows to display 2D objects DGtal::Board2D board; board << c; DGtal::Z2i::Curve::OuterPointsRange r1 = c.getOuterPointsRange(); board << r1; board.saveEPS("gridCurve.eps"); }
int main(int argc, char** argv) { if(argc != 4) { cout << argc << endl; cout << "to use this program you have to enter this command line ./main path/of/the/picture connexity threshold " << endl; cout << "Threshold should be in 0-255" << endl; cout << "connexity should be 4connexity or 8connexity or chamfer5711" << endl; } else { int threshold = atoi(argv[2]); if(threshold <= 255 && threshold >= 0 && ( (strcmp(argv[3],"4connexity") == 0 ) || (strcmp(argv[3],"8connexity") == 0 ) || strcmp(argv[3],"chamfer5711") == 0) ) { vector<point2dWeighting> myWeightingVector; if(strcmp(argv[3],"4connexity") == 0 ) { make4Connexity(myWeightingVector); } else if(strcmp(argv[3],"8connexity") == 0) { make8Connexity(myWeightingVector); } else { makeSimpleChamfrein(myWeightingVector); } // mask creation SymmetricMask<point2dWeighting> myMask; SymmetricMaskGenerator<point2dWeighting> generateur; myMask = generateur.generateMask(myWeightingVector); // CMETRIC and distance Transform instanciation CChamferMetric<int,point2d> myMetric(myMask); ChamferDistanceTransform<int,point2d> myDistance(myMetric); Image image = DGtal::PNMReader<Image>::importPGM(argv[1], true); /** distance transformation **/ ImageInt output = myDistance.applyAlgorithm(image,threshold,true); /** output colorisation **/ DGtal::Board2D aBoard; ImageInt::Value maxDT = (*std::max_element(output.begin(), output.end())); typedef DGtal::HueShadeColorMap<ImageInt::Value,2> HueTwice; aBoard.clear(); Display2DFactory::drawImage<HueTwice>(aBoard, output, (ImageInt::Value)0, (ImageInt::Value)maxDT); aBoard.saveEPS(outputNameFile); /** distance transformation numeric output **/ /* typename Image::Domain::ConstIterator dit= image.domain().begin(); for(;dit != image.domain().end();++dit) { cout << (*dit) << " : " << (int)output(*dit) << endl; }*/ } } return 0; }
int main () { Delaunay t; trace.beginBlock("Construction the shape"); typedef Ellipse2D<Z2i::Space> Ellipse; int a = 5, b = 3; Ellipse2D<Z2i::Space> ellipse(Z2i::Point(0,0), a, b, 0.3 ); // Ellipse2D<Z2i::Space> ellipse(Z2i::Point(0,0), 5.5, 5.5, 0 ); double h = 0.25; GaussDigitizer<Z2i::Space,Ellipse> dig; dig.attach( ellipse ); dig.init( ellipse.getLowerBound()+Z2i::Vector(-1,-1), ellipse.getUpperBound()+Z2i::Vector(1,1), h ); // typedef Flower2D<Z2i::Space> Flower; // Flower2D<Z2i::Space> flower(Z2i::Point(0,0), 15, 2, 5, 0); // double h = 0.25; // GaussDigitizer<Z2i::Space,Flower> dig; // dig.attach( flower ); // dig.init( flower.getLowerBound()+Z2i::Vector(-1,-1), // flower.getUpperBound()+Z2i::Vector(1,1), h ); Z2i::KSpace ks; ks.init( dig.getLowerBound(), dig.getUpperBound(), true ); SurfelAdjacency<2> sAdj( true ); Z2i::SCell bel = Surfaces<Z2i::KSpace>::findABel( ks, dig, 1000 ); std::vector<Z2i::Point> boundaryPoints; Surfaces<Z2i::KSpace> ::track2DBoundaryPoints( boundaryPoints, ks, sAdj, dig, bel ); Z2i::Curve c; c.initFromVector( boundaryPoints ); typedef Z2i::Curve::PointsRange Range; Range r = c.getPointsRange(); trace.endBlock(); trace.beginBlock("Delaunay"); for(Range::ConstIterator it=r.begin(), itend=r.end(); it != itend; ++it) { t.insert( Point( (*it)[0], (*it)[1])); t.insert( Point( (*it)[0] + 3 + (int) ceil( ((double)b)/h ), (*it)[1] - 3 - (int) ceil( ((double)a)/h ) )); } trace.endBlock(); std::cout << "number of vertices : " ; std::cout << t.number_of_vertices() << std::endl; std::cout << "number of faces : " ; std::cout << t.number_of_faces() << std::endl; trace.beginBlock("Area minimizing triangulation"); Edge_iterator itnext; bool flip = true; bool inverse = false; unsigned int pass = 0; while ( flip ) { std::cout << "----------- pass " << pass << " -------------------" << std::endl; inverse = false; flip = false; int nb_flip = 0; int nb_random_flip = 0; for( Edge_iterator it = t.edges_begin(), itend=t.edges_end(); it != itend; it = itnext ) { // vertex(cw(i)) and vertex(ccw(i)) of f. itnext = it; ++itnext; Edge e1 = *it; if ( isEdgeElementary( t, e1.first->vertex( t.ccw( e1.second ) ), e1.first->vertex( t.cw( e1.second ) ) ) ) continue; Edge e2 = t.mirror_edge( e1 ); if ( ! isQuadrilateral( t, e1.first->vertex( e1.second ), e1.first->vertex( t.ccw( e1.second ) ), e2.first->vertex( e2.second ), e1.first->vertex( t.cw( e1.second ) ) ) ) continue; int nb_f1 = twiceNbLatticePointsInTriangle( t, e1.first ); int nb_f2 = twiceNbLatticePointsInTriangle( t, e2.first ); int nb_flip_f1 = twiceNbLatticePointsInTriangle( t, e1.first->vertex( e1.second ), e1.first->vertex( t.ccw( e1.second ) ), e2.first->vertex( e2.second ) ); int nb_flip_f2 = twiceNbLatticePointsInTriangle( t, e1.first->vertex( e1.second ), e1.first->vertex( t.cw( e1.second ) ), e2.first->vertex( e2.second ) ); int nb_min = nb_f1 <= nb_f2 ? nb_f1 : nb_f2; int nb_flip_min = nb_flip_f1 <= nb_flip_f2 ? nb_flip_f1 : nb_flip_f2; if ( nb_flip_min < nb_min ) { std::cout << "flipped " << e1.first->vertex( e1.second )->point() << "->" << e1.first->vertex( e1.second )->point() << std::endl; t.flip( e1.first, e1.second ); nb_flip++; flip = true; } if ( nb_flip_min == nb_min ) { inverse = true; if ( random() % 2 == 1 ) { std::cout << "Random flipped " << e1.first->vertex( e1.second )->point() << "->" << e1.first->vertex( e1.second )->point() << std::endl; t.flip( e1.first, e1.second ); nb_random_flip++; } } // if ( ( empty_f1 == false ) // && ( empty_f2 == false ) ) // { // try if flip is better. // bool empty_flip_f1 // = twiceNbLatticePointsInTriangle( t, // e1.first->vertex( e1.second ), // e1.first->vertex( t.ccw( e1.second ) ), // e2.first->vertex( e2.second ) ) == 0; // bool empty_flip_f2 // = twiceNbLatticePointsInTriangle( t, // e2.first->vertex( e2.second ), // e2.first->vertex( t.ccw( e2.second ) ), // e1.first->vertex( e1.second ) ) == 0; // if ( empty_flip_f1 || empty_flip_f2 ) // { // if ( isEdgeElementary( t, // e1.first->vertex( t.ccw( e1.second ) ), // e1.first->vertex( t.cw( e1.second ) ) ) ) // { // std::cout << "Flip forbidden: " << e1.first->vertex( e1.second )->point() // << "->" << e1.first->vertex( e1.second )->point() // << std::endl; // } // else // { // std::cout << "flipped " << e1.first->vertex( e1.second )->point() // << "->" << e1.first->vertex( e1.second )->point() // << std::endl; // t.flip( e1.first, e1.second ); // flip = true; // } // } // } } std::cout << "----------- nb_flip " << nb_flip << ", nb_random " << nb_random_flip << " -------------" << std::endl; ++pass; if ( inverse && ( (nb_random_flip+4) > log(pass) ) ) flip = true; } trace.endBlock(); // GridCurve Z2i::Curve gc; gc.initFromPointsRange( r.begin(), r.end() ); typedef Z2i::Curve::PointsRange::ConstIterator ConstIterator; typedef ArithmeticalDSS<ConstIterator,int,4> DSS4; typedef SaturatedSegmentation<DSS4> Segmentation; //Segmentation Z2i::Curve::PointsRange range = gc.getPointsRange(); DSS4 dss4RecognitionAlgorithm; Segmentation theSegmentation( range.begin(), range.end(), dss4RecognitionAlgorithm ); DGtal::Board2D board; Z2i::Point dP; board << CustomStyle( dP.className(), new CustomPen( Color(0,0,0), Color(230,230,230), 1, Board2D::Shape::SolidStyle, Board2D::Shape::RoundCap, Board2D::Shape::RoundJoin )); for(Range::ConstIterator it=r.begin(), itend=r.end(); it != itend; ++it) board << *it; for(Faces_iterator it = t.finite_faces_begin(), itend=t.finite_faces_end(); it != itend; ++it) { Z2i::Point a( toDGtal(it->vertex(0)->point())), b(toDGtal(it->vertex(1)->point())), c(toDGtal(it->vertex(2)->point())); // Z2i::Vector ab( b - a ), ac( c - a ); // int d = ab[ 0 ] * ac[ 1 ] - ab[ 1 ] * ac[ 0 ]; if ( emptyLatticeTriangle( t, it ) ) //( ( d == 1 ) || (d == -1 ) ) { board.setPenColor(DGtal::Color::Blue); board.setFillColor( DGtal::Color::None ); board.setLineWidth( 3.0 ); board.drawTriangle(a[0],a[1],b[0],b[1],c[0],c[1]); } else { board.setPenColor(DGtal::Color::Red); board.setFillColor( DGtal::Color::None ); // board.setFillColorRGBi(200,200,200,128); board.setLineWidth( 2.0 ); board.drawTriangle(a[0],a[1],b[0],b[1],c[0],c[1]); } } Segmentation::SegmentComputerIterator i = theSegmentation.begin(); Segmentation::SegmentComputerIterator end = theSegmentation.end(); board.setPenColor(DGtal::Color::Green); board.setFillColor( DGtal::Color::None ); board << SetMode( "ArithmeticalDSS", "BoundingBox" ); std::string aStyleName = "ArithmeticalDSS/BoundingBox"; for ( ; i != end; ++i) { DSS4 current(*i); board << CustomStyle( aStyleName, new CustomPenColor( DGtal::Color::Green ) ) << current; } // Display Voronoi. // for(Edge_iterator it = t.edges_begin(), itend=t.edges_end(); // it != itend; ++it) // { // // vertex(cw(i)) and vertex(ccw(i)) of f. // Face_handle itf = it->first; // int i = it->second; // Z2i::Point a( toDGtal(itf->vertex( t.cw( i ) )->point())); // Z2i::Point b( toDGtal(itf->vertex( t.ccw( i ) )->point())); // CGAL::Object o = t.dual( it ); // if (CGAL::object_cast<K::Segment_2>(&o)) // { // const K::Segment_2* ptrSegment = CGAL::object_cast<K::Segment_2>(&o); // board.setPenColor(DGtal::Color::Black); // board.setFillColor( DGtal::Color::None ); // board.setLineWidth( 2.0 ); // board.drawLine( ptrSegment->source().x(), // ptrSegment->source().y(), // ptrSegment->target().x(), // ptrSegment->target().y() ); // } // else if (CGAL::object_cast<K::Ray_2>(&o)) // { // const K::Ray_2* ptrRay = CGAL::object_cast<K::Ray_2>(&o); // board.setPenColor(DGtal::Color::Black); // board.setFillColor( DGtal::Color::None ); // board.setLineWidth( 2.0 ); // double dx = ptrRay->to_vector().x(); // double dy = ptrRay->to_vector().y(); // double norm = sqrt( dx*dx+dy*dy ); // dx = 5.0 * dx / norm; // dy = 5.0 * dy / norm; // board.drawArrow( ptrRay->source().x(), // ptrRay->source().y(), // ptrRay->source().x() + dx, //1*ptrRay->to_vector().x(), // ptrRay->source().y() + dy ); //1*ptrRay->to_vector().y() ); // } // } board.saveSVG("delaunay.svg"); board.saveEPS("delaunay.eps"); return 0; }
int main() { //shape typedef Flower2D<Z2i::Space> Flower; Flower2D<Z2i::Space> flower(Z2i::Point(0,0), 20, 5, 5, 0); //! [shapeGridCurveEstimator-dig] //implicit digitization of a shape of type Flower //into a digital space of type Space double h = 1; GaussDigitizer<Z2i::Space,Flower> dig; dig.attach( flower ); dig.init( flower.getLowerBound()+Z2i::Vector(-1,-1), flower.getUpperBound()+Z2i::Vector(1,1), h ); //! [shapeGridCurveEstimator-dig] //! [shapeGridCurveEstimator-prepareTracking] //Khalimsky space Z2i::KSpace ks; ks.init( dig.getLowerBound(), dig.getUpperBound(), true ); //adjacency (4-connectivity) SurfelAdjacency<2> sAdj( true ); //! [shapeGridCurveEstimator-prepareTracking] //! [shapeGridCurveEstimator-tracking] //searching for one boundary element Z2i::SCell bel = Surfaces<Z2i::KSpace>::findABel( ks, dig, 1000 ); //tracking vector<Z2i::Point> boundaryPoints; Surfaces<Z2i::KSpace> ::track2DBoundaryPoints( boundaryPoints, ks, sAdj, dig, bel ); //! [shapeGridCurveEstimator-tracking] //! [shapeGridCurveEstimator-instantiation] Z2i::Curve c; c.initFromVector( boundaryPoints ); //! [shapeGridCurveEstimator-instantiation] DGtal::Board2D aBoard; aBoard << c; aBoard.saveEPS("DisplayGridCurve1.eps"); //! [shapeGridCurveEstimator-getRange] //range of points typedef Z2i::Curve::PointsRange Range; Range r = c.getPointsRange(); //! [shapeGridCurveEstimator-getRange] //! [shapeGridCurveEstimator-lengthEstimation] //length estimation DSSLengthEstimator< Range::ConstIterator > DSSlength; DSSlength.init( h, r.begin(), r.end(), c.isClosed() ); double length1 = DSSlength.eval(); trace.info() << "Length (h=" << h << "): " << length1 << endl; //! [shapeGridCurveEstimator-lengthEstimation] //@TODO correct init method of trueLengthEstimator (remove &flower) //! [shapeGridCurveEstimator-trueLengthEstimation] typedef ParametricShapeArcLengthFunctor< Flower > Length; TrueGlobalEstimatorOnPoints< Range::ConstIterator, Flower, Length > trueLengthEstimator; trueLengthEstimator.init( h, r.begin(), r.end(), &flower, c.isClosed()); double trueLength = trueLengthEstimator.eval(); trace.info() << "ground truth: " << trueLength << endl; //! [shapeGridCurveEstimator-trueLengthEstimation] //! [shapeGridCurveEstimator-higher] //implicit digitization at higher resolution h = 0.1; dig.init( flower.getLowerBound()+Z2i::Vector(-1,-1), flower.getUpperBound()+Z2i::Vector(1,1), h ); //a greater domain is needed in the Khalimsky space ks.init( dig.getLowerBound(), dig.getUpperBound(), true ); //searching for one boundary element bel = Surfaces<Z2i::KSpace>::findABel( ks, dig, 10000 ); //tracking Surfaces<Z2i::KSpace> ::track2DBoundaryPoints( boundaryPoints, ks, sAdj, dig, bel ); //reset grid curve and its points range c.initFromVector( boundaryPoints ); Range r2 = c.getPointsRange(); //estimate length DSSlength.init( h, r2.begin(), r2.end(), c.isClosed() ); double length2 = DSSlength.eval(); trace.info() << "Length (h=" << h << "): " << length2 << endl; //! [shapeGridCurveEstimator-higher] aBoard.clear(); aBoard << c; aBoard.saveEPS("DisplayGridCurve01.eps"); return 0; }