/** * Example of a test. To be completed. * */ bool testImplicitShape() { unsigned int nbok = 0; unsigned int nb = 0; trace.beginBlock ( "Testing implicit shaper ..." ); Z2i::Point a(0,0); Z2i::Point b(64,64); Z2i::Point c(32,32); Board2D board; Z2i::Domain domain(a,b); Z2i::DigitalSet set(domain); Shapes<Z2i::Domain>::shaper( set, ImplicitBall<Z2i::Space>( c, 10)); board << set; board.saveSVG("implicitball.svg"); set.clear(); board.clear(); Shapes<Z2i::Domain>::shaper( set, ImplicitHyperCube<Z2i::Space>( c, 10)); board << set; board.saveSVG("implicitcube.svg"); set.clear(); board.clear(); Shapes<Z2i::Domain>::shaper( set, ImplicitNorm1Ball<Z2i::Space>( c, 10)); board << set; board.saveSVG("implicitlosange.svg"); set.clear(); board.clear(); Shapes<Z2i::Domain>::shaper( set, ImplicitRoundedHyperCube<Z2i::Space>( c, 10, 1)); board << set; board.saveSVG("implicitrounded-1.svg"); set.clear(); board.clear(); Shapes<Z2i::Domain>::shaper( set, ImplicitRoundedHyperCube<Z2i::Space>( c, 10, 2.5)); board << set; board.saveSVG("implicitrounded-2.5.svg"); nbok += true ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << "true == true" << std::endl; trace.endBlock(); return nbok == nb; }
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 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; }
int main( int argc, char** argv ) { trace.beginBlock ( "Example exampleBezierCurve" ); trace.info() << "Args:"; for ( int i = 0; i < argc; ++i ) trace.info() << " " << argv[ i ]; trace.info() << endl; //control points typedef PointVector<2,int> Point; Point P(0,0), Q(4,4), R(8,0); //display Board2D board; //with fill board << SetMode(P.className(), "Grid") << P << Q << R; board.drawQuadraticBezierCurve(P[0], P[1], Q[0], Q[1], R[0], R[1]); board.saveSVG("BezierCurve.svg", Board2D::BoundingBox, 5000 ); board.saveEPS("BezierCurve.eps", Board2D::BoundingBox, 5000 ); board.saveTikZ("BezierCurve.tikz", Board2D::BoundingBox, 5000 ); board.saveFIG("BezierCurve.fig", Board2D::BoundingBox, 5000 ); #ifdef WITH_CAIRO board.saveCairo("BezierCurve.pdf", Board2D::CairoPDF); #endif board.clear(); //without fill board << SetMode(P.className(), "Grid") << P << Q << R; board.setFillColor(Color::None); board.drawQuadraticBezierCurve(P[0], P[1], Q[0], Q[1], R[0], R[1]); board.saveSVG("BezierCurve2.svg", Board2D::BoundingBox, 5000 ); board.saveEPS("BezierCurve2.eps", Board2D::BoundingBox, 5000 ); board.saveTikZ("BezierCurve2.tikz", Board2D::BoundingBox, 5000 ); board.saveFIG("BezierCurve2.fig", Board2D::BoundingBox, 5000 ); #ifdef WITH_CAIRO board.saveCairo("BezierCurve2.pdf", Board2D::CairoPDF); #endif trace.endBlock(); return 0; }
int main() { trace.beginBlock ( "Board example" ); Point p1( -3, -2 ); Point p2( 7, 3 ); Point p3( 0, 0 ); Domain domain( p1, p2 ); Board2D board; //We display the underlying domain board << domain ; //We display points board << p1 << p2 << p3; //Output board.saveSVG("test.svg"); board.saveEPS("test.eps"); board.saveTikZ("test.tikz"); //Clear board.clear(); //Upade position + color p2[0] = 5; //x-coordinate board << domain << p1 << p3; Color red( 255, 0, 0 ); //All points will be in red board << CustomStyle( p2.className(), new CustomColors( red, red ) ) << p2; //Export again board.saveEPS("test2.eps"); trace.endBlock(); return 0; }
void moduleImages_example() { using namespace Z2i; Board2D aBoard; //! [def] using Value = double; // value type of the image using HueShadeDouble = HueShadeColorMap<Value>; // a simple HueShadeColorMap varying on 'double' values //! [def] trace.beginBlock("image"); //! [raw_image_creation] const Domain domain(Point(1,1), Point(16,16)); Value* data = new Value[ domain.size() ]; ArrayImageAdapter< Value*, Domain > image( data, domain ); //! [raw_image_creation] //! [image_filling] Value i = 0; for ( auto & value : image ) value = i++; //! [image_filling] aBoard.clear(); Display2DFactory::drawImage<HueShadeDouble>(aBoard, image, 0, domain.size()-1); aBoard.saveSVG("ArrayImageAdapter_image.svg"); trace.endBlock(); trace.beginBlock("subImage"); //! [ConstArrayImageAdapterForSubImage_creation] Domain subDomain(Point(1,1), Point(8,8)); ArrayImageAdapter< Value const*, Domain > constSubImage( data, domain, subDomain ); //! [ConstArrayImageAdapterForSubImage_creation] aBoard.clear(); Display2DFactory::drawImage<HueShadeDouble>(aBoard, constSubImage, 0, domain.size()-1); aBoard.saveSVG("ArrayImageAdapter_subImage.svg"); trace.endBlock(); trace.beginBlock("modifying subImage through domain iterator"); { //! [ArrayImageAdapterForSubImage_creation] ArrayImageAdapter< Value*, Domain > subImage( data, domain, subDomain ); //! [ArrayImageAdapterForSubImage_creation] } //! [ArrayImageAdapterForSubImage_alternateCreation] auto subImage = makeArrayImageAdapterFromIterator( data, domain, subDomain ); //! [ArrayImageAdapterForSubImage_alternateCreation] //! [ArrayImageAdapterForSubImage_modifByDomain] for ( auto point : subImage.domain() ) { Value coord = (point - Point(4,4)).norm(); subImage.setValue( point, 25*(cos(coord)+1) ); } //! [ArrayImageAdapterForSubImage_modifByDomain] aBoard.clear(); Display2DFactory::drawImage<HueShadeDouble>(aBoard, image, 0, domain.size()-1); aBoard.saveSVG("ArrayImageAdapter_subImage_modifByDomain.svg"); trace.endBlock(); trace.beginBlock("modifying subImage through image iterator"); //! [ArrayImageAdapterForSubImage_modifByImage] for ( auto it = subImage.begin(), it_end = subImage.end(); it != it_end; ++it ) { Value coord = (it.getPoint() - Point(4,4)).norm(); *it = 25*(sin(coord)+1); } //! [ArrayImageAdapterForSubImage_modifByImage] aBoard.clear(); Display2DFactory::drawImage<HueShadeDouble>(aBoard, image, 0, domain.size()-1); aBoard.saveSVG("ArrayImageAdapter_subImage_modifByImage.svg"); trace.endBlock(); trace.beginBlock("subImage from an ImageContainerBySTLVector"); //! [ImageSTL_creation] ImageContainerBySTLVector<Domain, Value> anIterableImage(domain); for (auto& value : anIterableImage) value = 0; //! [ImageSTL_creation] //! [ArrayImageAdapterFromImageSTL] { ArrayImageAdapter< ImageContainerBySTLVector<Domain,Value>::Iterator, Domain > subImageSTL( anIterableImage.begin(), domain, subDomain ); } //! [ArrayImageAdapterFromImageSTL] //! [ArrayImageAdapterFromImageSTL_alternate] auto subImageSTL = makeArrayImageAdapterFromImage( anIterableImage, subDomain ); //! [ArrayImageAdapterFromImageSTL_alternate] trace.endBlock(); trace.beginBlock("using std::copy on ArrayImageAdapter"); //! [ArrayImageAdapterFromImageSTL_copy] std::copy( subImage.cbegin(), subImage.cend(), subImageSTL.begin() ); //! [ArrayImageAdapterFromImageSTL_copy] aBoard.clear(); Display2DFactory::drawImage<HueShadeDouble>(aBoard, anIterableImage, 0, domain.size()-1); aBoard.saveSVG("ArrayImageAdapter_subImage_copyToImageSTL.svg"); trace.endBlock(); delete[] data; }
int main() { trace.beginBlock ( "Example kernelDomain" ); //We create several space models. typedef DGtal::SpaceND<3, DGtal::int32_t> MySpace32; typedef DGtal::SpaceND<1, DGtal::int64_t> MySpace8; #ifdef WITH_BIGINTEGER typedef DGtal::SpaceND<3, DGtal::BigInteger> MySpaceBIGINTEGER; #endif typedef DGtal::Z2i::Space MySpace; //Point lying in the Z2i::Space typedef MySpace::Point MyPoint; MyPoint p(13,-5); trace.info() << "Point p="<<p<<endl; //We create a domain typedef HyperRectDomain<MySpace> MyDomain; MyPoint a(-3,-4); MyPoint b(10,4); MyDomain domain(a,b); //We trace domain information trace.info() <<"Domain domain="<<domain<<endl; //We generate a board Board2D board; board << domain; board.saveSVG("kernel-domain.svg"); MyPoint c(5,1); if ( domain.isInside(c) ) trace.info() << "C is inside the domain"<<endl; else trace.info() << "C is outside the domain"<<endl; board << c; board.saveSVG("kernel-domain-point.svg"); //PointVector example MyPoint q; MyPoint::Coordinate coord = 24; for(MySpace::Dimension d = 0 ; d < MySpace::dimension; d++) q[d] = coord; trace.info()<<"Q="<<q<<endl; MyPoint r; for(MyPoint::Iterator it=r.begin(), itend=r.end() ; it != itend; ++it) (*it) = coord; trace.info()<<"R="<<r<<endl; //We scan the domain for( MyDomain::ConstIterator it = domain.begin(), itend = domain.end(); it != itend; ++it) trace.info() << "Processing point"<< (*it) << endl; board.clear(); board << domain; //We draw an arrow between two consecutive points during the iteration. MyDomain::ConstIterator itPrec = domain.begin(); MyDomain::ConstIterator it = itPrec; MyDomain::Vector shift; ++it; board << (*itPrec); //We display the first point as a pixel. for( MyDomain::ConstIterator itend = domain.end(); it != itend; ++it, ++itPrec) { shift = (*it) -(*itPrec); Display2DFactory::draw(board, shift, (*itPrec)); } board.saveSVG("kernel-domain-it-arrow.svg"); trace.endBlock(); return 0; }
int main( int argc, char** argv ) { using namespace DGtal; using namespace DGtal::Z2i; typedef ImageContainerBySTLVector<Domain,unsigned char> GrayLevelImage2D; typedef ImageContainerBySTLVector<Domain,double> DoubleImage2D; typedef DistanceToMeasure<DoubleImage2D> Distance; if ( argc <= 3 ) return 1; GrayLevelImage2D img = GenericReader<GrayLevelImage2D>::import( argv[ 1 ] ); double mass = atof( argv[ 2 ] ); double rmax = atof( argv[ 3 ] ); double R = atof( argv[ 4 ] ); double r = atof( argv[ 5 ] ); double T1 = atof( argv[ 6 ] ); double T2 = atof( argv[ 7 ] ); DoubleImage2D fimg( img.domain() ); DoubleImage2D::Iterator outIt = fimg.begin(); for ( GrayLevelImage2D::ConstIterator it = img.begin(), itE = img.end(); it != itE; ++it ) { double v = ((double)*it) / 255.0; *outIt++ = v; } trace.beginBlock( "Computing delta-distance." ); Distance delta( mass, fimg, rmax ); const DoubleImage2D& d2 = delta.myDistance2; trace.endBlock(); double m = 0.0f; for ( typename Domain::ConstIterator it = d2.domain().begin(), itE = d2.domain().end(); it != itE; ++it ) { Point p = *it; double v = sqrt( d2( p ) ); m = std::max( v, m ); } GradientColorMap<double> cmap_grad( 0, m ); cmap_grad.addColor( Color( 255, 255, 255 ) ); cmap_grad.addColor( Color( 255, 255, 0 ) ); cmap_grad.addColor( Color( 255, 0, 0 ) ); cmap_grad.addColor( Color( 0, 255, 0 ) ); cmap_grad.addColor( Color( 0, 0, 255 ) ); cmap_grad.addColor( Color( 0, 0, 0 ) ); Board2D board; board << SetMode( d2.domain().className(), "Paving" ); for ( typename Domain::ConstIterator it = d2.domain().begin(), itE = d2.domain().end(); it != itE; ++it ) { Point p = *it; double v = sqrt( d2( p ) ); v = std::min( (double) m, std::max( v, 0.0 ) ); board << CustomStyle( p.className(), new CustomColors( Color::Black, cmap_grad( v ) ) ) << p; RealVector grad = delta.projection( p ); board.drawLine( p[ 0 ], p[ 1 ], p[ 0 ] + grad[ 0 ], p[ 1 ] + grad[ 1 ], 0 ); } std::cout << endl; board.saveEPS("dvcm-delta2.eps"); board.clear(); trace.beginBlock( "Computing delta-VCM." ); typedef DeltaVCM< Distance > DVCM; typedef DVCM::Matrix Matrix; DVCM dvcm( delta, R, r ); trace.endBlock(); { GrayLevelImage2D pm_img( dvcm.myProjectedMeasure.domain() ); DoubleImage2D::ConstIterator it = dvcm.myProjectedMeasure.begin(); DoubleImage2D::ConstIterator itE = dvcm.myProjectedMeasure.end(); GrayLevelImage2D::Iterator outIt = pm_img.begin(); for ( ; it != itE; ++it ) { double v = std::max( 0.0, std::min( (*it) * 255.0, 255.0 ) ); *outIt++ = v; } GenericWriter< GrayLevelImage2D >::exportFile( "dvcm-projmeasure.pgm", pm_img ); } typedef EigenDecomposition<2,double> LinearAlgebraTool; typedef functors::HatPointFunction<Point,double> KernelFunction; KernelFunction chi( 1.0, r ); // Flat zones are metallic blue, slightly curved zones are white, // more curved zones are yellow till red. double size = 1.0; GradientColorMap<double> colormap( 0.0, T2 ); colormap.addColor( Color( 128, 128, 255 ) ); colormap.addColor( Color( 255, 255, 255 ) ); colormap.addColor( Color( 255, 255, 0 ) ); colormap.addColor( Color( 255, 0, 0 ) ); Matrix vcm_r, evec, null; RealVector eval; for ( Domain::ConstIterator it = dvcm.domain().begin(), itE = dvcm.domain().end(); it != itE; ++it ) { // Compute VCM and diagonalize it. Point p = *it; vcm_r = dvcm.measure( chi, p ); if ( vcm_r == null ) continue; LinearAlgebraTool::getEigenDecomposition( vcm_r, evec, eval ); //double feature = eval[ 0 ] / ( eval[ 0 ] + eval[ 1 ] ); eval[ 0 ] = std::max( eval[ 0 ], 0.00001 ); double tubular = ( eval[ 1 ] <= 0.00001 ) // (R*R/4.0) ) ? 0 : ( eval[ 1 ] / ( eval[ 0 ] + eval[ 1 ] ) ); double bound = T1; double tubular2 = tubular * (eval[ 0 ] + eval[ 1 ]) / (R*R*r/12.0); double display = tubular2 <= bound ? 0.0 : ( tubular2 - bound ) / (1.0 - bound); //: eval[ 1 ] / ( 1.0 + eval[ 0 ] ) / ( 1.0 + delta( p )*delta( p ) ); //: eval[ 1 ] * eval[ 1 ] / ( 1.0 + eval[ 0 ] ) / ( 1.0 + delta( p ) ); trace.info() << "l0=" << eval[ 0 ] << " l1=" << eval[ 1 ] << " tub=" << tubular << " tub2=" << tubular2 << " disp=" << display << std::endl; board << CustomStyle( p.className(), new CustomColors( Color::Black, colormap( display > T2 ? T2 : display ) ) ) << p; // Display normal RealVector normal = evec.column( 0 ); RealPoint rp( p[ 0 ], p[ 1 ] ); Display2DFactory::draw( board, size*normal, rp ); Display2DFactory::draw( board, -size*normal, rp ); } board.saveEPS("dvcm-hat-r.eps"); board.clear(); return 0; }
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 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)); }
int main() { trace.beginBlock ( "Example distancetransform2D" ); 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 ( 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,50,0); //Colormap used for the SVG output typedef HueShadeColorMap<long int, 2> HueTwice; typedef GrayscaleColorMap<unsigned char> Gray; //Input shape output Board2D board; board.setUnit ( LibBoard::Board::UCentimeter ); image.selfDraw<Gray> ( board , 0, 129); board.saveSVG("inputShape.svg"); typedef DistanceTransformation<Image, 2> DTL2; typedef DistanceTransformation<Image, 0> DTLInf; typedef DistanceTransformation<Image, 1> DTL1; DTL2 dtL2; DTLInf dtLinf; DTL1 dtL1; DTL2::OutputImage resultL2 = dtL2.compute ( image ); DTLInf::OutputImage resultLinf = dtLinf.compute ( image ); DTL1::OutputImage resultL1 = dtL1.compute ( image ); unsigned int maxv=0; //We compute the maximum DT value on the Linf map for ( DTLInf::OutputImage::ConstIterator it = resultLinf.begin(), itend = resultLinf.end();it != itend; ++it) if ( (*it) > maxv) maxv = (*it); unsigned int maxv2=0; //We compute the maximum DT value on the L2 map for ( DTL2::OutputImage::ConstIterator it = resultL2.begin(), itend = resultL2.end();it != itend; ++it) if ( (*it) > maxv2) maxv2 = (*it); unsigned int maxv1=0; //We compute the maximum DT value on the L1 map for ( DTL1::OutputImage::ConstIterator it = resultL1.begin(), itend = resultL1.end();it != itend; ++it) if ( (*it) > maxv1) maxv1 = (*it); trace.warning() << resultL2 << " maxValue= "<<maxv2<< endl; board.clear(); resultL2.selfDraw<HueTwice> ( board , 0, maxv2 + 1 ); board.saveSVG ( "example-DT-L2.svg" ); trace.warning() << resultL1 << " maxValue= "<<maxv1<< endl; board.clear(); resultL1.selfDraw<HueTwice> ( board , 0, maxv1 + 1 ); board.saveSVG ( "example-DT-L1.svg" ); trace.warning() << resultLinf << " maxValue= "<<maxv<< endl; board.clear(); resultLinf.selfDraw<HueTwice> ( board , 0, maxv + 1 ); board.saveSVG ( "example-DT-Linf.svg" ); trace.endBlock(); return 0; }
/** * Example of a test. To be completed. * */ bool testDistanceTransformationNeg() { 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 ( -10, -10 ); Point b ( 10, 10 ); typedef ImageSelector<Domain, unsigned int>::Type Image; Image image ( a, b ); for(int y=-10; y<=10;y++) for(int x=-10; x<=10;x++) { if ((abs(x)<7) && (abs(y)<5)) image.setValue(Point(x,y),1); else image.setValue(Point(x,y),0); } 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, 1 ); board.saveSVG ( "image-preDT-neg.svg" ); for(int y=-10; y<=10;y++) { for(int x=-10; x<=10;x++) { std::cout<<image(Point(x,y))<<" "; } std::cout<<std::endl; } ImageLong result = dt.compute ( image ); DGtal::int64_t maxv=0; for(ImageLong::Iterator it = result.begin(), itend = result.end(); it != itend ; ++it) if (result(it) > maxv) maxv = result(it); for(int y=-10; y<=10;y++) { for(int x=-10; x<=10;x++) { std::cout<<result(Point(x,y))<<" "; } std::cout<<std::endl; } trace.warning() << result << endl; board.clear(); result.selfDraw<Gray> ( board, 0, maxv ); board.saveSVG ( "image-postDT-neg.svg" ); trace.info() << result << endl; trace.endBlock(); return nbok == nb; }
/** * Example of a test. To be completed. * */ bool testSimplePoints2D() { unsigned int nbok = 0; unsigned int nb = 0; typedef DGtal::Z2i::Point Point; typedef Domain::ConstIterator DomainConstIterator; Point p1( -17, -17 ); Point p2( 17, 17 ); Domain domain( p1, p2 ); DigitalSet shape_set( domain ); Shapes<Domain>::addNorm1Ball( shape_set, Point( -10, -8 ), 7 ); Shapes<Domain>::addNorm1Ball( shape_set, Point( 10, 8 ), 7 ); Shapes<Domain>::addNorm1Ball( shape_set, Point( 3, 0 ), 6 ); Shapes<Domain>::addNorm1Ball( shape_set, Point( 0, -3 ), 7 ); Shapes<Domain>::addNorm1Ball( shape_set, Point( -10, 0 ), 6 ); Shapes<Domain>::addNorm1Ball( shape_set, Point( -8, 8 ), 6 ); Shapes<Domain>::addNorm1Ball( shape_set, Point( 0, 9 ), 6 ); Shapes<Domain>::addNorm1Ball( shape_set, Point( 15, -2 ), 6 ); Shapes<Domain>::addNorm1Ball( shape_set, Point( 12, -10 ), 4 ); shape_set.erase( Point( 5, 0 ) ); shape_set.erase( Point( -1, -2 ) ); Object4_8 shape( dt4_8, shape_set ); Object8_4 shape2( dt8_4, shape_set ); GradientColorMap<int> cmap_grad( 0, 6 ); cmap_grad.addColor( Color( 128, 128, 255 ) ); cmap_grad.addColor( Color( 255, 255, 128 ) ); //cmap_grad.addColor( Color( 220, 130, 25 ) ); Board2D board; board.setUnit(Board::UCentimeter); board << SetMode( domain.styleName(), "Paving" ) // DrawDomainPaving() << domain; Board2D board2; board2.setUnit(Board::UCentimeter); board2 << SetMode( domain.styleName(), "Grid" ) // DrawDomainGrid() << domain; // Greedy thinning. DGtal::uint64_t nb_simple; trace.beginBlock ( "Greedy homotopic thinning ..." ); int layer = 0; do { DigitalSet & S = shape.pointSet(); std::queue<DigitalSet::Iterator> Q; for ( DigitalSet::Iterator it = S.begin(); it != S.end(); ++it ) if ( shape.isSimple( *it ) ) Q.push( it ); nb_simple = 0; while ( ! Q.empty() ) { DigitalSet::Iterator it = Q.front(); Q.pop(); if ( shape.isSimple( *it ) ) { board << CustomStyle( it->styleName(), new MyDrawStyleCustomFillColor ( cmap_grad( layer ) ) ) << *it; S.erase( *it ); ++nb_simple; } } ++layer; } while ( nb_simple != 0 ); trace.endBlock(); // Greedy thinning. trace.beginBlock ( "Greedy homotopic thinning ..." ); layer = 0; do { DigitalSet & S = shape2.pointSet(); std::queue<DigitalSet::Iterator> Q; for ( DigitalSet::Iterator it = S.begin(); it != S.end(); ++it ) if ( shape2.isSimple( *it ) ) Q.push( it ); nb_simple = 0; while ( ! Q.empty() ) { DigitalSet::Iterator it = Q.front(); Q.pop(); if ( shape2.isSimple( *it ) ) { board2 << CustomStyle( it->styleName(), new MyDrawStyleCustomFillColor ( cmap_grad( layer ) ) ) << *it; S.erase( *it ); ++nb_simple; } } ++layer; } while ( nb_simple != 0 ); trace.endBlock(); board << CustomStyle( shape.styleName(), new MyDrawStyleCustomRed ) << shape; board.saveSVG( "shape-thinning-4-8.svg"); board.clear(); board2 << CustomStyle( shape2.styleName(), new MyDrawStyleCustomRed ) << shape2; board2.saveSVG( "shape-thinning-8-4.svg"); board2.clear(); return nbok == nb; }
int main( int /*argc*/, char** /*argv*/ ) { trace.beginBlock ( "Example voronoimap2D" ); //! [Voro2D-Metric] typedef ExactPredicateLpSeparableMetric<Z2i::Space, 2> L2Metric; L2Metric l2; //! [Voro2D-Metric] //! [Voro2D-SmallImage] Z2i::Point lower(0,0); Z2i::Point upper(16,16); Z2i::Domain domain(lower,upper); Z2i::DigitalSet set(domain); set.insertNew(Z2i::Point(2,3)); set.insertNew(Z2i::Point(7,15)); set.insertNew(Z2i::Point(12,5)); Board2D board; board<< domain << set; board.saveSVG("voronoimap-inputset.svg"); //! [Voro2D-SmallImage] //! [Voro2D-Predicate] typedef NotPointPredicate<Z2i::DigitalSet> NotPredicate; NotPredicate notSetPred(set); //! [Voro2D-Predicate] //! [Voro2D-Voro] typedef VoronoiMap<Z2i::Space, NotPredicate, L2Metric > Voronoi2D; Voronoi2D voronoimap(domain,notSetPred,l2); //! [Voro2D-Voro] //! [Voro2D-trace] board.clear(); board << domain; for(Voronoi2D::Domain::ConstIterator it = voronoimap.domain().begin(), itend = voronoimap.domain().end(); it != itend; ++it) { Voronoi2D::Value site = voronoimap( *it ); //closest site to (*it) if (site != (*it)) Display2DFactory::draw( board, site - (*it), (*it)); //Draw an arrow } board.saveSVG("voronoimap-voro.svg"); //! [Voro2D-trace] //! [Voro2D-traceCell] board.clear(); for(Voronoi2D::Domain::ConstIterator it = voronoimap.domain().begin(), itend = voronoimap.domain().end(); it != itend; ++it) { Voronoi2D::Value site = voronoimap( *it ); //closest site to (*it) unsigned char c = (site[1]*13 + site[0] * 7) % 256; //basic hashfunction board << CustomStyle( (*it).className(), new CustomColors(Color(c,c,c),Color(c,c,c))) << (*it); } board.saveSVG("voronoimap-cells.svg"); //! [Voro2D-traceCell] //! [Voro2D-l8Metric] typedef ExactPredicateLpSeparableMetric<Z2i::Space, 8> L8Metric; L8Metric l8; typedef VoronoiMap<Z2i::Space, NotPredicate, L8Metric > Voronoi2D_l8; Voronoi2D_l8 voronoimap_l8(domain,notSetPred,l8); board.clear(); board << domain; for(Voronoi2D_l8::Domain::ConstIterator it = voronoimap_l8.domain().begin(), itend = voronoimap_l8.domain().end(); it != itend; ++it) { Voronoi2D::Value site = voronoimap_l8( *it ); //closest site to (*it) unsigned char c = (site[1]*13 + site[0] * 7) % 256; //basic hashfunction board << CustomStyle( (*it).className(), new CustomColors(Color(c,c,c),Color(c,c,c))) << (*it); } board.saveSVG("voronoimap-vorol8.svg"); //! [Voro2D-l8Metric] //! [Voro2D-DT] typedef DistanceTransformation<Z2i::Space, NotPredicate, L2Metric > DT; DT dt(domain,notSetPred,l2); board.clear(); board << domain; //Fast max computation on the range value DT::Value maxDT=0.0; for(DT::ConstRange::ConstIterator it = dt.constRange().begin(), itend = dt.constRange().end(); it != itend ; ++it) if ((*it)>maxDT) maxDT = (*it); //Colormap HueShadeColorMap<DT::Value,1> hueMap(0.0,maxDT); //Drawing for(DT::Domain::ConstIterator it = dt.domain().begin(), itend = dt.domain().end(); it != itend; ++it) { DT::Value dist = dt( *it ); //distance to closest site to (*it) board << CustomStyle( (*it).className(), new CustomColors( hueMap(dist), hueMap(dist))) << (*it); } board.saveSVG("voronoimap-dt.svg"); //! [Voro2D-DT] trace.endBlock(); return 0; }
/** * 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 testImageAdapter() { unsigned int nbok = 0; unsigned int nb = 0; trace.beginBlock ("Testing ImageAdapter"); typedef ImageContainerBySTLVector< Z2i::Domain, unsigned char> VImage; typedef GrayscaleColorMap<unsigned char> Gray; string filename = testPath + "samples/church-small.pgm"; VImage image = PGMReader<VImage>::importPGM(filename); trace.info() << "Imported image: " << image << endl; Board2D aBoard; Display2DFactory::drawImage<Gray>(aBoard, image, (unsigned char)0, (unsigned char)255); aBoard.saveSVG("church.svg"); #ifdef WITH_CAIRO aBoard.saveCairo("church.png", Board2D::CairoPNG); #endif typedef ImageAdapter<VImage, Z2i::Domain, DefaultFunctor, VImage::Value, DefaultFunctor, DefaultFunctor> MyImageAdapter; BOOST_CONCEPT_ASSERT(( CImage< MyImageAdapter > )); nbok += true ? 1 : 0; nb++; // 1) bell_tower //! [ImageAdapterWithSubdomain] Z2i::Point p1( 43, 107 ); Z2i::Point p2( 73, 177 ); Z2i::Domain domain_bell_tower( p1, p2 ); DefaultFunctor idbtD, idbtV, idbtVm1; MyImageAdapter bell_tower(image, domain_bell_tower, idbtD, idbtV, idbtVm1); //! [ImageAdapterWithSubdomain] trace.info() << "ImageAdapter: " << bell_tower << " " << bell_tower.domain() << std::endl; nbok += bell_tower.isValid() ? 1 : 0; nb++; aBoard.clear(); Display2DFactory::drawImage<Gray>(aBoard, bell_tower, (unsigned char)0, (unsigned char)255); aBoard.saveSVG("bell_tower.svg"); #ifdef WITH_CAIRO aBoard.saveCairo("bell_tower.png", Board2D::CairoPNG); #endif // 2) cars Z2i::Point p3( 0, 49 ); Z2i::Point p4( 58, 72 ); Z2i::Domain domain_cars( p3, p4 ); DefaultFunctor idcD; DefaultFunctor idcV; DefaultFunctor idcVm1; MyImageAdapter cars(image, domain_cars, idcD, idcV, idcVm1); trace.info() << "ImageAdapter: " << cars << " " << cars.domain() << std::endl; nbok += cars.isValid() ? 1 : 0; nb++; aBoard.clear(); Display2DFactory::drawImage<Gray>(aBoard, cars, (unsigned char)0, (unsigned char)255); aBoard.saveSVG("cars.svg"); #ifdef WITH_CAIRO aBoard.saveCairo("cars.png", Board2D::CairoPNG); #endif // 3) fill 255 for 'bell_tower' image MyImageAdapter::Domain::ConstIterator bt_it = bell_tower.domain().begin(); MyImageAdapter::Domain::ConstIterator bt_itEnd = bell_tower.domain().end(); for (; bt_it != bt_itEnd; ++bt_it) { bell_tower.setValue(*bt_it, 255); } aBoard.clear(); Display2DFactory::drawImage<Gray>(aBoard, bell_tower, (unsigned char)0, (unsigned char)255); aBoard.saveSVG("bell_tower_after_filling.svg"); #ifdef WITH_CAIRO aBoard.saveCairo("bell_tower_after_filling.png", Board2D::CairoPNG); #endif // 4) fill 55 for 'cars' image MyImageAdapter::Domain::ConstIterator c_it = cars.domain().begin(); MyImageAdapter::Domain::ConstIterator c_itEnd = cars.domain().end(); for (; c_it != c_itEnd; ++c_it) { cars.setValue(*c_it, 55); } aBoard.clear(); Display2DFactory::drawImage<Gray>(aBoard, cars, (unsigned char)0, (unsigned char)255); aBoard.saveSVG("cars_after_filling.svg"); #ifdef WITH_CAIRO aBoard.saveCairo("cars_after_filling.png", Board2D::CairoPNG); #endif // 5) fill 0 (only for one pixel on two) for 'floor_lamp' image //! [ImageAdapterWithSpecificDomain] Z2i::Point p5( 56, 33 ); Z2i::Point p6( 68, 79 ); Z2i::Domain domain_floor_lamp( p5, p6 ); // --- DigitalSetDomain Z2i::DigitalSet mySet( domain_floor_lamp ); unsigned int i = 0; for ( Z2i::Domain::ConstIterator it = domain_floor_lamp.begin() ; it != domain_floor_lamp.end(); ++it, ++i ) { if (i%2) mySet.insertNew( *it ); } DigitalSetDomain<Z2i::DigitalSet> my_specific_domain_floor_lamp(mySet); // --- DigitalSetDomain typedef ImageAdapter<VImage, DigitalSetDomain<Z2i::DigitalSet>, DefaultFunctor, VImage::Value, DefaultFunctor, DefaultFunctor> MyImageAdapter2; // BOOST_CONCEPT_ASSERT(( CImage< MyImageAdapter2 > )); // pb here DefaultFunctor idflD, idflV, idflVm1; MyImageAdapter2 floor_lamp(image, my_specific_domain_floor_lamp, idflD, idflV, idflVm1); //! [ImageAdapterWithSpecificDomain] trace.info() << "ImageAdapter: " << floor_lamp << " " << floor_lamp.domain() << std::endl; nbok += floor_lamp.isValid() ? 1 : 0; nb++; aBoard.clear(); Display2DFactory::drawImage<Gray>(aBoard, floor_lamp, (unsigned char)0, (unsigned char)255); aBoard.saveSVG("floor_lamp.svg"); #ifdef WITH_CAIRO aBoard.saveCairo("floor_lamp.png", Board2D::CairoPNG); #endif MyImageAdapter2::Domain::ConstIterator f_it = floor_lamp.domain().begin(); MyImageAdapter2::Domain::ConstIterator f_itEnd = floor_lamp.domain().end(); for (; f_it != f_itEnd; ++f_it) { floor_lamp.setValue(*f_it, 0); } aBoard.clear(); Display2DFactory::drawImage<Gray>(aBoard, floor_lamp, (unsigned char)0, (unsigned char)255); aBoard.saveSVG("floor_lamp_after_filling.svg"); #ifdef WITH_CAIRO aBoard.saveCairo("floor_lamp_after_filling.png", Board2D::CairoPNG); #endif aBoard.clear(); Display2DFactory::drawImage<Gray>(aBoard, image, (unsigned char)0, (unsigned char)255); aBoard.saveSVG("church_after_filling.svg"); #ifdef WITH_CAIRO aBoard.saveCairo("church_after_filling.png", Board2D::CairoPNG); #endif trace.info() << "(" << nbok << "/" << nb << ") " << "true == true" << endl; trace.endBlock(); return nbok == nb; }
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 testDistanceTransformationBorder() { 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); DistanceTransformation<Image, 2> dt; typedef DistanceTransformation<Image, 2>::OutputImage ImageLong; dt.checkTypesValidity ( image ); Board2D board; board.setUnit ( LibBoard::Board::UCentimeter ); image.selfDraw<Hue> ( board, 0, 150 ); board.saveSVG ( "image-preDT-border.svg" ); ImageLong result = dt.compute ( image ); DGtal::uint64_t maxv = 0; for ( ImageLong::Iterator it = result.begin(), itend = result.end();it != itend; ++it) if ( (*it) > maxv) maxv = (*it); ImageLong::ConstIterator it = result.begin(); for (unsigned int y = 0; y < 33; y++) { for (unsigned int x = 0; x < 33; x++) { std::cout << std::setw(4) << result(it) << " "; ++it; } std::cout << std::endl; } trace.warning() << result << "MaxV = " << maxv << endl; board.clear(); result.selfDraw<Hue> ( board, 0, maxv + 1); board.saveSVG ( "image-postDT-border.svg" ); trace.info() << result << endl; trace.endBlock(); return nbok == nb; }
bool testDTFromSet() { unsigned int nbok = 0; unsigned int nb = 0; trace.beginBlock ( "Testing the whole DT computation from a Set" ); typedef SpaceND<2> TSpace; typedef TSpace::Point Point; typedef HyperRectDomain<TSpace> Domain; typedef ImageSelector<Domain, unsigned int>::Type Image; typedef HueShadeColorMap<DGtal::uint64_t, 2> Hue; DistanceTransformation<Image, 2> dt; typedef DistanceTransformation<Image, 2>::OutputImage ImageLong; DistanceTransformation<Image, 0> dt0; typedef DistanceTransformation<Image, 0>::OutputImage ImageLong0; DistanceTransformation<Image, 1> dt1; typedef DistanceTransformation<Image, 1>::OutputImage ImageLong1; Board2D board; AccFlower2D<Z2i::Space> flower(Z2i::Point(0,0), 30, 5,2,0); Z2i::Domain domain(flower.getLowerBound(), flower.getUpperBound()); Z2i::DigitalSet aSet(domain); Shapes<Z2i::Domain>::shaper(aSet, flower); ImageLong result = dt.compute ( aSet ); ImageLong0 result0 = dt0.compute ( aSet ); ImageLong1 result1 = dt1.compute ( aSet ); trace.warning() << result << endl; DGtal::int64_t maxv = 0; for ( ImageLong::Iterator it = result.begin(), itend = result.end(); it != itend; ++it) if ( (*it) > maxv) maxv = (*it); trace.error() << "MaxV="<<maxv<<std::endl; result.selfDraw<Hue> ( board, 0, maxv+1); board.saveSVG ( "image-DTSet.svg" ); board.clear(); maxv = 0; for ( ImageLong::Iterator it = result0.begin(), itend = result0.end(); it != itend; ++it) if ( (*it) > maxv) maxv = (*it); trace.error() << "MaxV="<<maxv<<std::endl; result0.selfDraw<Hue> ( board, 0, maxv+1); board.saveSVG ( "image-DTSet-linfty.svg" ); board.clear(); maxv = 0; for ( ImageLong::Iterator it = result1.begin(), itend = result1.end(); it != itend; ++it) if ( (*it) > maxv) maxv = (*it); trace.error() << "MaxV="<<maxv<<std::endl; result1.selfDraw<Hue> ( board, 0, maxv+1); board.saveSVG ( "image-DTSet-l1.svg" ); trace.endBlock(); return nbok == nb; }
/** * Algorithms that computes the convex hull * of a point set */ void convexHull() { //Digitization of a disk of radius 6 Ball2D<Z2i::Space> ball(Z2i::Point(0,0), 6); Z2i::Domain domain(ball.getLowerBound(), ball.getUpperBound()); Z2i::DigitalSet pointSet(domain); Shapes<Z2i::Domain>::euclideanShaper(pointSet, ball); //! [Hull2D-Namespace] using namespace functions::Hull2D; //! [Hull2D-Namespace] //! [Hull2D-Functor] typedef InHalfPlaneBySimple3x3Matrix<Z2i::Point, DGtal::int64_t> Functor; Functor functor; //! [Hull2D-Functor] { //convex hull in counter-clockwise order vector<Z2i::Point> res; //! [Hull2D-StrictPredicateCCW] typedef PredicateFromOrientationFunctor2<Functor, false, false> StrictPredicate; StrictPredicate predicate( functor ); //! [Hull2D-StrictPredicateCCW] //according to the last two template arguments, neither strictly negative values, nor zeros are accepted: //the predicate returns 'true' only for strictly positive values returned by the underlying functor. //! [Hull2D-AndrewAlgo] andrewConvexHullAlgorithm( pointSet.begin(), pointSet.end(), back_inserter( res ), predicate ); //! [Hull2D-AndrewAlgo] //![Hull2D-Caliper-computeBasic] double th = DGtal::functions::Hull2D::computeHullThickness(res.begin(), res.end(), DGtal::functions::Hull2D::HorizontalVerticalThickness); //![Hull2D-Caliper-computeBasic] //![Hull2D-Caliper-computeAnti] Z2i::Point antipodalP, antipodalQ, antipodalS; th = DGtal::functions::Hull2D::computeHullThickness(res.begin(), res.end(), DGtal::functions::Hull2D::HorizontalVerticalThickness, antipodalP, antipodalQ, antipodalS); //![Hull2D-Caliper-computeAnti] trace.info() <<" ConvexHull HV thickness: " << th << std::endl; //display Board2D board; drawPolygon( res.begin(), res.end(), board ); //![Hull2D-Caliper-display] board.setPenColor(DGtal::Color::Red); board.drawCircle( antipodalS[0], antipodalS[1], 0.2) ; board.setPenColor(DGtal::Color::Blue); board.drawCircle(antipodalP[0], antipodalP[1], 0.2); board.drawCircle(antipodalQ[0], antipodalQ[1], 0.2); board.drawLine(antipodalP[0], antipodalP[1], antipodalQ[0], antipodalQ[1]); //![Hull2D-Caliper-display] board.saveSVG( "ConvexHullCCW.svg" ); #ifdef WITH_CAIRO board.saveCairo("ConvexHullCCW.png", Board2D::CairoPNG); #endif } { //convex hull in counter-clockwise order with all the points lying on the edges vector<Z2i::Point> res; //! [Hull2D-LargePredicateCCW] typedef PredicateFromOrientationFunctor2<Functor, false, true> LargePredicate; LargePredicate predicate( functor ); //! [Hull2D-LargePredicateCCW] //according to the last template argument, zeros are accepted so that //the predicate returns 'true' for all the positive values returned by the underlying functor. //andrew algorithm andrewConvexHullAlgorithm( pointSet.begin(), pointSet.end(), back_inserter( res ), predicate ); //display Board2D board; drawPolygon( res.begin(), res.end(), board ); board.saveSVG( "ConvexHullCCWWithPointsOnEdges.svg" ); #ifdef WITH_CAIRO board.saveCairo("ConvexHullCCWWithPointsOnEdges.png", Board2D::CairoPNG); #endif } { //convex hull in clockwise order vector<Z2i::Point> res; //! [Hull2D-StrictPredicateCW] typedef PredicateFromOrientationFunctor2<Functor, true, false> StrictPredicate; StrictPredicate predicate( functor ); //! [Hull2D-StrictPredicateCW] //according to the last two argument template, //the predicate returns 'true' only for strictly negative values returned by the underlying functor. //andrew algorithm andrewConvexHullAlgorithm( pointSet.begin(), pointSet.end(), back_inserter( res ), predicate ); //display Board2D board; drawPolygon( res.begin(), res.end(), board ); board.saveSVG( "ConvexHullCW.svg" ); #ifdef WITH_CAIRO board.saveCairo("ConvexHullCW.png", Board2D::CairoPNG); #endif } { //convex hull in counter-clockwise order vector<Z2i::Point> res; //geometric predicate typedef PredicateFromOrientationFunctor2<Functor, false, false> StrictPredicate; StrictPredicate predicate( functor ); //! [Hull2D-GrahamAlgo] grahamConvexHullAlgorithm( pointSet.begin(), pointSet.end(), back_inserter( res ), predicate ); //! [Hull2D-GrahamAlgo] //display Board2D board; drawPolygon( res.begin(), res.end(), board ); board.saveSVG( "ConvexHullCCWbis.svg" ); #ifdef WITH_CAIRO board.saveCairo("ConvexHullCCWbis.png", Board2D::CairoPNG); #endif } { //convex hull of a simple polygonal line that is not weakly externally visible vector<Z2i::Point> polygonalLine; polygonalLine.push_back(Z2i::Point(0,0)); polygonalLine.push_back(Z2i::Point(0,4)); polygonalLine.push_back(Z2i::Point(1,4)); polygonalLine.push_back(Z2i::Point(1,1)); polygonalLine.push_back(Z2i::Point(3,1)); polygonalLine.push_back(Z2i::Point(2,2)); polygonalLine.push_back(Z2i::Point(3,4)); polygonalLine.push_back(Z2i::Point(4,4)); polygonalLine.push_back(Z2i::Point(4,0)); vector<Z2i::Point> resGraham, res; typedef PredicateFromOrientationFunctor2<Functor, false, false> StrictPredicate; StrictPredicate predicate( functor ); closedGrahamScanFromAnyPoint( polygonalLine.begin(), polygonalLine.end(), back_inserter( resGraham ), predicate ); //! [Hull2D-OnLineMelkmanAlgo] DGtal::MelkmanConvexHull<Z2i::Point, Functor> ch( functor ); for (std::vector<Z2i::Point>::const_iterator it = polygonalLine.begin(), itEnd = polygonalLine.end(); it != itEnd; ++it) ch.add( *it ); //! [Hull2D-OnLineMelkmanAlgo] //! [Hull2D-OffLineMelkmanAlgo] melkmanConvexHullAlgorithm( polygonalLine.begin(), polygonalLine.end(), back_inserter( res ), functor ); //! [Hull2D-OffLineMelkmanAlgo] //display Board2D board; drawPolygon( polygonalLine.begin(), polygonalLine.end(), board, true ); board.saveSVG( "SimplePolygonalLine.svg" ); #ifdef WITH_CAIRO board.saveCairo("SimplePolygonalLine.png", Board2D::CairoPNG); #endif board.clear(); drawPolygon( resGraham.begin(), resGraham.end(), board ); board.saveSVG( "SimplePolygonalLineGraham.svg" ); #ifdef WITH_CAIRO board.saveCairo("SimplePolygonalLineGraham.png", Board2D::CairoPNG); #endif board.clear(); drawPolygon( res.begin(), res.end(), board ); board.saveSVG( "SimplePolygonalLineMelkman.svg" ); #ifdef WITH_CAIRO board.saveCairo("SimplePolygonalLineMelkman.png", Board2D::CairoPNG); #endif board.clear(); drawPolygon( ch.begin(), ch.end(), board ); board.saveSVG( "SimplePolygonalLineMelkman2.svg" ); #ifdef WITH_CAIRO board.saveCairo("SimplePolygonalLineMelkman2.png", Board2D::CairoPNG); #endif } { //order of the points for andrew algorithm vector<Z2i::Point> res; std::copy( pointSet.begin(), pointSet.end(), back_inserter( res ) ); std::sort( res.begin(), res.end() ); //display Board2D board; drawPolygon( res.begin(), res.end(), board, false ); board.saveSVG( "AndrewWEVP.svg" ); #ifdef WITH_CAIRO board.saveCairo("AndrewWEVP.png", Board2D::CairoPNG); #endif } { //order of the points for graham algorithm vector<Z2i::Point> res; std::copy( pointSet.begin(), pointSet.end(), back_inserter( res ) ); //find an extremal point //NB: we choose the point of greatest x-coordinate //so that the sort step (by a polar comparator) //returns a weakly externally visible polygon std::vector<Z2i::Point>::iterator itMax = std::max_element( res.begin(), res.end() ); //sort around this point with a polar comparator functors::PolarPointComparatorBy2x2DetComputer<Z2i::Point> comparator; comparator.setPole( *itMax ); std::sort( res.begin(), res.end(), comparator ); //display Board2D board; drawPolygon( res.begin(), res.end(), board, false ); board.saveSVG( "GrahamWEVP.svg" ); #ifdef WITH_CAIRO board.saveCairo("GrahamWEVP.png", Board2D::CairoPNG); #endif } }
int main( ) { trace.beginBlock ( "Example dgtalboard-2-sets" ); Point p1( -10, -7 ); Point p2( 10, 7 ); Domain domain( p1, p2 ); DigitalSet shape_set( domain ); Shapes<Domain>::addNorm1Ball( shape_set, Point( -5, -1 ), 5 ); Shapes<Domain>::addNorm1Ball( shape_set, Point( 5, 1 ), 5 ); shape_set.erase( Point( -5, -1 ) ); shape_set.erase( Point( 5, 1 ) ); Board2D board; board << domain << shape_set; // display domain and set board.saveSVG( "dgtalboard-2-sets-1.svg"); board.saveEPS( "dgtalboard-2-sets-1.eps"); #ifdef WITH_CAIRO board.saveCairo("dgtalboard-2-sets-1-cairo.pdf", Board2D::CairoPDF); board.saveCairo("dgtalboard-2-sets-1-cairo.png", Board2D::CairoPNG); board.saveCairo("dgtalboard-2-sets-1-cairo.ps", Board2D::CairoPS); board.saveCairo("dgtalboard-2-sets-1-cairo.svg", Board2D::CairoSVG); #endif board.clear(); // Object with couple (4,8) of adjacency. Object4_8 shape( dt4_8, shape_set ); board << domain // display domain << SetMode( shape.styleName(), "DrawAdjacencies" ) << shape; // and object with mode "DrawAdjacencies" board.saveSVG( "dgtalboard-2-sets-2.svg"); board.saveEPS( "dgtalboard-2-sets-2.eps"); #ifdef WITH_CAIRO board.saveCairo("dgtalboard-2-sets-2-cairo.pdf", Board2D::CairoPDF); board.saveCairo("dgtalboard-2-sets-2-cairo.png", Board2D::CairoPNG); board.saveCairo("dgtalboard-2-sets-2-cairo.ps", Board2D::CairoPS); board.saveCairo("dgtalboard-2-sets-2-cairo.svg", Board2D::CairoSVG); #endif board.clear(); // Object with couple (8,4) of adjacency. Object8_4 shape2( dt8_4, shape_set ); board << domain // display domain << SetMode( shape2.styleName(), "DrawAdjacencies" ) << shape2; // and object with mode "DrawAdjacencies" board.saveSVG( "dgtalboard-2-sets-3.svg"); board.saveEPS( "dgtalboard-2-sets-3.eps"); #ifdef WITH_CAIRO board.saveCairo("dgtalboard-2-sets-3-cairo.pdf", Board2D::CairoPDF); board.saveCairo("dgtalboard-2-sets-3-cairo.png", Board2D::CairoPNG); board.saveCairo("dgtalboard-2-sets-3-cairo.ps", Board2D::CairoPS); board.saveCairo("dgtalboard-2-sets-3-cairo.svg", Board2D::CairoSVG); #endif trace.endBlock(); return 0; }
/** * 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; }
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; }
/** * 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; }
/** * 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 ( Domain(a, b )); for ( unsigned k = 0; k < 49; k++ ) { a[0] = ( k / 7 ) + 5; a[1] = ( k % 7 ) + 5; image.setValue ( a, 128 ); } a= Point(2,2); typedef SimpleThresholdForegroundPredicate<Image> Predicate; Predicate aPredicate(image,0); DistanceTransformation<TSpace, Predicate , 2> dt(Domain(a,b),aPredicate); typedef DistanceTransformation<TSpace, Predicate, 2>::OutputImage ImageLong; dt.checkTypesValidity ( ); Board2D board; board.setUnit ( LibBoard::Board::UCentimeter ); Display2DFactory::drawImage<Gray>(board, image, (unsigned int)0, (unsigned int)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 ( ); trace.warning() << result << endl; //We just iterate on the Domain points and print out the point coordinates. ImageLong::ConstIterator it = result.begin(); ImageLong::ConstIterator itend = result.end(); for (; it != itend; ++it) { std::cout << (*it) << " "; } std::cout << std::endl; board.clear(); Display2DFactory::drawImage<Gray>(board, result, (DGtal::int64_t)0, (DGtal::int64_t)16); board.saveSVG ( "image-postDT.svg" ); trace.info() << result << endl; trace.endBlock(); return nbok == nb; }
/** * @brief Function that illustrates the basic usage of * a standard DSS. */ void exampleStandardDSS() { trace.beginBlock ( "Standard DSS" ); using namespace Z2i; //! [ArithmeticalDSSStandardCtor] // Construct a standard DSS StandardDSS4<Integer> segment( 5, 8, //slope Point(0,0), Point(8,5), //ending points Point(0,0), Point(8,5), //upper points Point(4,1), Point(4,1) //lower points ); //! [ArithmeticalDSSStandardCtor] // Trace to the standard output trace.info() << segment << std::endl; // Display the DSS with a domain on a board Domain domain( Point(0,0), Point(8,5) ); Board2D board; //! [StandardDSS4DrawingUsage] // Draw the grid board << SetMode(domain.className(), "Grid") << domain; // Draw the points of the DSS board << SetMode("PointVector", "Grid") << SetMode(segment.className(), "Points") << segment; // Draw the bounding box board << SetMode(segment.className(), "BoundingBox") << segment; //! [StandardDSS4DrawingUsage] // Save board.saveSVG("StandardDSS4.svg"); #ifdef WITH_CAIRO board.saveCairo("StandardDSS4.png", Board2D::CairoPNG); #endif board.clear(); //! [ArithmeticalDSSDrawingUsage] // Draw the pixels board << SetMode(domain.className(), "Paving") << domain; //Draw the points of the DSS board << SetMode("PointVector", "Both"); board << SetMode(segment.className(), "Points") << segment; // Draw the bounding box board << SetMode(segment.className(), "BoundingBox") << segment; //! [ArithmeticalDSSDrawingUsage] board.saveSVG("StandardDSS4bis.svg"); #ifdef WITH_CAIRO board.saveCairo("StandardDSS4bis.png", Board2D::CairoPNG); #endif trace.endBlock(); }
/** * 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; }
int main( int /* argc */, char** /* argv */ ) { //! [cubical-complex-illustrations-X] using namespace DGtal::Z2i; typedef CubicalComplex< KSpace > CC; KSpace K; K.init( Point( 0,0 ), Point( 5,3 ), true ); trace.beginBlock( "Creating Cubical Complex" ); CC X( K ); Domain domain( Point( 0,0 ), Point( 5,3 ) ); X.insertCell( K.uSpel( Point(1,1) ) ); X.insertCell( K.uSpel( Point(2,1) ) ); X.insertCell( K.uSpel( Point(3,1) ) ); X.insertCell( K.uSpel( Point(2,2) ) ); X.insertCell( K.uSpel( Point(3,2) ) ); X.insertCell( K.uSpel( Point(4,2) ) ); X.close(); trace.endBlock(); trace.beginBlock( "Displays Cubical Complex" ); Board2D board; board << domain; board << CustomStyle( X.className(), new CustomColors( Color(80,80,100), Color(180,180,200) ) ) << X; board.saveTikZ( "cubical-complex-illustrations-X.tikz" ); trace.endBlock(); //! [cubical-complex-illustrations-X] //! [cubical-complex-illustrations-S] CC S( K ); S.insertCell( K.uCell( Point( 5, 4 ) ) ); // a linel S.insertCell( K.uCell( Point( 4, 4 ) ) ); // a pointel S.insertCell( K.uCell( Point( 7, 5 ) ) ); // a pixel board << CustomStyle( X.className(), new CustomColors( Color::Black, Color(60,60,60) ) ) << S; board.saveTikZ( "cubical-complex-illustrations-S.tikz" ); board.clear(); //! [cubical-complex-illustrations-S] //! [cubical-complex-illustrations-closure] board << domain; board << CustomStyle( X.className(), new CustomColors( Color(80,80,100), Color(180,180,200) ) ) << X; board << CustomStyle( X.className(), new CustomColors( Color::Red, Color(255,120,120) ) ) << X.closure( S ); board.saveTikZ( "cubical-complex-illustrations-closure.tikz" ); board.clear(); //! [cubical-complex-illustrations-closure] //! [cubical-complex-illustrations-star] board << domain; board << CustomStyle( X.className(), new CustomColors( Color(80,80,100), Color(180,180,200) ) ) << X; board << CustomStyle( X.className(), new CustomColors( Color::Blue, Color(120,120,255) ) ) << X.star( S ); board.saveTikZ( "cubical-complex-illustrations-star.tikz" ); board.clear(); //! [cubical-complex-illustrations-star] //! [cubical-complex-illustrations-link] board << domain; board << CustomStyle( X.className(), new CustomColors( Color(80,80,100), Color(180,180,200) ) ) << X; board << CustomStyle( X.className(), new CustomColors( Color::Green, Color(120,255,120) ) ) << X.link( S ); board.saveTikZ( "cubical-complex-illustrations-link.tikz" ); board.clear(); //! [cubical-complex-illustrations-link] //! [cubical-complex-illustrations-bd] board << domain; board << CustomStyle( X.className(), new CustomColors( Color(80,80,100), Color(180,180,200) ) ) << X; board << CustomStyle( X.className(), new CustomColors( Color::Magenta, Color(255,120,255) ) ) << X.boundary(); board.saveTikZ( "cubical-complex-illustrations-bd.tikz" ); board.clear(); //! [cubical-complex-illustrations-bd] //! [cubical-complex-illustrations-int] board << domain; board << CustomStyle( X.className(), new CustomColors( Color(80,80,100), Color(180,180,200) ) ) << X; board << CustomStyle( X.className(), new CustomColors( Color::Cyan, Color(120,255,255) ) ) << X.interior(); board.saveTikZ( "cubical-complex-illustrations-int.tikz" ); board.clear(); //! [cubical-complex-illustrations-int] //! [cubical-complex-illustrations-collapse] board << domain; board << CustomStyle( X.className(), new CustomColors( Color(80,80,100), Color(180,180,200) ) ) << X; Cell p1 = K.uCell( Point(2,2) ); Cell p2 = K.uCell( Point(10,6) ); X[ p1 ] = CC::FIXED; X[ p2 ] = CC::FIXED; CC::DefaultCellMapIteratorPriority P; functions::collapse( X, X.begin(), X.end(), P, true, true, true ); board << CustomStyle( X.className(), new CustomColors( Color(255,120,20), Color(255,150,50) ) ) << X << CustomStyle( p1.className(), new CustomColors( Color::Blue, Color(120,120,255) ) ) << p1 << p2; board.saveTikZ( "cubical-complex-illustrations-collapse.tikz" ); board.clear(); //! [cubical-complex-illustrations-collapse] return 0; }