int main( ) { trace.beginBlock ( "Example dgtalboard-5-greedy-dss" ); typedef FreemanChain<int> Contour4; typedef ArithmeticalDSSComputer<Contour4::ConstIterator,int,4> DSS4; typedef GreedySegmentation<DSS4> Decomposition4; // A Freeman chain code is a string composed by the coordinates of the first pixel, and the list of elementary displacements. std::stringstream ss(stringstream::in | stringstream::out); ss << "31 16 11121212121212212121212212122122222322323233323333333323333323303330330030300000100010010010001000101010101111" << endl; // Construct the Freeman chain Contour4 theContour( ss ); // Segmentation Decomposition4 theDecomposition( theContour.begin(),theContour.end(),DSS4() ); // Draw the domain and the contour Point p1( 0, 0 ); Point p2( 31, 31 ); Domain domain( p1, p2 ); Board2D aBoard; aBoard << SetMode( domain.className(), "Grid" ) << domain << SetMode( "PointVector", "Grid" ) << theContour; // Draw each segment aBoard << SetMode( "ArithmeticalDSS", "BoundingBox" ); string className = "ArithmeticalDSS/BoundingBox"; for ( Decomposition4::SegmentComputerIterator it = theDecomposition.begin(), itEnd = theDecomposition.begin(); it != itEnd; ++it ) { aBoard << CustomStyle( className, new CustomPenColor( Color::Blue ) ) << it->primitive(); } aBoard.saveSVG("dgtalboard-5-greedy-dss.svg"); aBoard.saveSVG("dgtalboard-5-greedy-dss.eps"); trace.endBlock(); return 0; }
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); } }