bool testRaySurface() { typedef ImplicitBall<Z3i::Space> ImplicitShape; typedef GaussDigitizer<Z3i::Space, ImplicitShape> DigitalShape; typedef LightImplicitDigitalSurface<Z3i::KSpace,DigitalShape> Boundary; typedef DigitalSurface< Boundary > MyDigitalSurface; trace.beginBlock(" Ray shooting in digital surface"); trace.beginBlock( "Shape initialisation ..." ); ImplicitShape ishape( Z3i::RealPoint( 0, 0 ,0), 12 ); DigitalShape dshape; dshape.attach( ishape ); dshape.init( Z3i::RealPoint( -20.0, -20.0 ,-20.0 ), Z3i::RealPoint( 20.0, 20.0, 20.0 ), 1.0 ); Z3i::KSpace K; if ( !K.init( dshape.getLowerBound(), dshape.getUpperBound(), true ) ) { trace.error() << "Problem with Khalimsky space init" << std::endl; return false; } Z3i::KSpace::Surfel bel = Surfaces<Z3i::KSpace>::findABel( K, dshape, 10000 ); Boundary boundary( K, dshape, SurfelAdjacency<Z3i::KSpace::dimension>( true ), bel ); MyDigitalSurface surf ( boundary ); trace.endBlock(); trace.beginBlock(" Ray shooting the shape"); RayIntersectionPredicate<Z3i::KSpace::Cell::Point> ray(Z3i::KSpace::Cell::Point(0,0,0), Z3i::KSpace::Cell::Point(2,2,2)); RayIntersectionPredicate<Z3i::KSpace::Cell::Point> ray2(Z3i::KSpace::Cell::Point(0,0,0), Z3i::KSpace::Cell::Point(1,0,0)); MyDigitalSurface::ConstIterator it = std::find_if(surf.begin(), surf.end(), ray); trace.info() << "Ray shooting returns : "<< *it<<std::endl; MyDigitalSurface::ConstIterator it2 = std::find_if(surf.begin(), surf.end(), ray2); trace.info() << "Ray shooting returns : "<< *it2<<std::endl; trace.endBlock(); trace.endBlock(); return true; }
int main() { const double h = 1; const double radiusBall = 12.0; trace.beginBlock( "Make parametric shape..." ); typedef Ball3D< Z3i::Space > Shape; RealPoint center( 0.0, 0.0, 0.0 ); Shape ball( center, radiusBall ); RealPoint centerBis(18.0,0.0,0.0); Shape ballBis( centerBis, radiusBall); trace.endBlock(); trace.beginBlock( "Make digital shape..." ); typedef GaussDigitizer< Z3i::Space, Shape > DigitalShape; typedef DigitalShape::Domain Domain; DigitalShape digitalBall; digitalBall.attach( ball ); digitalBall.init( ball.getLowerBound() - Z3i::RealPoint( 1.0, 1.0, 1.0 ), ball.getUpperBound() + Z3i::RealPoint( 1.0, 1.0, 1.0 ), h ); DigitalShape digitalBallBis; digitalBallBis.attach( ballBis ); digitalBallBis.init( ballBis.getLowerBound() - Z3i::RealPoint( 1.0, 1.0, 1.0 ), ballBis.getUpperBound() + Z3i::RealPoint( 1.0, 1.0, 1.0 ), h ); Domain domain( digitalBall.getDomain().lowerBound().inf( digitalBallBis.getDomain().lowerBound() ), digitalBall.getDomain().upperBound().sup( digitalBallBis.getDomain().upperBound() )); Z3i::KSpace kspace; kspace.init( domain.lowerBound(), domain.upperBound(), true ); trace.info()<< domain <<std::endl; trace.endBlock(); trace.beginBlock( "Make first digital surface..." ); typedef LightImplicitDigitalSurface< Z3i::KSpace, DigitalShape > LightDigitalSurface; typedef DigitalSurface< LightDigitalSurface > DigitalSurface; typedef Z3i::KSpace::Surfel Surfel; Surfel bel = Surfaces< Z3i::KSpace >::findABel( kspace, digitalBall, 500 ); SurfelAdjacency< Z3i::KSpace::dimension > surfelAdjacency( true ); LightDigitalSurface lightDigitalSurface( kspace, digitalBall, surfelAdjacency, bel ); DigitalSurface digitalSurface( lightDigitalSurface ); bel = Surfaces< Z3i::KSpace >::findABel( kspace, digitalBallBis, 500 ); LightDigitalSurface lightDigitalSurfaceBis( kspace, digitalBallBis, surfelAdjacency, bel ); DigitalSurface digitalSurfaceBis( lightDigitalSurfaceBis ); trace.endBlock(); std::set<Surfel> storage; trace.beginBlock("Exporting the first ball"); std::ofstream handle("output.csv"); for(auto cell : digitalSurface) { const Point p = kspace.sKCoords(cell); if (p[0] < -7.5) continue; const KSpace::Sign sign = kspace.sSign(cell); for (int dim=0; dim<3; dim++) handle << p[dim] << " "; handle << ( sign == KSpace::POS ) << " "; for (int dim=0; dim<3; ++dim) handle << (p-center)[dim]<<" "; handle << std::endl; //std::cout << "exporting "<< cell<<std::endl; storage.insert( cell ); } trace.endBlock(); trace.beginBlock("Exporting the second ball"); for(auto cell : digitalSurfaceBis) { if (storage.find(cell) != storage.end()) continue; const Point p = kspace.sKCoords(cell); const KSpace::Sign sign = kspace.sSign(cell); // "2.0*" to map centerbis to Kspace const RealPoint normal = (p-2.0*centerBis).getNormalized(); for (int dim=0; dim<3; dim++) handle << p[dim] << " "; handle << ( sign == KSpace::POS ) << " "; for (int dim=0; dim<3; ++dim) handle << normal[dim] <<" "; handle << std::endl; //std::cout << "exporting "<< cell<<std::endl; } trace.endBlock(); handle.close(); return 0; }
int main( int argc, char** argv ) { trace.beginBlock ( "Example ctopo-2-3d" ); // for 3D display with Viewer3D QApplication application(argc,argv); typedef ImageSelector < Z3i::Domain, int>::Type Image; std::string inputFilename = examplesPath + "samples/cat10.vol"; Image image = VolReader<Image>::importVol(inputFilename); Z3i::DigitalSet set3d (image.domain()); SetPredicate<Z3i::DigitalSet> set3dPredicate( set3d ); SetFromImage<Z3i::DigitalSet>::append<Image>(set3d, image, 0,255); Viewer3D viewer; viewer.show(); // Construct the Khalimsky space from the image domain Z3i::KSpace ks; bool space_ok = ks.init( image.domain().lowerBound(), image.domain().upperBound(), true ); ASSERT(space_ok); std::vector<Z3i::SCell> vectBdrySCell; std::vector<Z3i::SCell> vectBdrySCell2; std::set<Z3i::SCell> vectBdrySCellALL; SurfelAdjacency<3> SAdj( true ); //Extract an initial boundary cell Z3i::SCell aCell = Surfaces<Z3i::KSpace>::findABel(ks, set3dPredicate); // Extracting all boundary surfels which are connected to the initial boundary Cell. Surfaces<Z3i::KSpace>::trackBoundary( vectBdrySCellALL, ks,SAdj, set3dPredicate, aCell ); // Extract the bondary contour associated to the initial surfel in its first direction Surfaces<Z3i::KSpace>::track2DBoundary( vectBdrySCell, ks, *(ks.sDirs( aCell )), SAdj, set3dPredicate, aCell ); // Extract the bondary contour associated to the initial surfel in its second direction Surfaces<Z3i::KSpace>::track2DBoundary( vectBdrySCell2, ks, *(++(ks.sDirs( aCell ))), SAdj, set3dPredicate, aCell ); // Displaying all the surfels in transparent mode viewer << SetMode3D((*(vectBdrySCellALL.begin())).styleName(), "Transparent"); for( std::set<Z3i::SCell>::iterator it=vectBdrySCellALL.begin(); it!= vectBdrySCellALL.end(); it++){ viewer<< *it; } // Displaying First surfels cut with gradient colors.; GradientColorMap<int> cmap_grad( 0, vectBdrySCell2.size() ); cmap_grad.addColor( Color( 50, 50, 255 ) ); cmap_grad.addColor( Color( 255, 0, 0 ) ); cmap_grad.addColor( Color( 255, 255, 10 ) ); // Need to avoid surfel superposition (the surfel size in increased) viewer << Viewer3D::shiftSurfelVisu; viewer << SetMode3D((*(vectBdrySCell2.begin())).styleName(), ""); viewer.setFillColor(Color(180, 200, 25, 255)); int d=0; for( std::vector<Z3i::SCell>::iterator it=vectBdrySCell2.begin(); it!= vectBdrySCell2.end(); it++){ Color col= cmap_grad(d); viewer.setFillColor(Color(col.red(),col.green() ,col.blue(), 255)); viewer<< *it; d++; } GradientColorMap<int> cmap_grad2( 0, vectBdrySCell.size() ); cmap_grad2.addColor( Color( 50, 50, 255 ) ); cmap_grad2.addColor( Color( 255, 0, 0 ) ); cmap_grad2.addColor( Color( 255, 255, 10 ) ); d=0; for( std::vector<Z3i::SCell>::iterator it=vectBdrySCell.begin(); it!= vectBdrySCell.end(); it++){ Color col= cmap_grad2(d); viewer.setFillColor(Color(col.red(),col.green() ,col.blue(), 255)); viewer<< *it; d++; } // On need once again to avoid superposition. viewer << Viewer3D::shiftSurfelVisu; viewer.setFillColor(Color(18, 200, 25, 255)); viewer << aCell ; viewer << Viewer3D::updateDisplay; return application.exec(); }
/** * Example of a test. To be completed. * */ bool testEstimatorCache(double h) { unsigned int nbok = 0; unsigned int nb = 0; typedef ImplicitBall<Z3i::Space> ImplicitShape; typedef GaussDigitizer<Z3i::Space, ImplicitShape> DigitalShape; typedef LightImplicitDigitalSurface<Z3i::KSpace,DigitalShape> Boundary; typedef DigitalSurface< Boundary > MyDigitalSurface; typedef DepthFirstVisitor< MyDigitalSurface > Visitor; typedef GraphVisitorRange< Visitor > VisitorRange; typedef VisitorRange::ConstIterator VisitorConstIterator; typedef functors::IIGaussianCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator< Z3i::KSpace, DigitalShape, MyIICurvatureFunctor > MyIICurvatureEstimator; // typedef MyIICurvatureFunctor::Value Value; double re = 5.0; double radius = 5.0; trace.beginBlock( "Shape initialisation ..." ); ImplicitShape ishape( Z3i::RealPoint( 0, 0, 0 ), radius ); DigitalShape dshape; dshape.attach( ishape ); dshape.init( Z3i::RealPoint( -10.0, -10.0, -10.0 ), Z3i::RealPoint( 10.0, 10.0, 10.0 ), h ); Z3i::KSpace K; if ( !K.init( dshape.getLowerBound(), dshape.getUpperBound(), true ) ) { trace.error() << "Problem with Khalimsky space" << std::endl; return false; } Z3i::KSpace::Surfel bel = Surfaces<Z3i::KSpace>::findABel( K, dshape, 10000 ); Boundary boundary( K, dshape, SurfelAdjacency<Z3i::KSpace::dimension>( true ), bel ); MyDigitalSurface surf ( boundary ); trace.endBlock(); trace.beginBlock( "Curvature estimator computation ..."); VisitorRange range( new Visitor( surf, *surf.begin() )); VisitorConstIterator ibegin = range.begin(); VisitorConstIterator iend = range.end(); MyIICurvatureFunctor curvatureFunctor; curvatureFunctor.init( h, re ); MyIICurvatureEstimator curvatureEstimator( curvatureFunctor ); curvatureEstimator.attach( K, dshape ); curvatureEstimator.setParams( re/h ); curvatureEstimator.init( h, ibegin, iend ); std::vector<MyIICurvatureEstimator::Quantity> results; std::back_insert_iterator< std::vector<MyIICurvatureEstimator::Quantity> > itback(results); curvatureEstimator.eval(ibegin,iend,itback); trace.info() << "Number of values = "<< results.size()<<std::endl; trace.endBlock(); trace.beginBlock( "Caching values ..."); VisitorRange range2( new Visitor( surf, *surf.begin() )); VisitorConstIterator ibegin2 = range2.begin(); VisitorConstIterator iend2 = range2.end(); typedef EstimatorCache<MyIICurvatureEstimator> GaussianCache; BOOST_CONCEPT_ASSERT(( concepts::CSurfelLocalEstimator<GaussianCache> )); GaussianCache cache( curvatureEstimator ); cache.init( h, ibegin2, iend2 ); trace.info() << "Number of cached values = "<< cache.size()<<std::endl; trace.info() << "Value at begin="<< cache.eval(surf.begin())<<" expected = "<< curvatureEstimator.eval(surf.begin())<<std::endl; trace.endBlock(); trace.beginBlock( "Complete test ..."); bool ok=true; for(MyDigitalSurface::ConstIterator it = surf.begin(), itend=surf.end(); it != itend; ++it) { if ( cache.eval(it) != curvatureEstimator.eval(it) ) { ok=false; trace.error() << "Incorrect values at "<<*it<<" read " <<cache.eval(it)<< " and expecting "<<curvatureEstimator.eval(it)<<std::endl; } } trace.endBlock(); trace.beginBlock( "Timing cache access ..."); for(MyDigitalSurface::ConstIterator it = surf.begin(), itend=surf.end(); it != itend; ++it) { if ( cache.eval(it) == 12345678 ) //making sure to visit //all surfels { ok=false; trace.error() << "Incorrect values at "<<*it<<std::endl; } } trace.endBlock(); trace.beginBlock( "Copy construction and timing cache access ..."); GaussianCache cache2(cache); trace.info() << "Number of cached values = "<< cache.size()<<std::endl; trace.info() << "Value at begin="<< cache2.eval(surf.begin())<<" expected = "<< curvatureEstimator.eval(surf.begin())<<std::endl; for(MyDigitalSurface::ConstIterator it = surf.begin(), itend=surf.end(); it != itend; ++it) { if ( cache.eval(it) == 12345678 ) //making sure to visit //all surfels { ok=false; trace.error() << "Incorrect values at "<<*it<<std::endl; } } trace.endBlock(); nbok += ok ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << "cache == eval" << std::endl; return nbok == nb; }
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 >(), ".vol file") ("radius,r", po::value< double >(), "Kernel radius for IntegralInvariant" ) ("threshold,t", po::value< unsigned int >()->default_value(8), "Min size of SCell boundary of an object" ) ("minImageThreshold,l", po::value< int >()->default_value(0), "set the minimal image threshold to define the image object (object defined by the voxel with intensity belonging to ]minImageThreshold, maxImageThreshold ] )." ) ("maxImageThreshold,u", po::value< int >()->default_value(255), "set the minimal image threshold to define the image object (object defined by the voxel with intensity belonging to ]minImageThreshold, maxImageThreshold] )." ) ("mode,m", po::value< std::string >()->default_value("mean"), "type of output : mean, gaussian, k1, k2, prindir1, prindir2 or normal (default mean)") ("exportOBJ,o", po::value< std::string >(), "Export the scene to specified OBJ/MTL filename (extensions added)." ) ("exportDAT,d", po::value<std::string>(), "Export resulting curvature (for mean, gaussian, k1 or k2 mode) in a simple data file each line representing a surfel. ") ("exportOnly", "Used to only export the result without the 3d Visualisation (usefull for scripts)." ) ("imageScale,s", po::value<std::vector<double> >()->multitoken(), "scaleX, scaleY, scaleZ: re sample the source image according with a grid of size 1.0/scale (usefull to compute curvature on image defined on anisotropic grid). Set by default to 1.0 for the three axis. ") ("normalization,n", "When exporting to OBJ, performs a normalization so that the geometry fits in [-1/2,1/2]^3") ; 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.error() << " Error checking program options: " << ex.what() << std::endl; } bool neededArgsGiven=true; if (parseOK && !(vm.count("input"))){ missingParam("--input"); neededArgsGiven=false; } if (parseOK && !(vm.count("radius"))){ missingParam("--radius"); neededArgsGiven=false; } bool normalization = false; if (parseOK && vm.count("normalization")) normalization = true; std::string mode; if( parseOK ) mode = vm["mode"].as< std::string >(); if ( parseOK && ( mode.compare("gaussian") != 0 ) && ( mode.compare("mean") != 0 ) && ( mode.compare("k1") != 0 ) && ( mode.compare("k2") != 0 ) && ( mode.compare("prindir1") != 0 ) && ( mode.compare("prindir2") != 0 ) && ( mode.compare("normal") != 0 )) { parseOK = false; trace.error() << " The selected mode ("<<mode << ") is not defined."<<std::endl; } #ifndef WITH_VISU3D_QGLVIEWER bool enable_visu = false; #else bool enable_visu = !vm.count("exportOnly"); ///<! Default QGLViewer viewer. Disabled if exportOnly is set. #endif bool enable_obj = vm.count("exportOBJ"); ///<! Export to a .obj file. bool enable_dat = vm.count("exportDAT"); ///<! Export to a .dat file. if( !enable_visu && !enable_obj && !enable_dat ) { #ifndef WITH_VISU3D_QGLVIEWER trace.error() << "You should specify what you want to export with --export and/or --exportDat." << std::endl; #else trace.error() << "You should specify what you want to export with --export and/or --exportDat, or remove --exportOnly." << std::endl; #endif neededArgsGiven = false; } if(!neededArgsGiven || !parseOK || vm.count("help") || argc <= 1 ) { trace.info()<< "Visualisation of 3d curvature from .vol file using curvature from Integral Invariant" <<std::endl << general_opt << "\n" << "Basic usage: "<<std::endl << "\t3dCurvatureViewer -i file.vol --radius 5 --mode mean"<<std::endl << std::endl << "Below are the different available modes: " << std::endl << "\t - \"mean\" for the mean curvature" << std::endl << "\t - \"gaussian\" for the Gaussian curvature" << std::endl << "\t - \"k1\" for the first principal curvature" << std::endl << "\t - \"k2\" for the second principal curvature" << std::endl << "\t - \"prindir1\" for the first principal curvature direction" << std::endl << "\t - \"prindir2\" for the second principal curvature direction" << std::endl << "\t - \"normal\" for the normal vector" << std::endl << std::endl; return 0; } unsigned int threshold = vm["threshold"].as< unsigned int >(); int minImageThreshold = vm["minImageThreshold"].as< int >(); int maxImageThreshold = vm["maxImageThreshold"].as< int >(); double h = 1.0; std::string export_obj_filename; std::string export_dat_filename; if( enable_obj ) { export_obj_filename = vm["exportOBJ"].as< std::string >(); if( export_obj_filename.find(".obj") == std::string::npos ) { std::ostringstream oss; oss << export_obj_filename << ".obj" << std::endl; export_obj_filename = oss.str(); } } if( enable_dat ) { export_dat_filename = vm["exportDAT"].as<std::string>(); } double re_convolution_kernel = vm["radius"].as< double >(); std::vector< double > aGridSizeReSample; if( vm.count( "imageScale" )) { std::vector< double> vectScale = vm["imageScale"].as<std::vector<double > >(); if( vectScale.size() != 3 ) { trace.error() << "The grid size should contains 3 elements" << std::endl; return 0; } else { aGridSizeReSample.push_back(1.0/vectScale.at(0)); aGridSizeReSample.push_back(1.0/vectScale.at(1)); aGridSizeReSample.push_back(1.0/vectScale.at(2)); } } else { aGridSizeReSample.push_back(1.0); aGridSizeReSample.push_back(1.0); aGridSizeReSample.push_back(1.0); } // Construction of the shape from vol file typedef Z3i::Space::RealPoint RealPoint; typedef Z3i::Point Point; typedef ImageSelector< Z3i::Domain, int>::Type Image; typedef DGtal::functors::BasicDomainSubSampler< HyperRectDomain<SpaceND<3, int> >, DGtal::int32_t, double > ReSampler; typedef DGtal::ConstImageAdapter<Image, Image::Domain, ReSampler, Image::Value, DGtal::functors::Identity > SamplerImageAdapter; typedef IntervalForegroundPredicate< SamplerImageAdapter > ImagePredicate; typedef BinaryPointPredicate<DomainPredicate<Image::Domain>, ImagePredicate, AndBoolFct2 > Predicate; typedef Z3i::KSpace KSpace; typedef KSpace::SCell SCell; typedef KSpace::Cell Cell; trace.beginBlock("Loading the file"); std::string filename = vm["input"].as< std::string >(); Image image = GenericReader<Image>::import( filename ); PointVector<3,int> shiftVector3D( 0 ,0, 0 ); DGtal::functors::BasicDomainSubSampler< HyperRectDomain< SpaceND< 3, int > >, DGtal::int32_t, double > reSampler(image.domain(), aGridSizeReSample, shiftVector3D); const functors::Identity identityFunctor{}; SamplerImageAdapter sampledImage ( image, reSampler.getSubSampledDomain(), reSampler, identityFunctor ); ImagePredicate predicateIMG = ImagePredicate( sampledImage, minImageThreshold, maxImageThreshold ); DomainPredicate<Z3i::Domain> domainPredicate( sampledImage.domain() ); AndBoolFct2 andF; Predicate predicate(domainPredicate, predicateIMG, andF ); Z3i::Domain domain = sampledImage.domain(); Z3i::KSpace K; bool space_ok = K.init( domain.lowerBound()-Z3i::Domain::Point::diagonal(), domain.upperBound()+Z3i::Domain::Point::diagonal(), true ); if (!space_ok) { trace.error() << "Error in the Khalimsky space construction."<<std::endl; return 2; } CanonicSCellEmbedder< KSpace > embedder( K ); SurfelAdjacency< Z3i::KSpace::dimension > Sadj( true ); trace.endBlock(); // Viewer settings // Extraction of components typedef KSpace::SurfelSet SurfelSet; typedef SetOfSurfels< KSpace, SurfelSet > MySetOfSurfels; typedef DigitalSurface< MySetOfSurfels > MyDigitalSurface; trace.beginBlock("Extracting surfaces"); std::vector< std::vector<SCell > > vectConnectedSCell; Surfaces<KSpace>::extractAllConnectedSCell(vectConnectedSCell,K, Sadj, predicate, false); std::ofstream outDat; if( enable_dat ) { trace.info() << "Exporting curvature as dat file: "<< export_dat_filename <<std::endl; outDat.open( export_dat_filename.c_str() ); outDat << "# data exported from 3dCurvatureViewer implementing the II curvature estimator (Coeurjolly, D.; Lachaud, J.O; Levallois, J., (2013). Integral based Curvature" << " Estimators in Digital Geometry. DGCI 2013.) " << std::endl; outDat << "# format: surfel coordinates (in Khalimsky space) curvature: "<< mode << std::endl; } trace.info()<<"Number of components= "<<vectConnectedSCell.size()<<std::endl; trace.endBlock(); if( vectConnectedSCell.size() == 0 ) { trace.error()<< "No surface component exists. Please check the vol file threshold parameter."; trace.info()<<std::endl; exit(2); } #ifdef WITH_VISU3D_QGLVIEWER QApplication application( argc, argv ); typedef Viewer3D<Z3i::Space, Z3i::KSpace> Viewer; #endif typedef Board3D<Z3i::Space, Z3i::KSpace> Board; #ifdef WITH_VISU3D_QGLVIEWER Viewer viewer( K ); #endif Board board( K ); #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { viewer.show(); } #endif for( unsigned int i = 0; i<vectConnectedSCell.size(); ++i ) { if( vectConnectedSCell[i].size() <= threshold ) { continue; } MySetOfSurfels aSet(K, Sadj); for( std::vector<SCell>::const_iterator it = vectConnectedSCell.at(i).begin(); it != vectConnectedSCell.at(i).end(); ++it ) { aSet.surfelSet().insert( *it); } MyDigitalSurface digSurf( aSet ); typedef DepthFirstVisitor<MyDigitalSurface> Visitor; typedef GraphVisitorRange< Visitor > VisitorRange; typedef VisitorRange::ConstIterator SurfelConstIterator; VisitorRange range( new Visitor( digSurf, *digSurf.begin() ) ); SurfelConstIterator abegin = range.begin(); SurfelConstIterator aend = range.end(); VisitorRange range2( new Visitor( digSurf, *digSurf.begin() ) ); SurfelConstIterator abegin2 = range2.begin(); trace.beginBlock("Curvature computation on a component"); if( ( mode.compare("gaussian") == 0 ) || ( mode.compare("mean") == 0 ) || ( mode.compare("k1") == 0 ) || ( mode.compare("k2") == 0 )) { typedef double Quantity; std::vector< Quantity > results; std::back_insert_iterator< std::vector< Quantity > > resultsIterator( results ); if ( mode.compare("mean") == 0 ) { typedef functors::IIMeanCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantVolumeEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } else if ( mode.compare("gaussian") == 0 ) { typedef functors::IIGaussianCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } else if ( mode.compare("k1") == 0 ) { typedef functors::IIFirstPrincipalCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } else if ( mode.compare("k2") == 0 ) { typedef functors::IISecondPrincipalCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } trace.endBlock(); // Drawing results trace.beginBlock("Visualisation"); Quantity min = results[ 0 ]; Quantity max = results[ 0 ]; for ( unsigned int i = 1; i < results.size(); ++i ) { if ( results[ i ] < min ) { min = results[ i ]; } else if ( results[ i ] > max ) { max = results[ i ]; } } trace.info() << "Max value= "<<max<<" min value= "<<min<<std::endl; ASSERT( min <= max ); typedef GradientColorMap< Quantity > Gradient; Gradient cmap_grad( min, (max==min)? max+1: max ); cmap_grad.addColor( Color( 50, 50, 255 ) ); cmap_grad.addColor( Color( 255, 0, 0 ) ); cmap_grad.addColor( Color( 255, 255, 10 ) ); #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { viewer << SetMode3D((*abegin2).className(), "Basic" ); } #endif if( enable_obj ) { board << SetMode3D((K.unsigns(*abegin2)).className(), "Basic" ); } for ( unsigned int i = 0; i < results.size(); ++i ) { #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { viewer << CustomColors3D( Color::Black, cmap_grad( results[ i ] )); viewer << *abegin2; } #endif if( enable_obj ) { board << CustomColors3D( Color::Black, cmap_grad( results[ i ] )); board << K.unsigns(*abegin2); } if( enable_dat ) { Point kCoords = K.uKCoords(K.unsigns(*abegin2)); outDat << kCoords[0] << " " << kCoords[1] << " " << kCoords[2] << " " << results[i] << std::endl; } ++abegin2; } } else { typedef Z3i::Space::RealVector Quantity; std::vector< Quantity > results; std::back_insert_iterator< std::vector< Quantity > > resultsIterator( results ); if( mode.compare("prindir1") == 0 ) { typedef functors::IIFirstPrincipalDirectionFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } else if( mode.compare("prindir2") == 0 ) { typedef functors::IISecondPrincipalDirectionFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } else if( mode.compare("normal") == 0 ) { typedef functors::IINormalDirectionFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } ///Visualizaton / export #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { viewer << SetMode3D(K.uCell( K.sKCoords(*abegin2) ).className(), "Basic" ); } #endif if( enable_obj ) { board << SetMode3D(K.uCell( K.sKCoords(*abegin2) ).className(), "Basic" ); } for ( unsigned int i = 0; i < results.size(); ++i ) { DGtal::Dimension kDim = K.sOrthDir( *abegin2 ); SCell outer = K.sIndirectIncident( *abegin2, kDim); if ( predicate(embedder(outer)) ) { outer = K.sDirectIncident( *abegin2, kDim); } Cell unsignedSurfel = K.uCell( K.sKCoords(*abegin2) ); #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { viewer << CustomColors3D( DGtal::Color(255,255,255,255), DGtal::Color(255,255,255,255)) << unsignedSurfel; } #endif if( enable_obj ) { board << CustomColors3D( DGtal::Color(255,255,255,255), DGtal::Color(255,255,255,255)) << unsignedSurfel; } if( enable_dat ) { Point kCoords = K.uKCoords(K.unsigns(*abegin2)); outDat << kCoords[0] << " " << kCoords[1] << " " << kCoords[2] << " " << results[i][0] << " " << results[i][1] << " " << results[i][2] << std::endl; } RealPoint center = embedder( outer ); #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { if( mode.compare("prindir1") == 0 ) { viewer.setLineColor( AXIS_COLOR_BLUE ); } else if( mode.compare("prindir2") == 0 ) { viewer.setLineColor( AXIS_COLOR_RED ); } else if( mode.compare("normal") == 0 ) { viewer.setLineColor( AXIS_COLOR_GREEN ); } viewer.addLine ( RealPoint( center[0] - 0.5 * results[i][0], center[1] - 0.5 * results[i][1], center[2] - 0.5 * results[i][2] ), RealPoint( center[0] + 0.5 * results[i][0], center[1] + 0.5 * results[i][1], center[2] + 0.5 * results[i][2] ), AXIS_LINESIZE ); } #endif if( enable_obj ) { if( mode.compare("prindir1") == 0 ) { board.setFillColor( AXIS_COLOR_BLUE ); } else if( mode.compare("prindir2") == 0 ) { board.setFillColor( AXIS_COLOR_RED ); } else if( mode.compare("normal") == 0 ) { board.setFillColor( AXIS_COLOR_GREEN ); } board.addCylinder ( RealPoint( center[0] - 0.5 * results[i][0], center[1] - 0.5 * results[i][1], center[2] - 0.5 * results[i][2]), RealPoint( center[0] + 0.5 * results[i][0], center[1] + 0.5 * results[i][1], center[2] + 0.5 * results[i][2]), 0.2 ); } ++abegin2; } } trace.endBlock(); } #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { viewer << Viewer3D<>::updateDisplay; } #endif if( enable_obj ) { trace.info()<< "Exporting object: " << export_obj_filename << " ..."; board.saveOBJ(export_obj_filename,normalization); trace.info() << "[done]" << std::endl; } if( enable_dat ) { outDat.close(); } #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { return application.exec(); } #endif return 0; }
int main( int argc, char** argv ) { const double h = 1; const double radiusBall = 12.0; const double radiusII = 6; const double trueAreaSurface = 4.0*M_PI*radiusBall*radiusBall; trace.beginBlock( "Make parametric shape..." ); typedef Ball3D< Z3i::Space > Shape; Z3i::RealPoint center( 0.0, 0.0, 0.0 ); Shape ball( center, radiusBall ); trace.endBlock(); trace.beginBlock( "Make digital shape..." ); typedef GaussDigitizer< Z3i::Space, Shape > DigitalShape; typedef DigitalShape::Domain Domain; DigitalShape digitalBall; digitalBall.attach( ball ); digitalBall.init( ball.getLowerBound() - Z3i::RealPoint( 1.0, 1.0, 1.0 ), ball.getUpperBound() + Z3i::RealPoint( 1.0, 1.0, 1.0 ), h ); Domain domain = digitalBall.getDomain(); Z3i::KSpace kspace; kspace.init( domain.lowerBound(), domain.upperBound(), true ); trace.endBlock(); trace.beginBlock( "Make digital surface..." ); typedef LightImplicitDigitalSurface< Z3i::KSpace, DigitalShape > LightDigitalSurface; typedef DigitalSurface< LightDigitalSurface > DigitalSurface; typedef DepthFirstVisitor< DigitalSurface > DepthFirstVisitor; typedef GraphVisitorRange< DepthFirstVisitor > GraphVisitorRange; typedef GraphVisitorRange::ConstIterator SurfelConstIterator; typedef Z3i::KSpace::Surfel Surfel; Surfel bel = Surfaces< Z3i::KSpace >::findABel( kspace, digitalBall, 500 ); SurfelAdjacency< Z3i::KSpace::dimension > surfelAdjacency( true ); LightDigitalSurface lightDigitalSurface( kspace, digitalBall, surfelAdjacency, bel ); DigitalSurface digitalSurface( lightDigitalSurface ); GraphVisitorRange graphVisitorRange( new DepthFirstVisitor( digitalSurface, *digitalSurface.begin() ) ); SurfelConstIterator sbegin = graphVisitorRange.begin(); SurfelConstIterator send = graphVisitorRange.end(); std::vector< Surfel > v_border; while( sbegin != send ) { v_border.push_back( *sbegin ); ++sbegin; } trace.endBlock(); trace.beginBlock( "Computation with normal estimation ..." ); typedef IIGeometricFunctors::IINormalDirectionFunctor< Z3i::Space > NormalFunctor; typedef IntegralInvariantCovarianceEstimator< Z3i::KSpace, DigitalShape, NormalFunctor > IINormalEstimator; NormalFunctor normalFunctor; IINormalEstimator normalEstimator( normalFunctor ); normalEstimator.attach( kspace, digitalBall ); normalEstimator.setParams( radiusII / h ); normalEstimator.init( h, v_border.begin(), v_border.end() ); double areaSurfaceEstimated = 0.0; for( unsigned int i_position = 0; i_position < v_border.size(); ++i_position ) { Z3i::RealPoint normalEstimated = normalEstimator.eval( &(v_border[i_position]) ); Z3i::RealPoint normalSurfel = kspace.sKCoords( kspace.sDirectIncident( v_border[i_position], kspace.sOrthDir( v_border[i_position] ))) - kspace.sKCoords( v_border[i_position] ); normalEstimated = normalEstimated.getNormalized(); areaSurfaceEstimated += std::abs( normalEstimated.dot( normalSurfel )) * h * h; } trace.endBlock(); trace.info() << "Area Surface estimated : " << areaSurfaceEstimated << std::endl; trace.info() << "True areaSurface : " << trueAreaSurface << std::endl; trace.info() << "Ratio : " << areaSurfaceEstimated / trueAreaSurface << std::endl; return 0; }
int main( int narg, char **argv ) { trace.beginBlock("Identifying the domain."); Z3i::Domain domain = scene_dimensions( argv[1] ) ; if ( domain.lowerBound() == domain.upperBound() ) { trace.error()<<"Invalid domain ("<<__FILE__<<")"<<std::endl; return -1 ; } trace.endBlock() ; trace.beginBlock("Reading slices."); Z3i::DigitalSet set3d( domain ) ; SetPredicate<Z3i::DigitalSet> set3dPredicate( set3d ) ; for ( uint depth = 0 ; depth < domain.upperBound().at(2) ; depth++ ) process_slice( argv[1], depth, set3d ) ; trace.endBlock() ; if ( 0) { try { Gray3DImage aImage( domain ); for ( Z3i::Domain::ConstIterator pt = domain.begin() ; pt != domain.end() ; pt++ ) aImage.setValue( (*pt), 255 ) ; boost::filesystem::path pathvolname = argv[1] ; pathvolname /= "obj.vol" ; if ( ! DGtal::VolWriter< Gray3DImage, GrayColorMap >::exportVol ( pathvolname.string(), aImage, 0, 255 ) ) { trace.error() <<"Can not export data (generated 3D object)"<<std::endl; return -4 ; } else { trace.info()<<"export data to "<<pathvolname.string()<<std::endl; } pathvolname = argv[1] ; pathvolname /= "obj.pgm3d" ; if ( ! PNMWriter<Gray3DImage, GrayColorMap >::exportPGM3D( pathvolname.string(), aImage, 0, 255 ) ) { trace.error() <<"Can not export data (generated 3D object)"<<std::endl; return -4 ; } else { trace.info()<<"export data to "<<pathvolname.string()<<std::endl; } } catch ( std::exception &e ) { trace.error() <<"Can not export data (generated 3D object) "<<e.what()<<std::endl; return -8 ; } } trace.beginBlock( "Decompose the object into connected components." ); { DGtal::Z3i::Object6_18 scene( DGtal::Z3i::dt6_18, set3d ) ; std::vector< Z3i::Object6_18 > v_obj ; back_insert_iterator< std::vector< Z3i::Object6_18 > > it( v_obj ) ; scene.writeComponents( it ) ; boost::filesystem::path scenefilename = argv[1] ; scenefilename /= "scene.pgm3d" ; IOPgm3d::write( v_obj, scenefilename.string().c_str() ) ; } trace.endBlock( ); return -64; trace.beginBlock( "Construct the Khalimsky space from the image domain." ); Z3i::KSpace ks; bool space_ok = ks.init( domain.lowerBound(), domain.upperBound(), true ); if (!space_ok) { trace.error() << "Error in the Khamisky space construction."<<std::endl; return -2; } trace.endBlock(); typedef SurfelAdjacency<Z3i::KSpace::dimension> MySurfelAdjacency; MySurfelAdjacency surfAdj( true ); // interior in all directions. trace.beginBlock( "Extracting boundary by tracking from an initial bel." ); Z3i::KSpace::SCellSet boundary; Z3i::SCell bel = Surfaces<Z3i::KSpace>::findABel( ks, set3dPredicate, 100000 ); Surfaces<Z3i::KSpace>::trackBoundary( boundary, ks, surfAdj, set3dPredicate, bel ); trace.endBlock(); trace.beginBlock( "Displaying surface in Viewer3D." ); QApplication application(narg,argv); Viewer3D viewer; viewer.show(); viewer << SetMode3D( boundary.begin()->className(), "") ; //CustomColors3D(Color(250, 0, 0 ), Color( 128, 128, 128 ) ); unsigned long nbSurfels = 0; for ( Z3i::KSpace::SCellSet::const_iterator it = boundary.begin(), it_end = boundary.end(); it != it_end; ++it, ++nbSurfels ) viewer << ks.uCell( Z3i::Point( (*it).myCoordinates.at(0), (*it).myCoordinates.at(1), (*it).myCoordinates.at(2) ) ) ; /** for ( Z3i::KSpace::SCellSet::const_iterator it = boundary.begin(), it_end = boundary.end(); it != it_end; ++it, ++nbSurfels ) viewer << (*it) ; */ trace.info() << *boundary.begin()<<std::endl; viewer << Viewer3D::updateDisplay; trace.info() << "nb surfels = " << nbSurfels << std::endl; trace.endBlock(); return application.exec(); }
int main( int argc, char** argv ) { if ( argc != 4 ) { trace.error() << "Usage: " << argv[0] << " <fileName.vol> <threshold> <re_convolution_kernel>" << std::endl; trace.error() << "Example : "<< argv[0] << " Al.150.vol 0 7.39247665" << std::endl; return 0; } trace.beginBlock ( "Example IntegralInvariantCurvature3D" ); trace.info() << "Args:"; for ( int i = 0; i < argc; ++i ) trace.info() << " " << argv[ i ]; trace.info() << endl; double h = 1.0; unsigned int threshold = atoi( argv[ 2 ] ); /// Construction of the shape from vol file typedef ImageSelector< Z3i::Domain, unsigned int >::Type Image; typedef SimpleThresholdForegroundPredicate< Image > ImagePredicate; typedef Z3i::KSpace::Surfel Surfel; typedef LightImplicitDigitalSurface< Z3i::KSpace, ImagePredicate > MyLightImplicitDigitalSurface; typedef DigitalSurface< MyLightImplicitDigitalSurface > MyDigitalSurface; std::string filename = argv[1]; Image image = VolReader<Image>::importVol( filename ); ImagePredicate predicate = ImagePredicate( image, threshold ); Z3i::Domain domain = image.domain(); Z3i::KSpace KSpaceShape; bool space_ok = KSpaceShape.init( domain.lowerBound(), domain.upperBound(), true ); if (!space_ok) { trace.error() << "Error in the Khalimsky space construction."<<std::endl; return 2; } SurfelAdjacency< Z3i::KSpace::dimension > SAdj( true ); Surfel bel = Surfaces< Z3i::KSpace >::findABel( KSpaceShape, predicate, 100000 ); MyLightImplicitDigitalSurface LightImplDigSurf( KSpaceShape, predicate, SAdj, bel ); MyDigitalSurface digSurf( LightImplDigSurf ); typedef DepthFirstVisitor< MyDigitalSurface > Visitor; typedef GraphVisitorRange< Visitor > VisitorRange; typedef VisitorRange::ConstIterator SurfelConstIterator; VisitorRange range( new Visitor( digSurf, *digSurf.begin() ) ); SurfelConstIterator abegin = range.begin(); SurfelConstIterator aend = range.end(); typedef ImageToConstantFunctor< Image, ImagePredicate > MyPointFunctor; MyPointFunctor pointFunctor( &image, &predicate, 1 ); /// Integral Invariant stuff //! [IntegralInvariantUsage] double re_convolution_kernel = atof(argv[3]); typedef FunctorOnCells< MyPointFunctor, Z3i::KSpace > MyCellFunctor; typedef IntegralInvariantGaussianCurvatureEstimator< Z3i::KSpace, MyCellFunctor > MyCurvatureEstimator; // Gaussian curvature estimator MyCellFunctor functor ( pointFunctor, KSpaceShape ); // Creation of a functor on Cells, returning true if the cell is inside the shape MyCurvatureEstimator estimator ( KSpaceShape, functor ); estimator.init( h, re_convolution_kernel ); // Initialisation for a given Euclidean radius of convolution kernel std::vector< double > results; back_insert_iterator< std::vector< double > > resultsIterator( results ); // output iterator for results of Integral Invariante curvature computation estimator.eval ( abegin, aend, resultsIterator ); // Computation //! [IntegralInvariantUsage] /// Drawing results typedef MyCurvatureEstimator::Quantity Quantity; Quantity min = numeric_limits < Quantity >::max(); Quantity max = numeric_limits < Quantity >::min(); for ( unsigned int i = 0; i < results.size(); ++i ) { if ( results[ i ] < min ) { min = results[ i ]; } else if ( results[ i ] > max ) { max = results[ i ]; } } QApplication application( argc, argv ); Viewer3D<> viewer; viewer.show(); typedef GradientColorMap< Quantity > Gradient; Gradient cmap_grad( min, max ); cmap_grad.addColor( Color( 50, 50, 255 ) ); cmap_grad.addColor( Color( 255, 0, 0 ) ); cmap_grad.addColor( Color( 255, 255, 10 ) ); VisitorRange range2( new Visitor( digSurf, *digSurf.begin() ) ); abegin = range2.begin(); for ( unsigned int i = 0; i < results.size(); ++i ) { viewer << CustomColors3D( Color::Black, cmap_grad( results[ i ] )) << *abegin; ++abegin; } viewer << Viewer3D<>::updateDisplay; trace.endBlock(); return application.exec(); }
int main( int argc, char** argv ) { typedef PointVector<4, double> Point4D; typedef PointVector<1, int> Point1D; // 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 file: sdp (sequence of discrete points with attribute)" ) ("noWindows,n", "Don't display Viewer windows." ) ("doSnapShotAndExit,d", po::value<std::string>(), "save display snapshot into file." ) ("fixMaxColorValue", po::value<double>(), "fix the maximal color value for the scale error display (else the scale is set from the maximal value)" ) ("fixMinColorValue", po::value<double>(), "fix the minimal color value for the scale error display (else the scale is set from the minimal value)" ) ("labelIndex", po::value<unsigned int>(), "set the index of the label (by default set to 3) " ) ("SDPindex", po::value<std::vector <unsigned int> >()->multitoken(), "specify the sdp index (by default 0,1,2)."); bool parseOK=true; bool cannotStart= false; po::variables_map vm; try{ po::store(po::parse_command_line(argc, argv, general_opt), vm); }catch(const std::exception& ex){ parseOK=false; trace.error()<< "Error checking program options: "<< ex.what()<< endl; } po::notify(vm); if(parseOK && ! vm.count("input")) { trace.error() << " The input file name was not defined" << endl; cannotStart = true; } if( !parseOK || cannotStart || vm.count("help")||argc<=1) { trace.info() << "Usage: " << argv[0] << " [input]\n" << "Display surfel data from SDP file with color attributes given as scalar interpreted as color." << general_opt << "\n"; return 0; } Z3i::KSpace K; string inputFilename = vm["input"].as<std::string>(); std::vector<Point4D> surfelAndScalarInput; if(vm.count("SDPindex")) { std::vector<unsigned int > vectIndex = vm["SDPindex"].as<std::vector<unsigned int > >(); if(vectIndex.size()!=4){ trace.error() << "you need to specify the three indexes of vertex." << std::endl; return 0; } surfelAndScalarInput = PointListReader<Point4D>::getPointsFromFile(inputFilename, vectIndex); }else{ surfelAndScalarInput = PointListReader<Point4D>::getPointsFromFile(inputFilename); } Point4D ptLower = surfelAndScalarInput.at(0); Point4D ptUpper = surfelAndScalarInput.at(0); getBoundingUpperAndLowerPoint(surfelAndScalarInput, ptLower, ptUpper); K.init(Z3i::Point(2*ptLower[0]+1, 2*ptLower[1]+1, 2*ptLower[2]+1), Z3i::Point(2*ptUpper[0]+1, 2*ptUpper[1]+1, 2*ptUpper[2]+1), true); std::vector<Cell> vectSurfelsInput; // Construction of the set of surfels for(unsigned int i =0; i<surfelAndScalarInput.size(); i++){ Point4D pt4d = surfelAndScalarInput.at(i); Cell c = K.uCell(Z3i::Point(pt4d[0], pt4d[1], pt4d[2])); vectSurfelsInput.push_back(c); } CanonicCellEmbedder<KSpace> embeder(K); std::vector<unsigned int> vectIndexMinToReference; //------------------------- // Displaying input with color given from scalar values QApplication application(argc,argv); typedef ViewerSnap<> Viewer; Viewer viewer(K, vm.count("doSnapShotAndExit")); if(vm.count("doSnapShotAndExit")){ viewer.setSnapshotFileName(QString(vm["doSnapShotAndExit"].as<std::string>().c_str())); } viewer.setWindowTitle("3dCompSurfel Viewer"); viewer.show(); viewer.restoreStateFromFile(); double minScalarVal=surfelAndScalarInput.at(0)[3]; double maxScalarVal=surfelAndScalarInput.at(0)[3]; for(unsigned int i=1; i <surfelAndScalarInput.size(); i++){ double scalVal = surfelAndScalarInput.at(i)[3]; if(scalVal < minScalarVal){ minScalarVal = scalVal; } if(scalVal > maxScalarVal){ maxScalarVal = scalVal; } } if(vm.count("fixMaxColorValue")){ maxScalarVal = vm["fixMaxColorValue"].as<double>(); } if(vm.count("fixMinColorValue")){ minScalarVal = vm["fixMinColorValue"].as<double>(); } GradientColorMap<double> gradientColorMap( minScalarVal, maxScalarVal ); gradientColorMap.addColor( Color(255,0,0,100 ) ); gradientColorMap.addColor( Color(0,255,0,100 ) ); gradientColorMap.addColor( Color(0,0,255,100 ) ); bool useGrad = minScalarVal!=maxScalarVal; viewer << SetMode3D(vectSurfelsInput.at(0).className(), "Basic"); for(unsigned int i=0; i <surfelAndScalarInput.size(); i++){ double valInput = surfelAndScalarInput.at(i)[3]; if(useGrad){ viewer.setFillColor(gradientColorMap(valInput)); }else{ viewer.setFillColor(Color::White); } viewer << vectSurfelsInput.at(i); } viewer << Viewer::updateDisplay; if(vm.count("doSnapShotAndExit")){ // Appy cleaning just save the last snap std::string name = vm["doSnapShotAndExit"].as<std::string>(); std::string extension = name.substr(name.find_last_of(".") + 1); std::string basename = name.substr(0, name.find_last_of(".")); for(int i=0; i< viewer.snapshotCounter()-1; i++){ std::stringstream s; s << basename << "-"<< setfill('0') << setw(4)<< i << "." << extension; trace.info() << "erase temp file: " << s.str() << std::endl; remove(s.str().c_str()); } std::stringstream s; s << basename << "-"<< setfill('0') << setw(4)<< viewer.snapshotCounter()-1 << "." << extension; rename(s.str().c_str(), name.c_str()); return 0; } if(vm.count("noWindows")){ return 0; }else{ return application.exec(); } }
int main(int argc, char** argv) { QApplication application(argc,argv); Point ptL(-1, -1, -1); Point ptU(3, 3, 1); Domain d (ptL, ptU); Point pt0(0,0, 0); Point pt1(1,0,0 ); Point pt2(0,1,0 ); Point pt3(2,1,0); Point pt4(1,2,0); Point pt5(2,2,0); DigitalSet aSet( d ); aSet.insert(pt0); aSet.insert(pt1); aSet.insert(pt2); aSet.insert(pt3); aSet.insert(pt4); std::set<SCell> bdry; Z3i::KSpace ks; ks.init( ptL, ptU, true ); SCell v0 = ks.sSpel(pt0, KSpace::POS); SCell v1 = ks.sSpel(pt1, KSpace::POS); SCell v2 = ks.sSpel(pt2, KSpace::POS); SCell v3 = ks.sSpel(pt3, KSpace::POS); SCell v4 = ks.sSpel(pt4, KSpace::POS); Viewer3D viewerAdjSRC; viewerAdjSRC.show(); viewerAdjSRC << d; viewerAdjSRC << SetMode3D( v0.className(), "Illustration" ); viewerAdjSRC << pt0 << pt1 << pt2 << pt3 << pt4; Viewer3D viewerAdj; viewerAdj.show(); viewerAdj << SetMode3D( v0.className(), "Illustration" ); viewerAdj << v0 << v1 << v2 << v3 << v4; Viewer3D viewerAdj2; viewerAdj2.show(); // Extracting the surface boundary of the shape Surfaces<Z3i::KSpace>::sMakeBoundary( bdry, ks, aSet, ks.lowerBound(), ks.upperBound() ); SurfelAdjacency<Z3i::KSpace::dimension> sAdjInt( true ); SurfelAdjacency<Z3i::KSpace::dimension> sAdjExt( false ); viewerAdj << SetMode3D( v0.className(), "Illustration" ); viewerAdj << v0 << v1 << v2 << v3 << v4; //Displaying the boundary bels std::set<SCell>::iterator itBoundary; int i=0; for(itBoundary= bdry.begin(); itBoundary!= bdry.end(); itBoundary++){ viewerAdj << *itBoundary; } viewerAdj2 << SetMode3D( v0.className(), "Illustration" ); viewerAdj2 << v0 << v1 << v2 << v3 << v4; itBoundary = bdry.begin(); for (int i =0; i<17; i++) itBoundary++; SCell surfel = *itBoundary; // Defining surfel Neighborhood given an surfel Adjacency SurfelNeighborhood<KSpace> sNeighInt; sNeighInt.init( &ks, &sAdjInt, surfel ); SurfelNeighborhood<KSpace> sNeighExt; sNeighExt.init( &ks, &sAdjExt, surfel ); SCell surfelFollowerInt; SCell surfelFollowerExt; sNeighInt.getAdjacentOnDigitalSet ( surfelFollowerInt, aSet, *(ks.sDirs(surfel)), true); sNeighExt.getAdjacentOnDigitalSet ( surfelFollowerExt, aSet, *(ks.sDirs(surfel)), true); viewerAdj2 << CustomColors3D(Color(220, 220,255),Color(220, 220,255)); viewerAdj2 << surfel; viewerAdj2 << CustomColors3D(Color(250, 0,0),Color(250, 0,0)); viewerAdj2 << surfelFollowerInt; viewerAdj2 << CustomColors3D(Color(0, 250,0),Color(0, 250,0)); viewerAdj2 << surfelFollowerExt; // Extraction of contour std::set<SCell> aContour1; Surfaces<Z3i::KSpace>::trackBoundary( aContour1, ks, sAdjExt, aSet, surfel ); Viewer3D viewerContour1; viewerContour1.show(); viewerContour1 << SetMode3D( v0.className(), "Illustration" ); viewerContour1 << v0 << v1 << v2 << v3 << v4; std::set<SCell>::iterator iterOnContour; for( iterOnContour= aContour1.begin(); iterOnContour != aContour1.end(); iterOnContour++){ if(*iterOnContour != surfel){ viewerContour1 << CustomColors3D(Color(0, 250,0),Color(0, 250,0)); viewerContour1<< *iterOnContour; }else{ viewerContour1 << CustomColors3D(Color(220, 220,255),Color(220, 220,255)); viewerContour1<< *iterOnContour; } } // Extraction of contour std::set<SCell> aContour2; Surfaces<Z3i::KSpace>::trackBoundary( aContour2, ks, sAdjInt, aSet, surfel ); Viewer3D viewerContour2; viewerContour2.show(); viewerContour2 << SetMode3D( v0.className(), "Illustration" ); viewerContour2 << v0 << v1 << v2 << v3 << v4; std::set<SCell>::iterator iterOnContour2; for( iterOnContour2= aContour2.begin(); iterOnContour2 != aContour2.end(); iterOnContour2++){ if(*iterOnContour2 != surfel){ viewerContour2 << CustomColors3D(Color(250, 0,0),Color(250, 0,0)); viewerContour2<< *iterOnContour2; }else{ viewerContour2 << CustomColors3D(Color(220, 220,255),Color(220, 220,255)); viewerContour2<< *iterOnContour2; } } viewerAdjSRC << Viewer3D:: updateDisplay; viewerAdj<< Viewer3D::updateDisplay; viewerAdj2<< Viewer3D::updateDisplay; viewerContour1 << Viewer3D::updateDisplay; viewerContour2 << Viewer3D::updateDisplay; return application.exec(); return 0; }