コード例 #1
0
/**
 * Algorithms that computes the convex hull
 * of a point set
 */
void convexHull()
{
  //Digitization of a disk of radius 6
  Ball2D<Z2i::Space> ball(Z2i::Point(0,0), 6);
  Z2i::Domain domain(ball.getLowerBound(), ball.getUpperBound());
  Z2i::DigitalSet pointSet(domain);   
  Shapes<Z2i::Domain>::euclideanShaper(pointSet, ball);

  //! [Hull2D-Namespace]
  using namespace functions::Hull2D; 
  //! [Hull2D-Namespace]

  //! [Hull2D-Functor]
  typedef InHalfPlaneBySimple3x3Matrix<Z2i::Point, DGtal::int64_t> Functor;  
  Functor functor; 
  //! [Hull2D-Functor]

  { //convex hull in counter-clockwise order
    vector<Z2i::Point> res; 

    //! [Hull2D-StrictPredicateCCW]
    typedef PredicateFromOrientationFunctor2<Functor, false, false> StrictPredicate; 
    StrictPredicate predicate( functor ); 
    //! [Hull2D-StrictPredicateCCW]
    //according to the last two template arguments, neither strictly negative values, nor zeros are accepted: 
    //the predicate returns 'true' only for strictly positive values returned by the underlying functor. 

    //! [Hull2D-AndrewAlgo]
    andrewConvexHullAlgorithm( pointSet.begin(), pointSet.end(), back_inserter( res ), predicate );   
    //! [Hull2D-AndrewAlgo]
    //![Hull2D-Caliper-computeBasic]
    double th = DGtal::functions::Hull2D::computeHullThickness(res.begin(), res.end(), DGtal::functions::Hull2D::HorizontalVerticalThickness);
    //![Hull2D-Caliper-computeBasic]

    //![Hull2D-Caliper-computeAnti]
    Z2i::Point antipodalP, antipodalQ, antipodalS;
    th = DGtal::functions::Hull2D::computeHullThickness(res.begin(), res.end(), DGtal::functions::Hull2D::HorizontalVerticalThickness, antipodalP, antipodalQ, antipodalS);
    //![Hull2D-Caliper-computeAnti]

    
    trace.info() <<" ConvexHull HV thickness: " << th << std::endl;
    //display
    Board2D board;
    drawPolygon( res.begin(), res.end(), board ); 
    //![Hull2D-Caliper-display]
    board.setPenColor(DGtal::Color::Red);
    board.drawCircle( antipodalS[0], antipodalS[1], 0.2) ;
    board.setPenColor(DGtal::Color::Blue);
    board.drawCircle(antipodalP[0], antipodalP[1], 0.2);
    board.drawCircle(antipodalQ[0], antipodalQ[1], 0.2);
    board.drawLine(antipodalP[0], antipodalP[1], antipodalQ[0], antipodalQ[1]);
    //![Hull2D-Caliper-display]
    
    board.saveSVG( "ConvexHullCCW.svg" );  
#ifdef WITH_CAIRO
    board.saveCairo("ConvexHullCCW.png", Board2D::CairoPNG);
#endif
  }

  { //convex hull in counter-clockwise order with all the points lying on the edges
    vector<Z2i::Point> res; 

    //! [Hull2D-LargePredicateCCW]
    typedef PredicateFromOrientationFunctor2<Functor, false, true> LargePredicate; 
    LargePredicate predicate( functor ); 
    //! [Hull2D-LargePredicateCCW]
    //according to the last template argument, zeros are accepted so that  
    //the predicate returns 'true' for all the positive values returned by the underlying functor. 

    //andrew algorithm
    andrewConvexHullAlgorithm( pointSet.begin(), pointSet.end(), back_inserter( res ), predicate );   

    //display
    Board2D board;
    drawPolygon( res.begin(), res.end(), board ); 
    board.saveSVG( "ConvexHullCCWWithPointsOnEdges.svg" );  
#ifdef WITH_CAIRO
    board.saveCairo("ConvexHullCCWWithPointsOnEdges.png", Board2D::CairoPNG);
#endif

  }

  { //convex hull in clockwise order
    vector<Z2i::Point> res; 

    //! [Hull2D-StrictPredicateCW]
    typedef PredicateFromOrientationFunctor2<Functor, true, false> StrictPredicate; 
    StrictPredicate predicate( functor );
    //! [Hull2D-StrictPredicateCW]
    //according to the last two argument template, 
    //the predicate returns 'true' only for strictly negative values returned by the underlying functor. 

    //andrew algorithm
    andrewConvexHullAlgorithm( pointSet.begin(), pointSet.end(), back_inserter( res ), predicate );   

    //display
    Board2D board;
    drawPolygon( res.begin(), res.end(), board ); 
    board.saveSVG( "ConvexHullCW.svg" );  
#ifdef WITH_CAIRO
    board.saveCairo("ConvexHullCW.png", Board2D::CairoPNG);
#endif
  }

  { //convex hull in counter-clockwise order
    vector<Z2i::Point> res; 

    //geometric predicate
    typedef PredicateFromOrientationFunctor2<Functor, false, false> StrictPredicate; 
    StrictPredicate predicate( functor ); 

    //! [Hull2D-GrahamAlgo]
    grahamConvexHullAlgorithm( pointSet.begin(), pointSet.end(), back_inserter( res ), predicate ); 
    //! [Hull2D-GrahamAlgo]

    //display
    Board2D board;
    drawPolygon( res.begin(), res.end(), board ); 
    board.saveSVG( "ConvexHullCCWbis.svg" );  
#ifdef WITH_CAIRO
    board.saveCairo("ConvexHullCCWbis.png", Board2D::CairoPNG);
#endif
  }

  { //convex hull of a simple polygonal line that is not weakly externally visible
    vector<Z2i::Point> polygonalLine;
    polygonalLine.push_back(Z2i::Point(0,0)); 
    polygonalLine.push_back(Z2i::Point(0,4)); 
    polygonalLine.push_back(Z2i::Point(1,4)); 
    polygonalLine.push_back(Z2i::Point(1,1)); 
    polygonalLine.push_back(Z2i::Point(3,1)); 
    polygonalLine.push_back(Z2i::Point(2,2)); 
    polygonalLine.push_back(Z2i::Point(3,4)); 
    polygonalLine.push_back(Z2i::Point(4,4)); 
    polygonalLine.push_back(Z2i::Point(4,0)); 

    vector<Z2i::Point> resGraham, res; 

    typedef PredicateFromOrientationFunctor2<Functor, false, false> StrictPredicate; 
    StrictPredicate predicate( functor ); 
    closedGrahamScanFromAnyPoint( polygonalLine.begin(), polygonalLine.end(), back_inserter( resGraham ), predicate );   

    //! [Hull2D-OnLineMelkmanAlgo]
    DGtal::MelkmanConvexHull<Z2i::Point, Functor> ch( functor ); 
    for (std::vector<Z2i::Point>::const_iterator 
	   it = polygonalLine.begin(), 
	   itEnd = polygonalLine.end(); 
	 it != itEnd; ++it)
      ch.add( *it ); 
    //! [Hull2D-OnLineMelkmanAlgo]

    //! [Hull2D-OffLineMelkmanAlgo]
    melkmanConvexHullAlgorithm( polygonalLine.begin(), polygonalLine.end(), back_inserter( res ), functor );   
    //! [Hull2D-OffLineMelkmanAlgo]

    //display
    Board2D board;
    drawPolygon( polygonalLine.begin(), polygonalLine.end(), board, true ); 
    board.saveSVG( "SimplePolygonalLine.svg" );  
#ifdef WITH_CAIRO
    board.saveCairo("SimplePolygonalLine.png", Board2D::CairoPNG);
#endif
    board.clear(); 
    drawPolygon( resGraham.begin(), resGraham.end(), board ); 
    board.saveSVG( "SimplePolygonalLineGraham.svg" );  
#ifdef WITH_CAIRO
    board.saveCairo("SimplePolygonalLineGraham.png", Board2D::CairoPNG);
#endif
    board.clear(); 
    drawPolygon( res.begin(), res.end(), board ); 
    board.saveSVG( "SimplePolygonalLineMelkman.svg" );  
#ifdef WITH_CAIRO
    board.saveCairo("SimplePolygonalLineMelkman.png", Board2D::CairoPNG);
#endif
    board.clear(); 
    drawPolygon( ch.begin(), ch.end(), board ); 
    board.saveSVG( "SimplePolygonalLineMelkman2.svg" );  
#ifdef WITH_CAIRO
    board.saveCairo("SimplePolygonalLineMelkman2.png", Board2D::CairoPNG);
#endif
  }

  { //order of the points for andrew algorithm
    vector<Z2i::Point> res; 
    std::copy( pointSet.begin(), pointSet.end(), back_inserter( res ) ); 

    std::sort( res.begin(), res.end() ); 

    //display
    Board2D board;
    drawPolygon( res.begin(), res.end(), board, false ); 
    board.saveSVG( "AndrewWEVP.svg" );  
#ifdef WITH_CAIRO
    board.saveCairo("AndrewWEVP.png", Board2D::CairoPNG);
#endif
  }

  { //order of the points for graham algorithm
    vector<Z2i::Point> res; 
    std::copy( pointSet.begin(), pointSet.end(), back_inserter( res ) ); 

    //find an extremal point
    //NB: we choose the point of greatest x-coordinate
    //so that the sort step (by a polar comparator) 
    //returns a weakly externally visible polygon
    std::vector<Z2i::Point>::iterator itMax 
      = std::max_element( res.begin(), res.end() ); 

    //sort around this point with a polar comparator
    functors::PolarPointComparatorBy2x2DetComputer<Z2i::Point> comparator;  
    comparator.setPole( *itMax );
    std::sort( res.begin(), res.end(), comparator ); 

    //display
    Board2D board;
    drawPolygon( res.begin(), res.end(), board, false ); 
    board.saveSVG( "GrahamWEVP.svg" );  
#ifdef WITH_CAIRO
    board.saveCairo("GrahamWEVP.png", Board2D::CairoPNG);
#endif
  }


}
コード例 #2
0
ファイル: delta-distance.cpp プロジェクト: dcoeurjo/VCM
int main( int argc, char** argv )
{
  using namespace DGtal;
  using namespace DGtal::Z2i;
  
  typedef ImageContainerBySTLVector<Domain,unsigned char> GrayLevelImage2D;
  typedef ImageContainerBySTLVector<Domain,float>         FloatImage2D;
  typedef DistanceToMeasure<FloatImage2D>                 Distance;
  if ( argc <= 3 ) return 1;
  GrayLevelImage2D img  = GenericReader<GrayLevelImage2D>::import( argv[ 1 ] );
  double           mass = atof( argv[ 2 ] );
  double           rmax = atof( argv[ 3 ] );
  FloatImage2D     fimg( img.domain() );
  FloatImage2D::Iterator outIt = fimg.begin();
  for ( GrayLevelImage2D::ConstIterator it = img.begin(), itE = img.end();
        it != itE; ++it )
    {
      float v = ((float)*it) / 255.0;
      *outIt++ = v;
    }
  trace.beginBlock( "Computing delta-distance." );
  Distance     delta( mass, fimg, rmax );
  const FloatImage2D& d2 = delta.myDistance2;
  trace.endBlock();

  float m = 0.0f;
  for ( typename Domain::ConstIterator it = d2.domain().begin(),
          itE = d2.domain().end(); it != itE; ++it )
    {
      Point p = *it;
      float v = sqrt( d2( p ) );
      m = std::max( v, m );
    }

  GradientColorMap<float> cmap_grad( 0, m );
  cmap_grad.addColor( Color( 255, 255, 255 ) );
  cmap_grad.addColor( Color( 255, 255, 0 ) );
  cmap_grad.addColor( Color( 255, 0, 0 ) );
  cmap_grad.addColor( Color( 0, 255, 0 ) );
  cmap_grad.addColor( Color( 0,   0, 255 ) );
  cmap_grad.addColor( Color( 0,   0, 0 ) );
  Board2D board;
  board << SetMode( d2.domain().className(), "Paving" );
  

  for ( typename Domain::ConstIterator it = d2.domain().begin(),
          itE = d2.domain().end(); it != itE; ++it )
    {
      Point p = *it;
      float v = sqrt( d2( p ) );
      v = std::min( (float)m, std::max( v, 0.0f ) ); 
      board << CustomStyle( p.className(),
                            new CustomColors( Color::Black, cmap_grad( v ) ) )
            << p;

      RealVector grad = delta.projection( p );
      board.drawLine( p[ 0 ], p[ 1 ], p[ 0 ] + grad[ 0 ], p[ 1 ] + grad[ 1 ], 0 );
    }
  std::cout << endl;
  board.saveEPS("delta2.eps");
  return 0;
}
コード例 #3
0
int main( int argc, char** argv )
{
  using namespace DGtal;
  using namespace DGtal::Z2i;
  
  typedef ImageContainerBySTLVector<Domain,unsigned char> GrayLevelImage2D;
  typedef ImageContainerBySTLVector<Domain,double>         DoubleImage2D;
  typedef DistanceToMeasure<DoubleImage2D>                 Distance;
  if ( argc <= 3 ) return 1;
  GrayLevelImage2D img  = GenericReader<GrayLevelImage2D>::import( argv[ 1 ] );
  double           mass = atof( argv[ 2 ] );
  double           rmax = atof( argv[ 3 ] );
  double           R    = atof( argv[ 4 ] );
  double           r    = atof( argv[ 5 ] );
  double           T1    = atof( argv[ 6 ] );
  double           T2    = atof( argv[ 7 ] );
  DoubleImage2D     fimg( img.domain() );
  DoubleImage2D::Iterator outIt = fimg.begin();
  for ( GrayLevelImage2D::ConstIterator it = img.begin(), itE = img.end();
        it != itE; ++it )
    {
      double v = ((double)*it) / 255.0;
      *outIt++ = v;
    }
  trace.beginBlock( "Computing delta-distance." );
  Distance     delta( mass, fimg, rmax );
  const DoubleImage2D& d2 = delta.myDistance2;
  trace.endBlock();

  double m = 0.0f;
  for ( typename Domain::ConstIterator it = d2.domain().begin(),
          itE = d2.domain().end(); it != itE; ++it )
    {
      Point p = *it;
      double v = sqrt( d2( p ) );
      m = std::max( v, m );
    }

  GradientColorMap<double> cmap_grad( 0, m );
  cmap_grad.addColor( Color( 255, 255, 255 ) );
  cmap_grad.addColor( Color( 255, 255, 0 ) );
  cmap_grad.addColor( Color( 255, 0, 0 ) );
  cmap_grad.addColor( Color( 0, 255, 0 ) );
  cmap_grad.addColor( Color( 0,   0, 255 ) );
  cmap_grad.addColor( Color( 0,   0, 0 ) );
  Board2D board;
  board << SetMode( d2.domain().className(), "Paving" );
  
  for ( typename Domain::ConstIterator it = d2.domain().begin(),
          itE = d2.domain().end(); it != itE; ++it )
    {
      Point p = *it;
      double v = sqrt( d2( p ) );
      v = std::min( (double) m, std::max( v, 0.0 ) ); 
      board << CustomStyle( p.className(),
                            new CustomColors( Color::Black, cmap_grad( v ) ) )
            << p;
      RealVector grad = delta.projection( p );
      board.drawLine( p[ 0 ], p[ 1 ], p[ 0 ] + grad[ 0 ], p[ 1 ] + grad[ 1 ], 0 );
    }
  std::cout << endl;
  board.saveEPS("dvcm-delta2.eps");
  board.clear();
  
  trace.beginBlock( "Computing delta-VCM." );
  typedef DeltaVCM< Distance > DVCM;
  typedef DVCM::Matrix                     Matrix;
  DVCM dvcm( delta, R, r );
  trace.endBlock();

  {
    GrayLevelImage2D pm_img( dvcm.myProjectedMeasure.domain() );
    DoubleImage2D::ConstIterator it    = dvcm.myProjectedMeasure.begin();
    DoubleImage2D::ConstIterator itE   = dvcm.myProjectedMeasure.end();
    GrayLevelImage2D::Iterator  outIt = pm_img.begin();
    for ( ; it != itE; ++it )
      {
        double v = std::max( 0.0, std::min( (*it) * 255.0, 255.0 ) );
        *outIt++ = v;
      }
    
    GenericWriter< GrayLevelImage2D >::exportFile( "dvcm-projmeasure.pgm", pm_img );
  }

  typedef EigenDecomposition<2,double> LinearAlgebraTool;
  typedef functors::HatPointFunction<Point,double> KernelFunction;
  KernelFunction chi( 1.0, r );

  // Flat zones are metallic blue, slightly curved zones are white,
  // more curved zones are yellow till red.
  double size = 1.0;
  GradientColorMap<double> colormap( 0.0, T2 );
  colormap.addColor( Color( 128, 128, 255 ) );
  colormap.addColor( Color( 255, 255, 255 ) );
  colormap.addColor( Color( 255, 255, 0 ) );
  colormap.addColor( Color( 255, 0, 0 ) );
  Matrix vcm_r, evec, null;
  RealVector eval;
  for ( Domain::ConstIterator it = dvcm.domain().begin(), itE = dvcm.domain().end();
        it != itE; ++it )
    {
      // Compute VCM and diagonalize it.
      Point p = *it;
      vcm_r = dvcm.measure( chi, p );
      if ( vcm_r == null ) continue;
      LinearAlgebraTool::getEigenDecomposition( vcm_r, evec, eval );
      //double feature = eval[ 0 ] / ( eval[ 0 ] +  eval[ 1 ] );
      eval[ 0 ] = std::max( eval[ 0 ], 0.00001 );
      double tubular = ( eval[ 1 ] <= 0.00001 ) // (R*R/4.0) )
        ? 0
        : ( eval[ 1 ] / ( eval[ 0 ] + eval[ 1 ] ) );
      double bound = T1;
      double tubular2 = tubular * (eval[ 0 ] + eval[ 1 ]) / (R*R*r/12.0);
      double display = tubular2 <= bound ? 0.0 : ( tubular2 - bound ) / (1.0 - bound);
      //: eval[ 1 ] / ( 1.0 + eval[ 0 ] ) / ( 1.0 + delta( p )*delta( p ) );
      //: eval[ 1 ] * eval[ 1 ] / ( 1.0 + eval[ 0 ] ) / ( 1.0 + delta( p ) );
      trace.info() << "l0=" << eval[ 0 ] << " l1=" << eval[ 1 ]
                   << " tub=" << tubular
                   << " tub2=" << tubular2
                   << " disp=" << display << std::endl;
      board << CustomStyle( p.className(), 
                            new CustomColors( Color::Black,
                                              colormap( display > T2 ? T2 : display ) ) )
            << p;
      // Display normal
      RealVector normal = evec.column( 0 );
      RealPoint rp( p[ 0 ], p[ 1 ] ); 
      Display2DFactory::draw( board, size*normal, rp );
      Display2DFactory::draw( board, -size*normal, rp );
    }      
  board.saveEPS("dvcm-hat-r.eps");
  board.clear();
  
  return 0;
}