Beispiel #1
0
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");
}
Beispiel #2
0
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");

}
Beispiel #3
0
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");
}
Beispiel #4
0
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;

}