bool testDigitalSetBoardSnippet() { typedef SpaceND<2> Z2; typedef HyperRectDomain<Z2> Domain; typedef Z2::Point Point; Point p1( -10, -10 ); Point p2( 10, 10 ); Domain domain( p1, p2 ); typedef DigitalSetSelector < Domain, BIG_DS + HIGH_ITER_DS + HIGH_BEL_DS >::Type SpecificSet; BOOST_CONCEPT_ASSERT(( concepts::CDigitalSet< SpecificSet > )); SpecificSet mySet( domain ); Point c( 0, 0 ); mySet.insert( c ); Point d( 5, 2 ); mySet.insert( d ); Point e( 1, -3 ); mySet.insert( e ); Board2D board; board.setUnit(LibBoard::Board::UCentimeter); board << mySet; board.saveSVG("myset-export.svg"); board.clear(); board.setUnit(LibBoard::Board::UCentimeter); board << SetMode( domain.className(), "Grid" ) << domain << mySet; board.saveSVG("simpleSet-grid.svg"); board.clear(); board.setUnit(LibBoard::Board::UCentimeter); board << SetMode( domain.className(), "Paving" ) << domain; board << mySet; board.saveSVG("simpleSet-paving.svg"); board.clear(); board.setUnit(LibBoard::Board::UCentimeter); board << CustomStyle( mySet.className(), new MyDomainStyleCustomRed ); board << mySet; board.saveSVG("simpleSet-color.svg"); return true; }
bool testBadKeySizes() { typedef SpaceND<2> SpaceType; typedef HyperRectDomain<SpaceType> TDomain; typedef TDomain::Point Point; Board2D board; typedef HueShadeColorMap<unsigned char,2> HueTwice; board.setUnit(Board2D::UCentimeter); //Default image selector = STLVector typedef ImageContainerByHashTree<TDomain, char> Image; Point d(128,128); trace.beginBlock ( "Test maximal depth > number of bits of the HashKey type" ); Image myImage ( 3, 80, 0 ); trace.info() << myImage; trace.endBlock(); trace.beginBlock ( "Test morton hash size > number of bits of the HashKey type" ); ///This should raise an ASSERT abort if uncommented // Image myImage2 ( 80, 8, 0 ); //trace.info() << myImage2; trace.endBlock(); //Default image selector = STLVector typedef ImageContainerByHashTree<TDomain, unsigned int, DGtal::uint32_t> Image2; trace.beginBlock ( "Changing the HashKey type" ); Image2 myImage3( 3, 80, 0 ); trace.info() << myImage3; trace.endBlock(); return true; }
void draw( const TImage aImg, const double& aMaxValue, std::string aBasename) { typedef typename TImage::Domain::ConstIterator ConstIteratorOnPoints; typedef typename TImage::Domain::Point Point; HueShadeColorMap<double, 2> colorMap(0,aMaxValue); Board2D b; b.setUnit ( LibBoard::Board::UCentimeter ); for (ConstIteratorOnPoints it = aImg.domain().begin(), itEnd = aImg.domain().end(); it != itEnd; ++it) { Point p = *it; b << CustomStyle( p.className(), new CustomFillColor( colorMap( aImg(p) ) ) ); b << p; } { std::stringstream s; s << aBasename << ".eps"; b.saveEPS(s.str().c_str()); } #ifdef WITH_CAIRO { std::stringstream s; s << aBasename << ".png"; b.saveCairo(s.str().c_str(), Board2D::CairoPNG); } #endif }
/** * Display * */ bool testDrawGridCurve(const string &filename) { GridCurve<KhalimskySpaceND<2> > c; //grid curve trace.info() << endl; trace.info() << "Displaying GridCurve " << endl; //reading grid curve fstream inputStream; inputStream.open (filename.c_str(), ios::in); c.initFromVectorStream(inputStream); inputStream.close(); //displaying it Board2D aBoard; aBoard.setUnit(Board2D::UCentimeter); aBoard << c; aBoard.saveEPS( "GridCurve.eps", Board2D::BoundingBox, 5000 ); #ifdef WITH_CAIRO aBoard.saveCairo("GridCurve-cairo.pdf", Board2D::CairoPDF, Board2D::BoundingBox, 5000); #endif return true; }
bool testDrawRange(const Range &aRange, const string &aName, const string& aDomainMode) { std::stringstream s; s << aName << "Range.eps"; trace.info() << endl; trace.info() << "Drawing " << s.str() << " (" << aRange.size() << " elts)" << endl; //board Board2D aBoard; aBoard.setUnit(Board2D::UCentimeter); //displaying domain PointVector<2,int> low(-1,-1); PointVector<2,int> up(3,3); if (aDomainMode == "Paving") up = PointVector<2,int>(4,4); HyperRectDomain< SpaceND<2,int> > aDomain( low,up ); aBoard << SetMode(aDomain.className(), aDomainMode) << aDomain; //displaying range aBoard << aRange; //save aBoard.saveEPS( s.str().c_str(), Board2D::BoundingBox, 5000 ); return true; }
bool testDigitalSetBoardSnippet() { typedef SpaceND<2> Z2; typedef HyperRectDomain<Z2> Domain; typedef Z2::Point Point; Point p1( -10, -10 ); Point p2( 10, 10 ); Domain domain( p1, p2 ); typedef DigitalSetSelector < Domain, BIG_DS + HIGH_ITER_DS + HIGH_BEL_DS >::Type SpecificSet; SpecificSet mySet( domain ); Point c( 0, 0 ); mySet.insert( c ); Point d( 5, 2 ); mySet.insert( d ); Point e( 1, -3 ); mySet.insert( e ); Board2D board; board.setUnit(Board::UCentimeter); board << mySet; board.saveSVG("myset-export.svg"); board.clear(); board.setUnit(Board::UCentimeter); board << DrawDomainGrid() << domain << mySet; board.saveSVG("simpleSet-grid.svg"); board.clear(); board.setUnit(Board::UCentimeter); board << DrawDomainPaving() << domain; board << mySet; board.saveSVG("simpleSet-paving.svg"); board.clear(); board.setUnit(Board::UCentimeter); board << CustomStyle( mySet.styleName(), new MyDomainStyleCustomRed ); board << mySet; board.saveSVG("simpleSet-color.svg"); return true; }
/** * Test for 8-connected points * */ bool testDSS8drawing() { typedef PointVector<2,int> Point; typedef std::vector<Point>::iterator Iterator; typedef ArithmeticalDSS<Iterator,int,8> DSS8; std::vector<Point> boundary; boundary.push_back(Point(0,0)); boundary.push_back(Point(1,1)); boundary.push_back(Point(2,1)); boundary.push_back(Point(3,2)); boundary.push_back(Point(4,2)); boundary.push_back(Point(5,2)); boundary.push_back(Point(6,3)); boundary.push_back(Point(6,4)); // Good Initialisation trace.beginBlock("Add points while it is possible and draw the result"); DSS8 theDSS8; theDSS8.init( boundary.begin() ); trace.info() << theDSS8 << " " << theDSS8.isValid() << std::endl; { while ( (theDSS8.end()!=boundary.end()) &&(theDSS8.extendForward()) ) {} trace.info() << theDSS8 << " " << theDSS8.isValid() << std::endl; HyperRectDomain< SpaceND<2,int> > domain( Point(0,0), Point(10,10) ); Board2D board; board.setUnit(Board::UCentimeter); board << SetMode(domain.className(), "Paving") << domain; board << SetMode("PointVector", "Both"); board << SetMode(theDSS8.className(), "Points") << theDSS8; board << SetMode(theDSS8.className(), "BoundingBox") << theDSS8; board.saveSVG("DSS8.svg"); } trace.endBlock(); return true; }
/** * Simple 3d distance transform * and slice display */ bool testDisplayDT3d(int size, int area, double distance) { static const DGtal::Dimension dimension = 3; //Domain typedef HyperRectDomain< SpaceND<dimension, int> > Domain; typedef Domain::Point Point; Domain d(Point::diagonal(-size), Point::diagonal(size)); DomainPredicate<Domain> dp(d); //Image and set typedef ImageContainerBySTLMap<Domain,double> Image; Image map( d, 0.0 ); map.setValue( Point::diagonal(0), 0.0 ); typedef DigitalSetFromMap<Image> Set; Set set(map); //computation trace.beginBlock ( "Display 3d FMM results " ); typedef FMM<Image, Set, DomainPredicate<Domain> > FMM; FMM fmm(map, set, dp, area, distance); fmm.compute(); trace.info() << fmm << std::endl; trace.endBlock(); { //display HueShadeColorMap<unsigned char, 2> colorMap(0,2*size); Board2D b; b.setUnit ( LibBoard::Board::UCentimeter ); Domain::ConstIterator it = d.begin(); for ( ; it != d.end(); ++it) { Point p3 = *it; if (p3[2] == 0) { PointVector<2,Point::Coordinate> p2(p3[0], p3[1]); b << CustomStyle( p2.className(), new CustomFillColor( colorMap(map(p3)) ) ) << p2; } } std::stringstream s; s << "DTFrom3dPt-" << size << "-" << area << "-" << distance << ".eps"; b.saveEPS(s.str().c_str()); } return fmm.isValid(); }
/** * Test for 4-connected points * */ bool testDSS4drawing() { typedef PointVector<2,int> Point; typedef std::vector<Point>::iterator Iterator; typedef ArithmeticalDSS<Iterator,int,4> DSS4; std::vector<Point> contour; contour.push_back(Point(0,0)); contour.push_back(Point(1,0)); contour.push_back(Point(1,1)); contour.push_back(Point(2,1)); contour.push_back(Point(3,1)); contour.push_back(Point(3,2)); contour.push_back(Point(4,2)); contour.push_back(Point(5,2)); contour.push_back(Point(6,2)); contour.push_back(Point(6,3)); contour.push_back(Point(6,4)); // Adding step trace.beginBlock("Add points while it is possible and draw the result"); DSS4 theDSS4; theDSS4.init( contour.begin() ); trace.info() << theDSS4 << " " << theDSS4.isValid() << std::endl; while ( (theDSS4.end() != contour.end()) &&(theDSS4.extendForward()) ) {} trace.info() << theDSS4 << " " << theDSS4.isValid() << std::endl; HyperRectDomain< SpaceND<2,int> > domain( Point(0,0), Point(10,10) ); Board2D board; board.setUnit(Board::UCentimeter); board << SetMode(domain.className(), "Grid") << domain; board << SetMode("PointVector", "Grid"); board << SetMode(theDSS4.className(), "Points") << theDSS4; board << SetMode(theDSS4.className(), "BoundingBox") << theDSS4; board.saveSVG("DSS4.svg"); trace.endBlock(); return true; }
/** * Example of a test. To be completed. * */ bool testPNMWriter() { trace.beginBlock ( "Testing block ..." ); typedef SpaceND<2> TSpace; typedef TSpace::Point Point; typedef HyperRectDomain<TSpace> Domain; typedef HueShadeColorMap<unsigned char> Hue; typedef HueShadeColorMap<unsigned char,2> HueTwice; typedef GrayscaleColorMap<unsigned char> Gray; // Gradient using the "Jet" preset. typedef GradientColorMap<unsigned char, CMAP_JET > Jet; // Gradient from black to red. const int BlackColor = DGTAL_RGB2INT(0,0,0); const int RedColor = DGTAL_RGB2INT(255,0,0); typedef GradientColorMap< unsigned char, CMAP_CUSTOM, BlackColor, RedColor > RedShade1; // Gradient from black to red, using a ColorBrightnessColorMap. typedef ColorBrightnessColorMap< unsigned char, RedColor > RedShade2; Point a ( 1, 1); Point b ( 16, 16); typedef ImageSelector<Domain, unsigned char>::Type Image; Image image(Domain(a,b)); for(unsigned int i=0 ; i < 256; i++) image[i] = i; PPMWriter<Image,Hue>::exportPPM("export-hue.ppm",image, Hue(0,255) ); PPMWriter<Image,HueTwice>::exportPPM("export-hue-twice.ppm",image,HueTwice(0,255)); PGMWriter<Image>::exportPGM("export-hue-twice.pgm",image); PPMWriter<Image,Gray>::exportPPM("export-gray.ppm",image, Gray(0,255)); PPMWriter<Image,Jet>::exportPPM("export-jet.ppm",image,Jet(0,255)); PPMWriter<Image,RedShade1>::exportPPM("export-red1.ppm",image,RedShade1(0,255)); PPMWriter<Image,RedShade2>::exportPPM("export-red2.ppm",image,RedShade2(0,255)); //TestingFunctor typedef DGtal::functors::Composer< Jet, functors::RedChannel, unsigned char> RedFunctor; RedFunctor redFunctor( Jet(0,255), functors::RedChannel() ) ; PGMWriter<Image, RedFunctor>::exportPGM("export-jet-red.pgm",image, redFunctor); //test Raw export RawWriter<Image>::exportRaw8("export-hue-twice.raw",image); //test Image export with libboard Board2D board; board.setUnit(LibBoard::Board::UCentimeter); Display2DFactory::drawImage<HueTwice>(board, image, (unsigned char)0, (unsigned char)255); board.saveSVG("export-hue-twice.svg"); trace.endBlock(); return true; }
/** * Test for the tangential cover of * 4-connected digital curves * */ bool testCover4() { typedef int Coordinate; typedef PointVector<2,Coordinate> Point; typedef FreemanChain<Coordinate> ContourType; typedef ArithmeticalDSS<ContourType::ConstIterator,Coordinate,4> PrimitiveType; typedef MaximalSegments<PrimitiveType> DecompositionType; std::string filename = testPath + "samples/france.fc"; std::cout << filename << std::endl; std::fstream fst; fst.open (filename.c_str(), std::ios::in); ContourType theContour(fst); //Segmentation trace.beginBlock("Tangential cover of 4-connected digital curves"); PrimitiveType primitive; DecompositionType theDecomposition(theContour.begin(), theContour.end(), primitive, false); // Draw the grid Board2D aBoard; aBoard.setUnit(Board::UCentimeter); aBoard << SetMode("PointVector", "Grid") << theContour; //for each segment unsigned int compteur = 0; DecompositionType::SegmentIterator i = theDecomposition.begin(); for ( ; i != theDecomposition.end(); ++i) { compteur++; PrimitiveType segment(*i); trace.info() << segment << std::endl; //standard output aBoard << SetMode( "ArithmeticalDSS", "BoundingBox" ) << segment; // draw each segment } aBoard.saveEPS("segmentationDSS4.eps"); trace.info() << "# segments" << compteur << std::endl; trace.endBlock(); return true; }
bool testSmartDSS() { typedef PointVector<2,int> Point; typedef std::vector<Point>::iterator Iterator; typedef ArithmeticalDSS<Iterator,int,4> DSS4; std::vector<Point> contour; contour.push_back(Point(0,0)); contour.push_back(Point(1,0)); contour.push_back(Point(1,1)); contour.push_back(Point(2,1)); contour.push_back(Point(3,1)); contour.push_back(Point(3,2)); contour.push_back(Point(4,2)); contour.push_back(Point(5,2)); contour.push_back(Point(6,2)); contour.push_back(Point(6,3)); contour.push_back(Point(6,4)); // Adding step trace.beginBlock("extension"); DSS4 s; s.init( contour.begin() ); while ( (s.end()!=contour.end()) &&(s.extend()) ) {} HyperRectDomain< SpaceND<2,int> > domain( Point(0,0), Point(10,10) ); Board2D board; board.setUnit(Board::UCentimeter); board << SetMode(domain.styleName(), "Grid") << domain; board << SetMode("PointVector", "Grid"); board << SetMode(s.styleName(), "Points") << s; board << SetMode(s.styleName(), "BoundingBox") << s; board.saveEPS("DSS.eps"); trace.endBlock(); return true; }
/** * Test for the segmentation of * one DSS into DSSs * */ bool testOneDSS() { typedef int Coordinate; typedef PointVector<2,Coordinate> Point; typedef ArithmeticalDSS<std::vector<Point>::iterator,Coordinate,8> PrimitiveType; typedef MaximalSegments<PrimitiveType> DecompositionType; std::vector<Point> curve; curve.push_back(Point(0,0)); curve.push_back(Point(1,1)); curve.push_back(Point(2,1)); curve.push_back(Point(3,2)); curve.push_back(Point(4,2)); curve.push_back(Point(5,2)); curve.push_back(Point(6,3)); curve.push_back(Point(7,3)); //Segmentation trace.beginBlock("Segmentation of one DSS"); PrimitiveType primitive; DecompositionType theDecomposition(curve.begin(), curve.end(), primitive, false); // Draw the pixels Board2D aBoard; aBoard.setUnit(Board::UCentimeter); aBoard << SetMode("PointVector", "Both"); for (std::vector<Point>::iterator it = curve.begin(); it != curve.end(); ++it) { aBoard << (*it); } //for each segment unsigned int compteur = 0; DecompositionType::SegmentIterator i = theDecomposition.begin(); for ( ; i != theDecomposition.end(); ++i) { ++compteur; PrimitiveType segment(*i); trace.info() << segment << std::endl; //standard output aBoard << SetMode( "ArithmeticalDSS", "BoundingBox" ) << segment; // draw each segment } aBoard.saveSVG("oneDSS.svg"); trace.endBlock(); return (compteur==1); }
void draw( const TIterator& itb, const TIterator& ite, const int& size, std::string basename) { typedef typename std::iterator_traits<TIterator>::value_type Pair; typedef typename Pair::first_type Point; HueShadeColorMap<unsigned char, 2> colorMap(0,3*size); Board2D b; b.setUnit ( LibBoard::Board::UCentimeter ); TIterator it = itb; for ( ; it != ite; ++it) { Point p = it->first; b << CustomStyle( p.className(), new CustomFillColor( colorMap( it->second) ) ); b << p; } std::stringstream s; s << basename << ".eps"; b.saveEPS(s.str().c_str()); }
/** * testDisplay * */ bool testDisplay() { typedef FreemanChain<int> FreemanChain; //typedef FreemanChain::Point Point; //typedef FreemanChain::Vector Vector; //typedef FreemanChain::ConstIterator Iterator; //typedef std::vector<unsigned int> numVector; Board2D aBoard; aBoard.setUnit(Board::UCentimeter); fstream fst; fst.open ((testPath + "samples/contourS.fc").c_str() , ios::in); FreemanChain fc(fst); aBoard.setPenColor(Color::Red); //aBoard << DrawPavingPixel(); aBoard << fc; std::string filenameImage = testPath + "samples/contourS.png"; // ! only PNG with Cairo for the moment ! LibBoard::Image image( 0, 84, 185, 85, filenameImage, 20 ); image.shiftDepth(500); LibBoard::Board & board = aBoard; board << image; aBoard.saveSVG( "testDisplayFC.svg", Board::BoundingBox, 5000 ); aBoard.saveEPS( "testDisplayFC.eps", Board::BoundingBox, 5000 ); aBoard.saveFIG( "testDisplayFC.fig", Board::BoundingBox, 5000 ); #ifdef WITH_CAIRO aBoard.saveCairo("testDisplayFC-cairo.pdf", Board2D::CairoPDF, Board::BoundingBox, 5000); aBoard.saveCairo("testDisplayFC-cairo.png", Board2D::CairoPNG, Board::BoundingBox, 5000); aBoard.saveCairo("testDisplayFC-cairo.ps", Board2D::CairoPS, Board::BoundingBox, 5000); aBoard.saveCairo("testDisplayFC-cairo.svg", Board2D::CairoSVG, Board::BoundingBox, 5000); #endif return true; }
int main(int /*argc*/, char** /*argv*/) { //////////////////////////////////////// Board2D board; board.setUnit(Board2D::UCentimeter); board.drawArc(0.0, 1.0, 5.0, 0, M_PI/2.0, false); board.drawArc(0.0, 1.0, 4.0, 0, M_PI/2.0, true); board.drawArc(0.0, 1.0, 3.0, -0.5, M_PI/2.0-0.5, false); board.drawArc(0.0, 1.0, 2.0, 0.5, M_PI/2.0+0.5, false); board.saveEPS( "essai.eps" ); board.saveSVG( "essai.svg" ); board.saveTikZ( "essai.tikz" ); #ifdef WITH_CAIRO board.saveCairo("essai.pdf", Board2D::CairoPDF); #endif //////////////////////////////////////// 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") ("FreemanChain,f", po::value<std::string>(), "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>") ("lineWidth", po::value<double>()->default_value(1.0), "Define the linewidth of the contour (SDP format)") ("withProcessing", po::value<std::string>(), "Processing (used only with --FreemanChain):\n\t DSS segmentation {DSS}\n\t Maximal segments {MS}\n\t Faithful Polygon {FP}\n\t Minimum Length Polygon {MLP}") ("outputEPS", po::value<std::string>(), " <filename> specify eps format (default format output.eps)") ("outputSVG", po::value<std::string>(), " <filename> specify svg format.") ("outputFIG", po::value<std::string>(), " <filename> specify fig format.") #ifdef WITH_CAIRO ("outputPDF", po::value<std::string>(), "outputPDF <filename> specify pdf format. ") ("outputPNG", po::value<std::string>(), "outputPNG <filename> specify png format.") ("invertYaxis", " invertYaxis invert the Y axis for display contours (used only with --SDP)") #endif #ifdef WITH_MAGICK ("backgroundImage", po::value<std::string>(), "backgroundImage <filename> <alpha> : display image as background with transparency alpha (defaut 1) (transparency works only if cairo is available)") ("alphaBG", po::value<double>(), "alphaBG <value> 0-1.0 to display the background image in transparency (default 1.0)") #endif ("scale", po::value<double>(), "scale <value> 1: normal; >1 : larger ; <1 lower resolutions )"); po::variables_map vm; po::store(po::parse_command_line(argc, argv, general_opt), vm); po::notify(vm); if(vm.count("help")||argc<=1 || (not(vm.count("FreemanChain")) && not(vm.count("SDP")) && not(vm.count("SFP"))&& not(vm.count("backgroundImage")) ) ) { trace.info()<< "Display discrete contours. " <<std::endl << "Basic usage: "<<std::endl << "\t displayContours [options] --FreemanChain <fileName> --imageName image.png "<<std::endl << general_opt << "\n"; return 0; } double lineWidth= vm["lineWidth"].as<double>(); double scale=1.0; if(vm.count("scale")){ scale = vm["scale"].as<double>(); } Board2D aBoard; aBoard.setUnit (0.05*scale, LibBoard::Board::UCentimeter); #ifdef WITH_MAGICK double alpha=1.0; if(vm.count("alphaBG")){ alpha = vm["alphaBG"].as<double>(); } if(vm.count("backgroundImage")){ string imageName = vm["backgroundImage"].as<string>(); typedef ImageSelector<Z2i::Domain, unsigned char>::Type Image; DGtal::MagickReader<Image> reader; Image img = reader.importImage( imageName ); Z2i::Point ptInf = img.lowerBound(); Z2i::Point ptSup = img.upperBound(); unsigned int width = abs(ptSup.at(0)-ptInf.at(0)+1); unsigned int height = abs(ptSup.at(1)-ptInf.at(1)+1); aBoard.drawImage(imageName, 0-0.5,height-0.5, width, height, -1, alpha ); } #endif if(vm.count("FreemanChain")){ string fileName = vm["FreemanChain"].as<string>(); vector< FreemanChain<int> > vectFc = PointListReader< Z2i::Point>:: getFreemanChainsFromFile<int> (fileName); //aBoard << SetMode( vectFc.at(0).styleName(), "InterGrid" ); aBoard << CustomStyle( vectFc.at(0).styleName(), new CustomColors( Color::Red , Color::None ) ); for(unsigned int i=0; i<vectFc.size(); i++){ aBoard << vectFc.at(i) ; if(vm.count("withProcessing")){ std::string processingName = vm["withProcessing"].as<std::string>(); 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 ArithmeticalDSS<vector<Z2i::Point>::iterator,int,4> DSS4; typedef deprecated::GreedyDecomposition<DSS4> Decomposition4; //Segmentation DSS4 computer; Decomposition4 theDecomposition( vPts.begin(),vPts.end(),computer,isClosed ); //for each segment aBoard << SetMode( computer.styleName(), "BoundingBox" ); string styleName = computer.styleName() + "/BoundingBox"; for ( Decomposition4::SegmentIterator it = theDecomposition.begin(); it != theDecomposition.end(); ++it ) { DSS4 segment(*it); aBoard << CustomStyle( styleName, new CustomPenColor( DGtal::Color::Gray ) ); aBoard << segment; // draw each segment } } else if (processingName == "MS") { typedef ArithmeticalDSS<vector<Z2i::Point>::iterator,int,4> DSS4; typedef deprecated::MaximalSegments<DSS4> Decomposition4; //Segmentation DSS4 computer; Decomposition4 theDecomposition( vPts.begin(),vPts.end(),computer,isClosed ); //for each segment aBoard << SetMode( computer.styleName(), "BoundingBox" ); string styleName = computer.styleName() + "/BoundingBox"; for ( Decomposition4::SegmentIterator it = theDecomposition.begin(); it != theDecomposition.end(); ++it ) { DSS4 segment(*it); aBoard << CustomStyle( styleName, new CustomPenColor( DGtal::Color::Black ) ); aBoard << segment; // draw each segment } } else if (processingName == "FP") { typedef FP<vector<Z2i::Point>::iterator,int,4> FP; FP theFP( vPts.begin(),vPts.end(),isClosed ); aBoard << CustomStyle( theFP.styleName(), new CustomPenColor( DGtal::Color::Black ) ); aBoard << theFP; } else if (processingName == "MLP") { typedef FP<vector<Z2i::Point>::iterator,int,4> FP; FP theFP( vPts.begin(),vPts.end(),isClosed ); vector<FP::RealPoint> v( theFP.size() ); theFP.copyMLP( v.begin() ); //polyline to draw vector<LibBoard::Point> polyline; 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); } } } } 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>(); } vector<LibBoard::Point> contourPt; if(vm.count("SDP")){ string fileName = vm["SDP"].as<string>(); 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")){ string fileName = vm["SFP"].as<string>(); 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.setLineStyle (LibBoard::Shape::SolidStyle ); aBoard.setLineWidth (lineWidth); aBoard.drawPolyline(contourPt); } if (vm.count("outputSVG")){ string outputFileName= vm["outputSVG"].as<string>(); aBoard.saveSVG(outputFileName.c_str()); } else if (vm.count("outputFIG")){ string outputFileName= vm["outputFIG"].as<string>(); aBoard.saveFIG(outputFileName.c_str()); } else if (vm.count("outputEPS")){ string outputFileName= vm["outputEPS"].as<string>(); aBoard.saveEPS(outputFileName.c_str()); } #ifdef WITH_CAIRO else if (vm.count("outputEPS")){ string outputFileName= vm["outputEPS"].as<string>(); aBoard.saveCairo(outputFileName.c_str(),Board2D::CairoEPS ); } else if (vm.count("outputPDF")){ string outputFileName= vm["outputPDF"].as<string>(); aBoard.saveCairo(outputFileName.c_str(),Board2D::CairoPDF ); } else if (vm.count("outputPNG")){ string outputFileName= vm["outputPNG"].as<string>(); aBoard.saveCairo(outputFileName.c_str(),Board2D::CairoPNG ); } #endif else { //default output string outputFileName= "output.eps"; aBoard.saveEPS(outputFileName.c_str()); } }
bool testChessboard() { unsigned int nbok = 0; unsigned int nb = 0; trace.beginBlock ( "Testing DT computation with Infinity values at the first step" ); typedef SpaceND<2> TSpace; typedef TSpace::Point Point; typedef HyperRectDomain<TSpace> Domain; typedef HueShadeColorMap<DGtal::uint64_t, 2> Hue; typedef GrayscaleColorMap<DGtal::uint64_t> Gray; Point a (0, 0 ); Point b ( 128, 128 ); typedef ImageSelector<Domain, unsigned int>::Type Image; Image image ( a, b ); for ( Image::Iterator it = image.begin(), itend = image.end();it != itend; ++it) image.setValue ( it, 128 ); randomSeeds(image, 19, 0); typedef ImageSelector<Domain, long int>::Type ImageLong; //L_euc metric typedef DistanceTransformation<Image, 2> DT2; DT2 dt2; //L_infinity metric typedef DistanceTransformation<Image, 0> DT; DT dt; //L_1 metric typedef DistanceTransformation<Image, 1> DT1; DT1 dt1; dt.checkTypesValidity ( image ); DT::OutputImage result = dt.compute ( image ); DT1::OutputImage result1 = dt1.compute ( image ); DT2::OutputImage result2 = dt2.compute (image); DGtal::int64_t maxv = 0; for ( DT::OutputImage::Iterator it = result.begin(), itend = result.end();it != itend; ++it) if ( (*it) > maxv) maxv = (*it); DT::OutputImage::ConstIterator it = result.begin(); trace.warning() << result << "MaxV = " << maxv << endl; //We display the values on a 2D slice for (unsigned int y = 0; y < 16; y++) { for (unsigned int x = 0; x < 16; x++) { Point p(x, y); std::cout << std::setw(4) << result(p) << " "; } std::cout << std::endl; } trace.info()<< "Exporting to SVG"<<endl; Board2D board; board.setUnit ( LibBoard::Board::UCentimeter ); result.selfDraw<Hue> ( board, 0, maxv + 1); board.saveSVG ( "image-DT-linfty.svg" ); trace.info()<< "done"<<endl; trace.info()<< "max L1"<<endl; maxv = 0; for ( DT1::OutputImage::Iterator it2 = result1.begin(), itend = result1.end(); it2 != itend; ++it2) { if ( result1(it2) > maxv) maxv = (*it2); } trace.info()<< "Exporting to SVG L1"<<endl; board.clear(); result1.selfDraw<Hue> ( board, 0, maxv + 1); board.saveSVG ( "image-DT-l1.svg" ); trace.info()<< "done"<<endl; trace.info()<< "max Leuc"<<endl; maxv = 0; for ( DT2::OutputImage::Iterator it = result2.begin(), itend = result2.end(); it != itend; ++it) { if ( result2(it) > maxv) maxv = (*it); } trace.info()<< "Exporting to SVG L2"<<endl; board.clear(); result2.selfDraw<Hue> ( board, 0, maxv + 1); board.saveSVG ( "image-DT-l2.svg" ); trace.info()<< "done"<<endl; trace.info() << result << endl; trace.endBlock(); return nbok == nb; }
/** * Example of a test. To be completed. * */ bool testDistanceTransformation() { unsigned int nbok = 0; unsigned int nb = 0; trace.beginBlock ( "Testing the whole DT computation" ); typedef SpaceND<2> TSpace; typedef TSpace::Point Point; typedef HyperRectDomain<TSpace> Domain; typedef HueShadeColorMap<unsigned char, 2> HueTwice; typedef GrayscaleColorMap<unsigned char> Gray; Point a ( 2, 2 ); Point b ( 15, 15 ); typedef ImageSelector<Domain, unsigned int>::Type Image; Image image ( a, b ); for ( unsigned k = 0; k < 49; k++ ) { a[0] = ( k / 7 ) + 5; a[1] = ( k % 7 ) + 5; image.setValue ( a, 128 ); } DistanceTransformation<Image, 2> dt; typedef DistanceTransformation<Image, 2>::OutputImage ImageLong; dt.checkTypesValidity ( image ); Board2D board; board.setUnit ( LibBoard::Board::UCentimeter ); image.selfDraw<Gray> ( board, 0, 255 ); board.saveSVG ( "image-preDT.svg" ); //We just iterate on the Domain points and print out the point coordinates. std::copy ( image.begin(), image.end(), std::ostream_iterator<unsigned int> ( std::cout, " " ) ); ImageLong result = dt.compute ( image ); trace.warning() << result << endl; //We just iterate on the Domain points and print out the point coordinates. ImageLong::ConstIterator it = result.begin(); for (unsigned int y = 2; y < 16; y++) { for (unsigned int x = 2; x < 16; x++) { std::cout << result(it) << " "; ++it; } std::cout << std::endl; } board.clear(); result.selfDraw<Gray> ( board, 0, 16 ); board.saveSVG ( "image-postDT.svg" ); trace.info() << result << endl; trace.endBlock(); return nbok == nb; }
bool testDraw() { unsigned int nbok = 0; unsigned int nb = 0; trace.beginBlock ( "testDraw(): testing drawing commands." ); typedef SpaceND< 2 > Z2; typedef Z2::Point Point; typedef Point::Coordinate Coordinate; typedef HyperRectDomain< Z2 > DomainType; Point p1( -10, -10 ); Point p2( 10, 10 ); DomainType domain( p1, p2 ); // typedef DomainMetricAdjacency< DomainType, 1 > Adj4; // typedef DomainMetricAdjacency< DomainType, 2 > Adj8; typedef MetricAdjacency< Z2, 1 > MetricAdj4; typedef MetricAdjacency< Z2, 2 > MetricAdj8; typedef DomainAdjacency< DomainType, MetricAdj4 > Adj4; typedef DomainAdjacency< DomainType, MetricAdj8 > Adj8; typedef DigitalTopology< Adj4, Adj8 > DT48; typedef DigitalTopology< Adj8, Adj4 > DT84; typedef DigitalSetSelector < DomainType, MEDIUM_DS + HIGH_BEL_DS >::Type MediumSet; // typedef DigitalSetSelector< DomainType, SMALL_DS >::Type // MediumSet; typedef Object<DT48, MediumSet> ObjectType; typedef Object<DT84, MediumSet> ObjectType84; //typedef ObjectType::SmallSet SmallSet; //typedef Object<DT48, SmallSet> SmallObjectType; //typedef ObjectType::Size Size; // Adj4 adj4( domain ); // Adj8 adj8( domain ); MetricAdj4 madj4; MetricAdj8 madj8; Adj4 adj4( domain, madj4 ); Adj8 adj8( domain, madj8 ); DT48 dt48( adj4, adj8, JORDAN_DT ); DT84 dt84( adj8, adj4, JORDAN_DT ); Coordinate r = 5; double radius = (double) (r + 1); Point c( 0, 0 ); Point l( r, 0 ); MediumSet disk( domain ); ostringstream sstr; sstr << "Creating disk( r < " << radius << " ) ..."; trace.beginBlock ( sstr.str() ); for ( DomainType::ConstIterator it = domain.begin(); it != domain.end(); ++it ) { if ( (*it - c ).norm() < radius ) // 450.0 // insertNew is very important for vector container. disk.insertNew( *it ); } trace.endBlock(); trace.beginBlock ( "Testing Object instanciation and smart copy ..." ); ObjectType disk_object( dt48, disk ); ObjectType84 disk_object2( dt84, disk ); trace.endBlock(); trace.beginBlock ( "Testing export as SVG with libboard." ); Board2D board; board.setUnit(Board::UCentimeter); board << SetMode( domain.className(), "Grid" ) << domain; board << disk_object; board.saveSVG("disk-object.svg"); Board2D board2; board2.setUnit(Board::UCentimeter); board2 << SetMode( domain.className(), "Grid" ) << domain; board2 << SetMode( disk_object.className(), "DrawAdjacencies" ) << disk_object; board2.saveSVG("disk-object-adj.svg"); Board2D board3; board3.setUnit( Board::UCentimeter ); board3 << SetMode( domain.className(), "Grid" ) << domain; board3 << SetMode( disk_object2.className(), "DrawAdjacencies" ) << disk_object2; board3.saveSVG("disk-object-adj-bis.svg"); trace.endBlock(); trace.endBlock(); return nbok == nb; }
int main() { trace.beginBlock ( "Example distancetransform2D" ); //! [DTDef] Z2i::Point a ( 0, 0 ); Z2i::Point b ( 127, 127); //Input image with unsigned char values typedef ImageSelector<Z2i::Domain, unsigned int>::Type Image; Image image ( Z2i::Domain(a, b )); //We fill the image with the 128 value for ( Image::Iterator it = image.begin(), itend = image.end();it != itend; ++it) (*it)=128; //We generate 16 seeds with 0 values. randomSeeds(image,16,0); //! [DTDef] //! [DTColormaps] //Colormap used for the SVG output typedef HueShadeColorMap<long int, 2> HueTwice; typedef GrayscaleColorMap<unsigned char> Gray; //! [DTColormaps] //Input shape output Board2D board; board.setUnit ( LibBoard::Board::UCentimeter ); Display2DFactory::drawImage<Gray>(board, image, (unsigned int)0, (unsigned int)129); board.saveSVG("inputShape.svg"); //! [DTPredicate] //Point Predicate from random seed image typedef SimpleThresholdForegroundPredicate<Image> PointPredicate; PointPredicate predicate(image,0); //! [DTPredicate] //! [DTCompute] typedef DistanceTransformation<Z2i::Space, PointPredicate, Z2i::L2Metric> DTL2; typedef DistanceTransformation<Z2i::Space, PointPredicate, Z2i::L1Metric> DTL1; DTL2 dtL2(image.domain(), predicate, Z2i::l2Metric); DTL1 dtL1(image.domain(), predicate, Z2i::l1Metric); //! [DTCompute] DTL2::Value maxv2=0; //We compute the maximum DT value on the L2 map for ( DTL2::ConstRange::ConstIterator it = dtL2.constRange().begin(), itend = dtL2.constRange().end();it != itend; ++it) if ( (*it) > maxv2) maxv2 = (*it); DTL1::Value maxv1=0; //We compute the maximum DT value on the L1 map for ( DTL1::ConstRange::ConstIterator it = dtL1.constRange().begin(), itend = dtL1.constRange().end();it != itend; ++it) if ( (*it) > maxv1) maxv1 = (*it); trace.warning() << dtL2 << " maxValue= "<<maxv2<< endl; board.clear(); Display2DFactory::drawImage<HueTwice>(board, dtL2, 0.0, maxv2 + 1); board.saveSVG ( "example-DT-L2.svg" ); trace.warning() << dtL1 << " maxValue= "<<maxv1<< endl; board.clear(); Display2DFactory::drawImage<HueTwice>(board, dtL1, 0.0, maxv1 + 1); board.saveSVG ( "example-DT-L1.svg" ); //We compute the maximum DT value on the L2 map for ( unsigned int j=0;j<33;j++) { for(unsigned int i=0; i<33; i++) trace.info()<< dtL2(Z2i::Point(i,j)) << " "; trace.info()<<std::endl; } 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); } }
bool testCellDrawOnBoard() { typedef typename KSpace::Integer Integer; typedef typename KSpace::Cell Cell; typedef typename KSpace::SCell SCell; typedef typename KSpace::Point Point; typedef typename KSpace::DirIterator DirIterator; typedef typename KSpace::Cells Cells; typedef typename KSpace::SCells SCells; typedef SpaceND<2, Integer> Z2; typedef HyperRectDomain<Z2> Domain; unsigned int nbok = 0; unsigned int nb = 0; trace.beginBlock ( "Testing cell draw on digital board ..." ); KSpace K; int xlow[ 4 ] = { -3, -3 }; int xhigh[ 4 ] = { 5, 3 }; Point low( xlow ); Point high( xhigh ); bool space_ok = K.init( low, high, true ); Domain domain( low, high ); Board2D board; board.setUnit( LibBoard::Board::UCentimeter ); board << SetMode( domain.className(), "Paving" ) << domain; int spel[ 2 ] = { 1, 1 }; // pixel 0,0 Point kp( spel ); Cell uspel = K.uCell( kp ); board << uspel << low << high << K.uIncident( uspel, 0, false ) << K.uIncident( uspel, 1, false ); int spel2[ 2 ] = { 5, 1 }; // pixel 2,0 Point kp2( spel2 ); SCell sspel2 = K.sCell( kp2, K.POS ); board << CustomStyle( sspel2.className(), new CustomPen( Color( 200, 0, 0 ), Color( 255, 100, 100 ), 2.0, Board2D::Shape::SolidStyle ) ) << sspel2 << K.sIncident( sspel2, 0, K.sDirect( sspel2, 0 ) ) << K.sIncident( sspel2, 1, K.sDirect( sspel2, 0 ) ); board.saveEPS( "cells-1.eps" ); board.saveSVG( "cells-1.svg" ); trace.endBlock(); board.clear(); board << domain; SCell slinel0 = K.sIncident( sspel2, 0, K.sDirect( sspel2, 0 ) ); SCell spointel01 = K.sIncident( slinel0, 1, K.sDirect( slinel0, 1 ) ); board << CustomStyle( sspel2.className(), new CustomColors( Color( 200, 0, 0 ), Color( 255, 100, 100 ) ) ) << sspel2 << CustomStyle( slinel0.className(), new CustomColors( Color( 0, 200, 0 ), Color( 100, 255, 100 ) ) ) << slinel0 << CustomStyle( spointel01.className(), new CustomColors( Color( 0, 0, 200 ), Color( 100, 100, 255 ) ) ) << spointel01; board.saveEPS( "cells-3.eps" ); board.saveSVG( "cells-3.svg" ); return ((space_ok) && (nbok == nb)); }
/** * Simple test to illustrate the border extraction of a simple 2D * object considering different topologies. * */ bool testObjectBorder() { trace.beginBlock ( "Testing Object Borders in 2D ..." ); typedef int Integer; // choose your digital line here. typedef SpaceND<2> Z2; // Z^2 typedef Z2::Point Point; typedef MetricAdjacency<Z2, 1> Adj4; // 4-adjacency type typedef MetricAdjacency<Z2, 2> Adj8; // 8-adjacency type typedef DigitalTopology< Adj8, Adj4 > DT8_4; //8,4 topology type typedef HyperRectDomain< Z2 > Domain; typedef Domain::ConstIterator DomainConstIterator; typedef DigitalSetSelector < Domain, BIG_DS + HIGH_BEL_DS >::Type DigitalSet; typedef Object<DT8_4, DigitalSet> ObjectType; Point p1( -20, -10 ); Point p2( 20, 10 ); Domain domain( p1, p2 ); Adj4 adj4; // instance of 4-adjacency Adj8 adj8; // instance of 8-adjacency DT8_4 dt8_4(adj8, adj4, JORDAN_DT ); Point c( 0, 0 ); //We construct a simple 3-bubbles set DigitalSet bubble_set( domain ); for ( DomainConstIterator it = domain.begin(); it != domain.end(); ++it ) { int x = (*it)[0]; int y = (*it)[1]; if (( x*x + y*y < 82) || ( (x - 14)*(x - 14) + (y + 1)*(y + 1) < 17) || ( (x + 14)*(x + 14) + (y - 1)*(y - 1) < 17) ) bubble_set.insertNew( *it); } ObjectType bubble( dt8_4, bubble_set ); //Connectedness Check if (bubble.computeConnectedness() == ObjectType::CONNECTED) trace.info() << "The object is (8,4)connected." << endl; else trace.info() << "The object is not (8,4)connected." << endl; //Border Computation ObjectType bubbleBorder = bubble.border(); if (bubbleBorder.computeConnectedness() == ObjectType::CONNECTED) trace.info() << "The object (8,4) border is connected." << endl; else trace.info() << "The object (8,4) border is not connected." << endl; //Board Export Board2D board; board.setUnit(Board::UCentimeter); board << DrawDomainGrid() << domain << bubble_set; board.saveSVG("bubble-set.svg"); board << DrawObjectAdjacencies() // << DrawWithCustomStyle<SelfDrawStyleCustom>() << CustomStyle( "Object", new MyObjectStyleCustom ) << bubbleBorder; board.saveSVG("bubble-object-border.svg"); board.clear(); //////////////////////: //the same with the reverse topology typedef Object<DT8_4::ReverseTopology, DigitalSet> ObjectType48; DT8_4::ReverseTopology dt4_8 = dt8_4.reverseTopology(); ObjectType48 bubble2( dt4_8, bubble_set ); //Border Computation ObjectType48 bubbleBorder2 = bubble2.border(); if (bubbleBorder2.computeConnectedness() == ObjectType48::CONNECTED) trace.info() << "The object (4,8) border is connected." << endl; else trace.info() << "The object (4,8) border is not connected." << endl; domain.selfDrawAsGrid(board); bubble_set.selfDraw(board); board << DrawObjectAdjacencies() << CustomStyle( "Object", new MyObjectStyleCustom ) << bubbleBorder2; board.saveSVG("bubble-object-border-48.svg"); //We split the border according to its components vector<ObjectType48> borders(30); unsigned int nbComponents; vector<ObjectType48>::iterator it = borders.begin(); nbComponents = bubbleBorder2.writeComponents( it ); trace.info() << "The Bubble object has " << nbComponents << " (4,8)-connected components" << endl; bool flag = true; for (unsigned int k = 0;k < nbComponents ; k++) { if (flag) board << DrawObjectAdjacencies() << CustomStyle( "Object", new MyObjectStyleCustom ) << borders[k]; else board << DrawObjectAdjacencies() << CustomStyle( "Object", new MyObjectStyleCustom ) << borders[k]; flag = !flag; } board.saveSVG("bubble-object-color-borders-48.svg"); trace.endBlock(); return true; }
int main() { trace.beginBlock ( "Example distancetransform2D" ); //! [DTDef] Z2i::Point a ( 0, 0 ); Z2i::Point b ( 127, 127); //Input image with unsigned char values typedef ImageSelector<Z2i::Domain, unsigned int>::Type Image; Image image ( Z2i::Domain(a, b )); //We fill the image with the 128 value for ( Image::Iterator it = image.begin(), itend = image.end();it != itend; ++it) (*it)=128; //We generate 16 seeds with 0 values. randomSeeds(image,16,0); //! [DTDef] //Input shape output typedef GrayscaleColorMap<Image::Value> Gray; Board2D board; board.setUnit ( LibBoard::Board::UCentimeter ); Display2DFactory::drawImage<Gray>(board, image, (unsigned int)0, (unsigned int)129); board.saveSVG("inputShape.svg"); //! [DTPredicate] //Point Predicate from random seed image typedef functors::SimpleThresholdForegroundPredicate<Image> PointPredicate; PointPredicate predicate(image,0); //! [DTPredicate] //! [DTCompute] typedef DistanceTransformation<Z2i::Space, PointPredicate, Z2i::L2Metric> DTL2; typedef DistanceTransformation<Z2i::Space, PointPredicate, Z2i::L1Metric> DTL1; DTL2 dtL2(image.domain(), predicate, Z2i::l2Metric); DTL1 dtL1(image.domain(), predicate, Z2i::l1Metric); //! [DTCompute] DTL2::Value maxv2=0; //We compute the maximum DT value on the L2 map for ( DTL2::ConstRange::ConstIterator it = dtL2.constRange().begin(), itend = dtL2.constRange().end();it != itend; ++it) if ( (*it) > maxv2) maxv2 = (*it); DTL1::Value maxv1=0; //We compute the maximum DT value on the L1 map for ( DTL1::ConstRange::ConstIterator it = dtL1.constRange().begin(), itend = dtL1.constRange().end();it != itend; ++it) if ( (*it) > maxv1) maxv1 = (*it); //! [DTColormaps] //Colormap used for the SVG output typedef HueShadeColorMap<DTL2::Value, 2> HueTwice; //! [DTColormaps] trace.warning() << dtL2 << " maxValue= "<<maxv2<< endl; board.clear(); Display2DFactory::drawImage<HueTwice>(board, dtL2, 0.0, maxv2 + 1); board.saveSVG ( "example-DT-L2.svg" ); trace.warning() << dtL1 << " maxValue= "<<maxv1<< endl; board.clear(); Display2DFactory::drawImage<HueTwice>(board, dtL1, 0.0, maxv1 + 1); board.saveSVG ( "example-DT-L1.svg" ); //Explicit export with ticked colormap //We compute the maximum DT value on the L2 map board.clear(); TickedColorMap<double, GradientColorMap<double> > ticked(0.0,maxv2, Color::White); ticked.addRegularTicks(5, 0.5); ticked.finalize(); ticked.colormap()->addColor( Color::Red ); ticked.colormap()->addColor( Color::Black ); for ( DTL2::Domain::ConstIterator it = dtL2.domain().begin(), itend = dtL2.domain().end();it != itend; ++it) { board<< CustomStyle((*it).className(),new CustomColors(ticked(dtL2(*it)),ticked(dtL2(*it)))); board << *it; } board.saveSVG("example-DT-L2-ticked.svg"); trace.endBlock(); return 0; }
bool testDisconnectedCurve() { typedef int Coordinate; typedef PointVector<2,Coordinate> Point; typedef ArithmeticalDSS<std::vector<Point>::iterator,Coordinate,4> PrimitiveType; typedef MaximalSegments<PrimitiveType> DecompositionType; std::vector<Point> curve; curve.push_back(Point(0,0)); curve.push_back(Point(1,0)); curve.push_back(Point(1,1)); curve.push_back(Point(2,1)); curve.push_back(Point(3,2)); curve.push_back(Point(4,2)); curve.push_back(Point(5,2)); curve.push_back(Point(6,2)); curve.push_back(Point(6,3)); curve.push_back(Point(6,4)); curve.push_back(Point(7,4)); curve.push_back(Point(8,4)); curve.push_back(Point(9,3)); curve.push_back(Point(9,2)); curve.push_back(Point(10,2)); curve.push_back(Point(11,2)); //Segmentation trace.beginBlock("Tangential cover of disconnected digital curves"); PrimitiveType primitive; DecompositionType theDecomposition(curve.begin(), curve.end(), primitive, false); // Draw the pixels Board2D aBoard; aBoard.setUnit(Board::UCentimeter); aBoard << SetMode("PointVector", "Grid"); for (std::vector<Point>::iterator it = curve.begin(); it != curve.end(); ++it) { aBoard << (*it); } //for each segment unsigned int compteur = 0; DecompositionType::SegmentIterator i = theDecomposition.begin(); for ( ; i != theDecomposition.end(); ++i) { compteur++; trace.info() << "Segment " << compteur << std::endl; PrimitiveType segment(*i); trace.info() << segment << std::endl; //standard output aBoard << SetMode( "ArithmeticalDSS", "Points" ) << segment; // draw each segment aBoard << SetMode( "ArithmeticalDSS", "BoundingBox" ) << segment; // draw each segment } aBoard.saveSVG("specialCase.svg"); trace.endBlock(); return (compteur==5); }
/** * Example of a test. To be completed. * */ bool testGetSetVal() { unsigned int nbok = 0; unsigned int nb = 0; typedef SpaceND<2> SpaceType; typedef HyperRectDomain<SpaceType> TDomain; typedef TDomain::Point Point; Board2D board; typedef HueShadeColorMap<unsigned char,2> HueTwice; board.setUnit(LibBoard::Board::UCentimeter); //Default image selector = STLVector typedef ImageContainerByHashTree<TDomain, int > Image; typedef ImageContainerBySTLVector<TDomain, int> ImageVector; Point a( 1,1 ); Point b ( 50,50 ); Point c(15,15); Point d(128,128); Point l(0,0); Point u(255,255); trace.beginBlock ( "Image init" ); ///Domain characterized by points Image myImage ( 3, 8, 0 ); ImageVector myImageV(TDomain(l,u)); trace.info() << myImage; trace.endBlock(); trace.beginBlock("SetVal"); for( a[1] = 0; a[1] < 256; a[1]++) for( a[0] = 0; a[0] < 256; a[0]++) { if ( pow((double)(a[0]-128),3.0) - pow((double)(a[1]-128),3.0) < pow(32.0,3.0)) { myImage.setValue(a, 30); myImageV.setValue(a,30); } else if ( pow((double)(a[0]-128),3.0) - pow((double)(a[1]-128),3.0) < pow(64.0,3.0)) { myImage.setValue(a, 10); myImageV.setValue(a,10); } } trace.endBlock(); bool result=true; trace.beginBlock("GetVal consistency test"); for( a[1] = 0; a[1] < 256; a[1]++) for( a[0] = 0; a[0] < 256; a[0]++) { if ( pow((a[0]-128),3.0) - pow((a[1]-128),3.0) < pow(32,3.0)) result = result && (myImage(a) == 30); else if ( pow((a[0]-128),3.0) - pow((a[1]-128),3.0) < pow(64,3.0)) result = result && (myImage(a) == 10); } trace.endBlock(); if (result) trace.info() << "Get/Set test passed"<<endl; else trace.error() << "Get/Set test error"<<endl; nbok += result ? 1 : 0; nb++; trace.info() << myImage; trace.info() << myImageV; drawImage<HueTwice>(board, myImage, 0, 255); board.saveSVG( "hashtree.svg" ); board.clear(); drawImage<HueTwice>(board, myImageV, 0, 255); board.saveSVG( "hashtree-vector.svg" ); ///Domain characterized by points Image myImage2 ( 5, 8, 0 ); trace.beginBlock("SetVal (keysize=5)"); for( a[1] = 0; a[1] < 256; a[1]++) for( a[0] = 0; a[0] < 256; a[0]++) { if ( pow((a[0]-128),3.0) - pow((a[1]-128),3.0) < pow(32,3.0)) myImage2.setValue(a, 30); else if ( pow((a[0]-128),3.0) - pow((a[1]-128),3.0) < pow(64,3.0)) myImage2.setValue(a, 10); } trace.endBlock(); result=true; trace.beginBlock("GetVal consistency test (keysize=5)"); for( a[1] = 0; a[1] < 256; a[1]++) for( a[0] = 0; a[0] < 256; a[0]++) { if ( pow((a[0]-128),3.0) - pow((a[1]-128),3.0) < pow(32,3.0)) result = result && (myImage2(a) == 30); else if ( pow((a[0]-128),3.0) - pow((a[1]-128),3.0) < pow(64,3.0)) result = result && (myImage2(a) == 10); } trace.endBlock(); if (result) trace.info() << "Get/Set test passed"<<endl; else trace.error() << "Get/Set test error"<<endl; nbok += result ? 1 : 0; nb++; trace.warning() << "(" << nbok << "/" << nb << ") " << "true == true" << std::endl; return nbok == nb; }
/** * Simple test of Board2D. Illustrates the border extraction of a * simple 2D object considering different topologies. * */ bool testBoard2D() { trace.beginBlock ( "Testing Board2D with Object Borders in 2D ..." ); typedef int Integer; // choose your digital line here. typedef SpaceND<2> Z2; // Z^2 typedef Z2::Point Point; typedef MetricAdjacency<Z2, 1> Adj4; // 4-adjacency type typedef MetricAdjacency<Z2, 2> Adj8; // 8-adjacency type typedef DigitalTopology< Adj8, Adj4 > DT8_4; //8,4 topology type typedef HyperRectDomain< Z2 > Domain; typedef Domain::ConstIterator DomainConstIterator; typedef DigitalSetSelector < Domain, BIG_DS + HIGH_BEL_DS >::Type DigitalSet; typedef Object<DT8_4, DigitalSet> ObjectType; Point p1( -20, -10 ); Point p2( 20, 10 ); Domain domain( p1, p2 ); Adj4 adj4; // instance of 4-adjacency Adj8 adj8; // instance of 8-adjacency DT8_4 dt8_4(adj8, adj4, JORDAN_DT ); Point c( 0, 0 ); //We construct a simple 3-bubbles set DigitalSet bubble_set( domain ); for ( DomainConstIterator it = domain.begin(); it != domain.end(); ++it ) { int x = (*it)[0]; int y = (*it)[1]; if (( x*x + y*y < 82) || ( (x - 14)*(x - 14) + (y + 1)*(y + 1) < 17) || ( (x + 14)*(x + 14) + (y - 1)*(y - 1) < 17) ) bubble_set.insertNew( *it); } ObjectType bubble( dt8_4, bubble_set ); //Connectedness Check if (bubble.computeConnectedness() == ObjectType::CONNECTED) trace.info() << "The object is (8,4)connected." << endl; else trace.info() << "The object is not (8,4)connected." << endl; //Border Computation ObjectType bubbleBorder = bubble.border(); if (bubbleBorder.computeConnectedness() == ObjectType::CONNECTED) trace.info() << "The object (8,4) border is connected." << endl; else trace.info() << "The object (8,4) border is not connected." << endl; //Board Export Board2D board; board.setUnit(Board::UCentimeter); board << DrawDomainGrid() << CustomStyle( domain.styleName(), new MyDrawStyleCustomGreen ) << domain << CustomStyle( bubble_set.styleName(), new MyDrawStyleCustomRed ) << bubble_set; board.saveSVG("bubble-set-dgtalboard.svg"); board << DrawObjectAdjacencies( true ) << CustomStyle( bubbleBorder.styleName(), new MyDrawStyleCustomBlue ) << bubbleBorder; board.saveSVG("bubble-object-border-dgtalboard.svg"); board.clear(); trace.endBlock(); return true; }
int main() { //! [DTDef] using namespace std; using namespace DGtal; using namespace Z2i; Point a ( 0, 0 ); Point b ( 32, 16); //Input image with unsigned char values typedef ImageSelector<Domain, unsigned int>::Type Image; Image image ( Domain(a, b )); //We fill the image with the 128 value for ( Image::Iterator it = image.begin(), itend = image.end();it != itend; ++it) (*it)=128; //We add 3 seeds with 0 values. image.setValue(Point(16,2), 0); image.setValue(Point(2,11), 0); image.setValue(Point(30,15), 0); //! [DTDef] trace.beginBlock ( "Example toricdomainvolumetric" ); //Input shape output typedef GrayscaleColorMap<Image::Value> Gray; Board2D board; board.setUnit ( LibBoard::Board::UCentimeter ); Display2DFactory::drawImage<Gray>(board, image, (unsigned int)0, (unsigned int)129); board.saveSVG("toric-inputShape.svg"); //! [DTPredicate] //Point Predicate from random seed image typedef functors::SimpleThresholdForegroundPredicate<Image> PointPredicate; PointPredicate predicate(image,0); //! [DTPredicate] //! [DTComputeToric] typedef DistanceTransformation<Space, PointPredicate, L2Metric> DTL2; typedef DistanceTransformation<Space, PointPredicate, L2Metric> DTL2Toric; //Regular 2D domain DTL2 dtL2(image.domain(), predicate, l2Metric); //Full toric 2D domain DTL2Toric dtL2Toric(image.domain(), predicate, l2Metric, {{true, true}} ); //! [DTComputeToric] //! [DTComputePartialToric] typedef DistanceTransformation<Space, PointPredicate, L2Metric> DTL2ToricX; typedef DistanceTransformation<Space, PointPredicate, L2Metric> DTL2ToricY; // 2D domain that is periodic along the first dimension. DTL2ToricX dtL2ToricX( image.domain(), predicate, l2Metric, {{true, false}} ); // 2D domain that is periodic along the second dimension. DTL2ToricY dtL2ToricY( image.domain(), predicate, l2Metric, {{false, true}} ); //! [DTComputePartialToric] //We compute the maximum DT value on the L2 map const DTL2::Value maxv2 = * (std::max_element(dtL2.constRange().begin(), dtL2.constRange().end())); const DTL2Toric::Value maxvtoric = * (std::max_element(dtL2Toric.constRange().begin(), dtL2Toric.constRange().end())); const DTL2ToricX::Value maxvtoricX = * (std::max_element(dtL2ToricX.constRange().begin(), dtL2ToricX.constRange().end())); const DTL2ToricY::Value maxvtoricY = * (std::max_element(dtL2ToricY.constRange().begin(), dtL2ToricY.constRange().end())); // Color map based on the maximal value for all maps (in order to compare results with similar colors). const auto maxvall = std::max( { maxv2, maxvtoric, maxvtoricX, maxvtoricY } ); //! [DTColormaps] //Colormap used for the SVG output typedef HueShadeColorMap<DTL2::Value, 1> HueTwice; //! [DTColormaps] trace.warning() << "DT maxValue= " << maxv2 << endl; board.clear(); Display2DFactory::drawImage<HueTwice>(board, dtL2, 0.0, maxvall + 1); board.saveSVG ( "toric-example-DT-L2.svg" ); trace.warning() << "Full toric maxValue= " << maxvtoric << endl; board.clear(); Display2DFactory::drawImage<HueTwice>(board, dtL2Toric, 0.0, maxvall + 1); board.saveSVG ( "toric-example-DT-L2-toric.svg" ); trace.warning() << "1th dimension periodic maxValue= " << maxvtoricX << endl; board.clear(); Display2DFactory::drawImage<HueTwice>(board, dtL2ToricX, 0.0, maxvall + 1); board.saveSVG ( "toric-example-DT-L2-toricX.svg" ); trace.warning() << "2nd dimension periodic maxValue= " << maxvtoricY << endl; board.clear(); Display2DFactory::drawImage<HueTwice>(board, dtL2ToricY, 0.0, maxvall + 1); board.saveSVG ( "toric-example-DT-L2-toricY.svg" ); //Explicit export with ticked colormap //We compute the maximum DT value on the L2 map TickedColorMap<double, GradientColorMap<double> > ticked(0.0,maxv2, Color::White); ticked.addRegularTicks(3, 0.5); ticked.finalize(); ticked.colormap()->addColor( Color::Red ); ticked.colormap()->addColor( Color::Black ); board.clear(); for ( auto it = dtL2.domain().begin(), itend = dtL2.domain().end();it != itend; ++it) { board<< CustomStyle((*it).className(),new CustomColors(ticked(dtL2(*it)),ticked(dtL2(*it)))); board << *it; } board.saveSVG("toric-example-DT-L2-ticked.svg"); board.clear(); for ( auto it = dtL2Toric.domain().begin(), itend = dtL2Toric.domain().end();it != itend; ++it) { board<< CustomStyle((*it).className(),new CustomColors(ticked(dtL2Toric(*it)),ticked(dtL2Toric(*it)))); board << *it; } board.saveSVG("toric-example-DT-L2-ticked-toric.svg"); board.clear(); for ( auto it = dtL2ToricX.domain().begin(), itend = dtL2ToricX.domain().end();it != itend; ++it) { board<< CustomStyle((*it).className(),new CustomColors(ticked(dtL2ToricX(*it)),ticked(dtL2ToricX(*it)))); board << *it; } board.saveSVG("toric-example-DT-L2-ticked-toricX.svg"); board.clear(); for ( auto it = dtL2ToricY.domain().begin(), itend = dtL2ToricY.domain().end();it != itend; ++it) { board<< CustomStyle((*it).className(),new CustomColors(ticked(dtL2ToricY(*it)),ticked(dtL2ToricY(*it)))); board << *it; } board.saveSVG("toric-example-DT-L2-ticked-toricY.svg"); //Voronoi vector output board.clear(); board << dtL2.domain(); for ( auto it = dtL2.domain().begin(), itend = dtL2.domain().end();it != itend; ++it) if ( dtL2.getVoronoiVector(*it) != *it ) Display2DFactory::draw(board,dtL2.getVoronoiVector(*it) - (*it), (*it)); board.saveSVG("toric-example-Voro-L2.svg"); board.clear(); board << dtL2Toric.domain(); for ( auto it = dtL2Toric.domain().begin(), itend = dtL2Toric.domain().end();it != itend; ++it) if ( dtL2Toric.getVoronoiVector(*it) != *it ) Display2DFactory::draw(board, dtL2Toric.getVoronoiVector(*it) - (*it), (*it)); board.saveSVG("toric-example-Voro-L2-toric.svg"); board.clear(); board << dtL2Toric.domain(); for ( auto it = dtL2Toric.domain().begin(), itend = dtL2Toric.domain().end();it != itend; ++it) if ( dtL2Toric.getVoronoiVector(*it) != *it ) Display2DFactory::draw(board, dtL2Toric.projectPoint(dtL2Toric.getVoronoiVector(*it)) - (*it), (*it)); board.saveSVG("toric-example-Voro-L2-toric-projected.svg"); board.clear(); board << dtL2ToricX.domain(); for ( auto it = dtL2ToricX.domain().begin(), itend = dtL2ToricX.domain().end();it != itend; ++it) if ( dtL2ToricX.getVoronoiVector(*it) != *it ) Display2DFactory::draw(board, dtL2ToricX.getVoronoiVector(*it) - (*it), (*it)); board.saveSVG("toric-example-Voro-L2-toricX.svg"); board.clear(); board << dtL2ToricY.domain(); for ( auto it = dtL2ToricY.domain().begin(), itend = dtL2ToricY.domain().end();it != itend; ++it) if ( dtL2ToricY.getVoronoiVector(*it) != *it ) Display2DFactory::draw(board, dtL2ToricY.getVoronoiVector(*it) - (*it), (*it)); board.saveSVG("toric-example-Voro-L2-toricY.svg"); trace.endBlock(); return 0; }
bool testSurfelAdjacency() { typedef typename KSpace::Integer Integer; typedef typename KSpace::Cell Cell; typedef typename KSpace::SCell SCell; typedef typename KSpace::Point Point; typedef typename KSpace::DirIterator DirIterator; typedef typename KSpace::Cells Cells; typedef typename KSpace::SCells SCells; unsigned int nbok = 0; unsigned int nb = 0; trace.beginBlock ( "Testing block KSpace instantiation and scan ..." ); KSpace K; int xlow[ 4 ] = { -3, -3, -3, -3 }; int xhigh[ 4 ] = { 5, 3, 3, 3 }; Point low( xlow ); Point high( xhigh ); bool space_ok = K.init( low, high, true ); nbok += space_ok ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << "K.init( low, high )" << std::endl; trace.info() << "K.dim()=" << K.dimension << endl; trace.endBlock(); trace.beginBlock ( "Testing surfel adjacency ..." ); SurfelAdjacency<KSpace::dimension> SAdj( true ); for ( Dimension i = 0; i < K.dimension; ++i ) for ( Dimension j = 0; j < K.dimension; ++j ) if ( i != j ) trace.info() << "(" << i << "," << j << ")=" << ( SAdj.getAdjacency( i, j ) ? "i2e" : "e2i" ); trace.info() << endl; trace.endBlock(); int spel[ 4 ] = { 1, 1, 1, 1 }; // pixel Point kp( spel ); SCell sspel = K.sCell( kp, K.POS ); trace.beginBlock ( "Testing surfel directness ..." ); for ( Dimension k = 0; k < K.dimension; ++k ) { SCell surfel = K.sIncident( sspel, k, true ); SCell innerspel = K.sDirectIncident( surfel, K.sOrthDir( surfel ) ); trace.info() << "spel=" << sspel << " surfel=" << surfel << " innerspel=" << innerspel << endl; nbok += sspel == innerspel ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << "spel == innerspel" << std::endl; surfel = K.sIncident( sspel, k, false ); innerspel = K.sDirectIncident( surfel, K.sOrthDir( surfel ) ); trace.info() << "spel=" << sspel << " surfel=" << surfel << " innerspel=" << innerspel << endl; nbok += sspel == innerspel ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << "spel == innerspel" << std::endl; } trace.endBlock(); SurfelNeighborhood<KSpace> SN; trace.beginBlock ( "Testing surfel neighborhood ..." ); SCell surfel = K.sIncident( sspel, 0, false ); SN.init( &K, &SAdj, surfel ); trace.info() << "surfel =" << surfel << endl; trace.info() << "follower1(+)=" << SN.follower1( 1, true ) << endl; trace.info() << "follower2(+)=" << SN.follower2( 1, true ) << endl; trace.info() << "follower3(+)=" << SN.follower3( 1, true ) << endl; trace.info() << "follower1(-)=" << SN.follower1( 1, false ) << endl; trace.info() << "follower2(-)=" << SN.follower2( 1, false ) << endl; trace.info() << "follower3(-)=" << SN.follower3( 1, false ) << endl; trace.endBlock(); trace.beginBlock ( "Testing surface tracking ..." ); typedef SpaceND< KSpace::dimension, Integer > Space; typedef HyperRectDomain<Space> Domain; typedef typename DigitalSetSelector< Domain, BIG_DS+HIGH_BEL_DS >::Type DigitalSet; Domain domain( low, high ); DigitalSet shape_set( domain ); SetPredicate<DigitalSet> shape_set_predicate( shape_set ); int center[ 4 ] = { 1, 0, 0, 0 }; // pixel Point pcenter( center ); Shapes<Domain>::addNorm1Ball( shape_set, pcenter, 1 ); trace.info() << "surfel = " << surfel << endl; SCell other1, other2; SN.getAdjacentOnDigitalSet( other1, shape_set, 1, K.sDirect( surfel, 1 ) ); SN.getAdjacentOnDigitalSet( other2, shape_set, 1, !K.sDirect( surfel, 1 ) ); trace.info() << "directNext = " << other1 << endl; trace.info() << "indirectNext= " << other2 << endl; std::set<SCell> bdry; // surfel = Surfaces<KSpace>::findABel( K, shape_set ); Surfaces<KSpace>::trackBoundary( bdry, K, SAdj, shape_set_predicate, surfel ); trace.info() << "tracking finished, size=" << bdry.size() << ", should be " << 2*K.dimension*(2*K.dimension-1) << endl; nbok += bdry.size() == ( 2*K.dimension*(2*K.dimension-1) ) ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << "bdry.size() == ( 2*K.dimension*(2*K.dimension-1) )" << std::endl; std::set<SCell> bdry_direct; Surfaces<KSpace>::trackClosedBoundary( bdry_direct, K, SAdj, shape_set_predicate, surfel ); trace.info() << "fast direct tracking finished, size=" << bdry_direct.size() << ", should be " << 2*K.dimension*(2*K.dimension-1) << endl; nbok += bdry_direct.size() == ( 2*K.dimension*(2*K.dimension-1) ) ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << "bdry_direct.size() == ( 2*K.dimension*(2*K.dimension-1) )" << std::endl; trace.endBlock(); if ( K.dimension == 2 ) { Board2D board; board.setUnit( LibBoard::Board::UCentimeter ); board << SetMode( domain.className(), "Paving" ) << domain; for ( typename std::set<SCell>::const_iterator it = bdry_direct.begin(), it_end = bdry_direct.end(); it != it_end; ++it ) board << *it; board.saveEPS( "cells-2.eps" ); board.saveSVG( "cells-2.svg" ); } return nbok == nb; }