Beispiel #1
0
void dssLength() {
  typedef DGtal::ImageContainerBySTLVector< DGtal::Z2i::Domain, unsigned char> Image;
  std::string filename = examplesPath + "contourS.pgm";
  Image image = DGtal::PGMReader<Image>::importPGM(filename);

  typedef DGtal::functors::IntervalThresholder<Image::Value> Binarizer;
  Binarizer b(1, 135);
  DGtal::functors::PointFunctorPredicate<Image, Binarizer> predicate(image, b);

  DGtal::Z2i::KSpace ks;
  ks.init( image.domain().lowerBound(), image.domain().upperBound(), true );
  DGtal::SurfelAdjacency<2> sAdj(true);

  std::vector< std::vector< DGtal::Z2i::SCell > > contours;
  DGtal::Surfaces<DGtal::Z2i::KSpace>::extractAll2DSCellContours(contours, ks, sAdj, predicate);

  DGtal::Z2i::Curve c;
  c.initFromSCellsVector( contours.at(1) );
  
  typedef DGtal::Z2i::Curve::PointsRange Range;
  Range r = c.getPointsRange();

  DGtal::DSSLengthEstimator< Range::ConstCirculator > DSSlength;
  DSSlength.init(1, r.c(), r.c());
  DGtal::trace.info() << "Length: " << DSSlength.eval() << std::endl;
  
}
void
estimateGeometry(Shape& s,
                 const double& h,
                 const Range& r,
                 std::vector<Point>& points,
                 std::vector<Point>& tangents,
                 std::vector<Quantity>& curvatures) {
  
  typedef typename Range::ConstIterator ConstIterator;
  for (ConstIterator i = r.begin(); i != r.end(); ++i) {
    Point p( *i );
    p *= h;
    points.push_back(p);
  }
  
  typedef typename Range::ConstCirculator ConstCirculator;
  
  typedef ParametricShapeTangentFunctor< Shape > TangentFunctor;
  TrueLocalEstimatorOnPoints< ConstCirculator, Shape, TangentFunctor >
  trueTangentEstimator;
  trueTangentEstimator.attach(&s);
  trueTangentEstimator.init( h, r.c(), r.c());
  trueTangentEstimator.eval(r.c(), r.c(), std::back_inserter(tangents) );
  
  typedef ParametricShapeCurvatureFunctor< Shape > CurvatureFunctor;
  TrueLocalEstimatorOnPoints< ConstCirculator, Shape, CurvatureFunctor >
  trueCurvatureEstimator;
  trueCurvatureEstimator.attach(&s);
  trueCurvatureEstimator.init( h, r.c(), r.c());
  trueCurvatureEstimator.eval(r.c(), r.c(), std::back_inserter(curvatures) );
  
}
Beispiel #3
0
/**
 * Test 
 *
 */
bool testFP(string filename)
{


  trace.info() << endl;
  trace.info() << "Reading GridCurve from " << filename << endl;
  
  ifstream instream; // input stream
  instream.open (filename.c_str(), ifstream::in);

  //range of points
  typedef int Coordinate; 
  typedef KhalimskySpaceND<2,Coordinate> Kspace; //space
  GridCurve<Kspace> c; //building grid curve
  c.initFromVectorStream(instream);
  typedef GridCurve<Kspace >::PointsRange Range;//range
  Range r = c.getPointsRange();//building range

  typedef Range::ConstIterator ConstIterator;//constIterator

  //faithful polyon
  trace.info() << "Building FP (process digital curve as"; 
  trace.info() << ( (c.isClosed())?"closed":"open" ) << ")" << endl;

  bool res = true; 
  if (c.isClosed())
    {
      typedef FP<Range::ConstCirculator,Coordinate,4> FP; 
      FP theFP( r.c(), r.c() );
      res = theFP.isValid();       
    }
  else 
    {
      typedef FP<Range::ConstIterator,Coordinate,4> FP; 
      FP theFP( r.begin(), r.end() );
      res = theFP.isValid(); 
    }
  return res;
 
}
/**
 * Applying test on a given data file 
 *
 */
bool testEval(string filename)
{

  trace.info() << endl;
  trace.info() << "Reading GridCurve from " << filename << endl;
  
  ifstream instream; // input stream
  instream.open (filename.c_str(), ifstream::in);
  typedef KhalimskySpaceND<2> Kspace; //space
  GridCurve<Kspace> c; //building grid curve
  c.initFromVectorStream(instream);
  typedef GridCurve<Kspace >::PointsRange Range;//range
  Range r = c.getPointsRange();//building range

  trace.info() << "Building Estimator (process range as"; 
  trace.info() << ( (c.isClosed())?"closed":"open" ) << ")" << endl;

  if (c.isClosed())
    return test(r.c(), r.c()); 
  else 
    return test(r.begin(), r.end()); 

}
bool testRange(const Range &aRange)
{

  trace.info() << endl;
  trace.info() << "Testing Range (" << aRange.size() << " elts)" << endl;
  
  typedef typename IteratorCirculatorTraits<typename Range::ConstIterator>::Value Value; 
  std::vector<Value> v1,v2,v3,v4; 
  
{
  trace.info() << "Forward" << endl;
  typename Range::ConstIterator i = aRange.begin();
  typename Range::ConstIterator end = aRange.end();
  for ( ; i != end; ++i) {
    //cout << *i << endl;
    v1.push_back(*i); 
  }
}
{
  trace.info() << "Backward" << endl;
  typename Range::ConstReverseIterator i = aRange.rbegin();
  typename Range::ConstReverseIterator end = aRange.rend();
  for ( ; i != end; ++i) {
    //cout << *i << endl;
    v2.push_back(*i); 
  }
}
{
  trace.info() << "Circulator" << endl;
  typename Range::ConstCirculator c = aRange.c();
  typename Range::ConstCirculator cend = aRange.c();
  if (isNotEmpty(c,cend)) 
  {
    do 
    {
      //cout << *c << endl;
      v3.push_back(*c);
      c++;
    } while (c!=cend); 
  }
}

{
  trace.info() << "Reverse Circulator" << endl;
  typename Range::ConstReverseCirculator c = aRange.rc();
  typename Range::ConstReverseCirculator cend = aRange.rc();
  if (isNotEmpty(c,cend)) 
  {
    do 
    {
      //cout << *c << endl;
      v4.push_back(*c);
      c++;
    } while (c!=cend); 
  }
}

  return ( std::equal(v1.begin(),v1.end(),v3.begin())
          && std::equal(v2.begin(),v2.end(),v4.begin())
          && std::equal(v1.begin(),v1.end(),v2.rbegin())
          && std::equal(v3.begin(),v3.end(),v4.rbegin()) );
}
int main( int argc, char** argv )
{

    // parse command line ----------------------------------------------
    po::options_description general_opt("Allowed options are: ");
    general_opt.add_options()
    ("help,h", "display this message")
    ("input,i", po::value<std::string>(), "input FreemanChain file name")
    ("SDP", po::value<std::string>(), "Import a contour as a Sequence of Discrete Points (SDP format)")
    ("SFP", po::value<std::string>(), "Import a contour as a Sequence of Floating Points (SFP format)")
    ("drawContourPoint", po::value<double>(), "<size> display contour points as disk of radius <size>")
    ("fillContour", "fill the contours with default color (gray)")
    ("lineWidth", po::value<double>()->default_value(1.0), "Define the linewidth of the contour (SDP format)")
    ("drawPointOfIndex", po::value<int>(), "<index> Draw the contour point of index <index> (default 0) ")
    ("pointSize", po::value<double>()->default_value(2.0), "<size> Set the display point size of the point displayed by drawPointofIndex option (default 2.0) ")
    ("noXFIGHeader", " to exclude xfig header in the resulting output stream (no effect with option -outputFile).")
    ("withProcessing", po::value<std::string>(), "Processing (used only when the input is a Freeman chain (--input)):\n\t DSS segmentation {DSS}\n\t  Maximal segments {MS}\n\t Faithful Polygon {FP}\n\t Minimum Length Polygon {MLP}")
    ("outputFile,o", po::value<std::string>(), " <filename> save output file automatically according the file format extension.")
    ("outputStreamEPS", " specify eps for output stream format.")
    ("outputStreamSVG", " specify svg for output stream format.")
    ("outputStreamFIG", " specify fig for output stream format.")
    ("invertYaxis", " invertYaxis invert the Y axis for display contours (used only with --SDP)")

    ("backgroundImage", po::value<std::string>(), "backgroundImage <filename> : display image as background ")
    ("alphaBG", po::value<double>(), "alphaBG <value> 0-1.0 to display the background image in transparency (default 1.0), (transparency works only if cairo is available)")

    ("scale", po::value<double>(), "scale <value> 1: normal; >1 : larger ; <1 lower resolutions  )");



    bool parseOK=true;
    po::variables_map vm;
    try {
        po::store(po::parse_command_line(argc, argv, general_opt), vm);
    } catch(const std::exception& ex) {
        parseOK=false;
        trace.info()<< "Error checking program options: "<< ex.what()<< std::endl;
    }

    po::notify(vm);
    if(!parseOK||vm.count("help")||argc<=1 || (!(vm.count("input")) && !(vm.count("SDP")) && !(vm.count("SFP"))&&
            !(vm.count("backgroundImage")) ) )
    {
        trace.info()<< "Display discrete contours. " <<std::endl << "Basic usage: "<<std::endl
                    << "\t displayContours [options] --input  <fileName>  "<<std::endl
                    << general_opt << "\n";
        return 0;
    }



    double lineWidth=  vm["lineWidth"].as<double>();
    bool filled = vm.count("fillContour");
    double scale=1.0;
    if(vm.count("scale")) {
        scale = vm["scale"].as<double>();
    }

    Board2D aBoard;
    aBoard.setUnit (0.05*scale, LibBoard::Board::UCentimeter);





    double alpha=1.0;
    if(vm.count("alphaBG")) {
        alpha = vm["alphaBG"].as<double>();
    }

    if(vm.count("backgroundImage")) {
        std::string imageName = vm["backgroundImage"].as<std::string>();
        typedef ImageSelector<Z2i::Domain, unsigned char>::Type Image;
        Image img = DGtal::GenericReader<Image>::import( imageName );
        Z2i::Point ptInf = img.domain().lowerBound();
        Z2i::Point ptSup = img.domain().upperBound();
        unsigned int width = abs(ptSup[0]-ptInf[0]+1);
        unsigned int height = abs(ptSup[1]-ptInf[1]+1);

        aBoard.drawImage(imageName, 0-0.5,height-0.5, width, height, -1, alpha );
    }




    if(vm.count("input")) {
        std::string fileName = vm["input"].as<std::string>();
        std::vector< FreemanChain<int> > vectFc =  PointListReader< Z2i::Point>:: getFreemanChainsFromFile<int> (fileName);
        aBoard << CustomStyle( vectFc.at(0).className(),
                               new CustomColors( Color::Red  ,  filled?  Color::Gray: Color::None  ) );
        aBoard.setLineWidth (lineWidth);
        for(unsigned int i=0; i<vectFc.size(); i++) {
            aBoard <<  vectFc.at(i) ;
            if(vm.count("drawPointOfIndex")) {
                int index = vm["drawPointOfIndex"].as<int>();
                double size = vm["pointSize"].as<double>();
                aBoard.setPenColor(Color::Blue);

                aBoard.fillCircle((double)(vectFc.at(i).getPoint(index)[0]), (double)(vectFc.at(i).getPoint(index)[1]), size);
            }

            if(vm.count("withProcessing")) {
                std::string processingName = vm["withProcessing"].as<std::string>();

                std::vector<Z2i::Point> vPts(vectFc.at(i).size()+1);
                copy ( vectFc.at(i).begin(), vectFc.at(i).end(), vPts.begin() );
                bool isClosed;
                if ( vPts.at(0) == vPts.at(vPts.size()-1) ) {
                    isClosed = true;
                    vPts.pop_back();
                } else isClosed = false;

                if (processingName == "DSS") {

                    typedef ArithmeticalDSSComputer<std::vector<Z2i::Point>::iterator,int,4> DSS4;
                    typedef GreedySegmentation<DSS4> Decomposition4;

                    DSS4 computer;
                    Decomposition4 theDecomposition( vPts.begin(),vPts.end(),computer );

                    //for each segment
                    std::string className;
                    for ( Decomposition4::SegmentComputerIterator it = theDecomposition.begin();
                            it != theDecomposition.end(); ++it )
                    {
                        DSS4::Primitive segment(it->primitive());

                        aBoard << SetMode( segment.className(), "BoundingBox" );
                        className = segment.className() + "/BoundingBox";
                        aBoard << CustomStyle( className,
                                               new CustomPenColor( DGtal::Color::Gray ) );
                        aBoard << segment; // draw each segment
                    }

                } else if (processingName == "MS") {

                    typedef ArithmeticalDSSComputer<std::vector<Z2i::Point>::iterator,int,4> DSS4;
                    typedef SaturatedSegmentation<DSS4> Decomposition4;

                    //Segmentation
                    DSS4 computer;
                    Decomposition4 theDecomposition( vPts.begin(),vPts.end(),computer );

                    //for each segment
                    std::string className;
                    for ( Decomposition4::SegmentComputerIterator it = theDecomposition.begin();
                            it != theDecomposition.end(); ++it )
                    {
                        DSS4::Primitive segment(it->primitive());

                        aBoard << SetMode( segment.className(), "BoundingBox" );
                        className = segment.className() + "/BoundingBox";
                        aBoard << CustomStyle( className,
                                               new CustomPenColor( DGtal::Color::Gray ) );
                        aBoard << segment; // draw each segment
                    }

                } else if (processingName == "FP") {

                    typedef FP<std::vector<Z2i::Point>::iterator,int,4> FP;
                    FP theFP( vPts.begin(),vPts.end() );
                    aBoard << CustomStyle( theFP.className(),
                                           new CustomPenColor( DGtal::Color::Black ) );
                    aBoard << theFP;


                } else if (processingName == "MLP") {

                    typedef FP<std::vector<Z2i::Point>::iterator,int,4> FP;
                    FP theFP( vPts.begin(),vPts.end() );

                    std::vector<FP::RealPoint> v( theFP.size() );
                    theFP.copyMLP( v.begin() );

                    //polyline to draw
                    std::vector<LibBoard::Point> polyline;
                    std::vector<FP::RealPoint>::const_iterator it = v.begin();
                    for ( ; it != v.end(); ++it) {
                        FP::RealPoint p = (*it);
                        polyline.push_back(LibBoard::Point(p[0],p[1]));
                    }
                    if (isClosed) {
                        FP::RealPoint p = (*v.begin());
                        polyline.push_back(LibBoard::Point(p[0],p[1]));
                    }
                    aBoard.setPenColor(DGtal::Color::Black);
                    aBoard.drawPolyline(polyline);

                } else if (processingName == "MDCA") {
                    typedef KhalimskySpaceND<2,int> KSpace;
                    typedef GridCurve<KSpace> Curve;
                    Curve curve; //grid curve
                    curve.initFromPointsVector( vPts );
                    typedef Curve::IncidentPointsRange Range; //range
                    Range r = curve.getIncidentPointsRange(); //range
                    typedef Range::ConstCirculator ConstCirculator; //iterator
                    typedef StabbingCircleComputer<ConstCirculator> SegmentComputer; //segment computer
                    //typedef GeometricalDCA<ConstIterator> SegmentComputer; //segment computer
                    typedef SaturatedSegmentation<SegmentComputer> Segmentation;
                    //Segmentation theSegmentation( r.begin(), r.end(), SegmentComputer() );
                    Segmentation theSegmentation( r.c(), r.c(), SegmentComputer() );
                    theSegmentation.setMode("Last");
                    // board << curve;
                    Segmentation::SegmentComputerIterator it = theSegmentation.begin();
                    Segmentation::SegmentComputerIterator itEnd = theSegmentation.end();
                    Board2D otherBoard;
                    otherBoard.setPenColor(DGtal::Color::Black);
                    otherBoard << curve;
                    for ( ; it != itEnd; ++it ) {
                        aBoard << SetMode(SegmentComputer().className(), "") << (*it);
                        otherBoard << SetMode(SegmentComputer().className(), "") << (*it);
                    }
                    otherBoard.saveSVG("mdca.svg", Board2D::BoundingBox, 5000 );
                }
            }

        }



    }



    if(vm.count("SDP") || vm.count("SFP")) {
        bool drawPoints= vm.count("drawContourPoint");
        bool invertYaxis = vm.count("invertYaxis");
        double pointSize=1.0;
        if(drawPoints) {
            pointSize = vm["drawContourPoint"].as<double>();
        }
        std::vector<LibBoard::Point> contourPt;
        if(vm.count("SDP")) {
            std::string fileName = vm["SDP"].as<std::string>();
            std::vector< Z2i::Point >  contour =
                PointListReader< Z2i::Point >::getPointsFromFile(fileName);
            for(unsigned int j=0; j<contour.size(); j++) {
                LibBoard::Point pt((double)(contour.at(j)[0]),
                                   (invertYaxis? (double)(-contour.at(j)[1]+contour.at(0)[1]):(double)(contour.at(j)[1])));
                contourPt.push_back(pt);
                if(drawPoints) {
                    aBoard.fillCircle(pt.x, pt.y, pointSize);
                }
            }
        }

        if(vm.count("SFP")) {
            std::string fileName = vm["SFP"].as<std::string>();
            std::vector< PointVector<2,double>  >  contour =
                PointListReader<  PointVector<2,double>  >::getPointsFromFile(fileName);
            for(unsigned int j=0; j<contour.size(); j++) {
                LibBoard::Point pt((double)(contour.at(j)[0]),
                                   (invertYaxis? (double)(-contour.at(j)[1]+contour.at(0)[1]):(double)(contour.at(j)[1])));
                contourPt.push_back(pt);
                if(drawPoints) {
                    aBoard.fillCircle(pt.x, pt.y, pointSize);
                }
            }

        }


        aBoard.setPenColor(Color::Red);
        aBoard.setFillColor(Color::Gray);
        aBoard.setLineStyle (LibBoard::Shape::SolidStyle );
        aBoard.setLineWidth (lineWidth);
        if(!filled) {
            aBoard.drawPolyline(contourPt);
        } else {
            aBoard.fillPolyline(contourPt);
        }
        if(vm.count("drawPointOfIndex")) {
            int index = vm["drawPointOfIndex"].as<int>();
            double size = vm["pointSize"].as<double>();
            aBoard.fillCircle((double)(contourPt.at(index).x), (double)(contourPt.at(index).y), size);
        }



    }




    if(vm.count("outputFile")) {
        std::string outputFileName= vm["outputFile"].as<std::string>();
        std::string extension = outputFileName.substr(outputFileName.find_last_of(".") + 1);

        if(extension=="svg") {
            aBoard.saveSVG(outputFileName.c_str());
        }
#ifdef WITH_CAIRO
        else if (extension=="eps") {
            aBoard.saveCairo(outputFileName.c_str(),Board2D::CairoEPS );
        } else if (extension=="pdf") {
            aBoard.saveCairo(outputFileName.c_str(),Board2D::CairoPDF );
        } else if (extension=="png") {
            aBoard.saveCairo(outputFileName.c_str(),Board2D::CairoPNG );
        }
#endif
        else if(extension=="eps") {
            aBoard.saveEPS(outputFileName.c_str());
        } else if(extension=="fig") {
            aBoard.saveFIG(outputFileName.c_str(),LibBoard::Board::BoundingBox, 10.0, !vm.count("noXFIGHeader") );
        }
    }

    if (vm.count("outputStreamSVG")) {
        aBoard.saveSVG(std::cout);
    } else if (vm.count("outputStreamFIG")) {
        aBoard.saveFIG(std::cout, LibBoard::Board::BoundingBox, 10.0,  !vm.count("noXFIGHeader"));
    } else if (vm.count("outputStreamEPS")) {
        aBoard.saveEPS(std::cout);
    }

}
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;
}