int main( int argc, char** argv ) { typedef ImageContainerBySTLVector < Z3i::Domain, unsigned char > Image3D; typedef ImageContainerBySTLVector < Z2i::Domain, unsigned char > Image2D; // parse command line ---------------------------------------------- po::options_description general_opt("Allowed options are: "); general_opt.add_options() ("help,h", "display this message") ("sliceOrientation,s", po::value<unsigned int>()->default_value(2), "specify the slice orientation for which the slice are considered (by default =2 (Z direction))" ) ("input,i", po::value<std::vector <std::string> >()->multitoken(), "input 2D files (.pgm) " ) ("output,o", po::value<std::string>(), "volumetric file (.vol, .longvol .pgm3d) " ); bool parseOK=true; po::variables_map vm; try{ po::store(po::parse_command_line(argc, argv, general_opt), vm); }catch(const std::exception& ex){ parseOK=false; trace.info()<< "Error checking program options: "<< ex.what()<< endl; } po::notify(vm); if( !parseOK || vm.count("help")) { std::cout << "Usage: " << argv[0] << " [input-files] [output]\n" << "Convert set of 2D images into volumetric file (pgm3d, vol, longvol) " << general_opt << "\n"; std::cout << "Example:\n" << "slice2vol -i slice1.pgm slice2.pgm slice3.pgm -o vol.p3d \n" << "see vol2slice"<<endl; return 0; } if(! vm.count("input-files")||! vm.count("output")) { trace.error() << " Input and output filename are needed to be defined" << endl; return 0; } std::string outputFileName = vm["output"].as<std::string>(); std::vector<string> vectImage2DNames = vm["input"].as<std::vector<std::string> >(); unsigned int sliceOrientation = vm["sliceOrientation"].as<unsigned int>(); std::vector<Image2D> vectImages2D; // Reading all images for(unsigned int i=0; i< vectImage2DNames.size(); i++){ trace.info() << "Reading image " << i ; Image2D image = GenericReader<Image2D>::import(vectImage2DNames.at(i)); vectImages2D.push_back(image); trace.info() << " [done]" << std::endl; } Image2D::Domain domImage2D = vectImages2D.at(0).domain(); DGtal::functors::Projector<DGtal::Z3i::Space> projIn3Dlower(0); DGtal::functors::Projector<DGtal::Z3i::Space> projIn3Dupper(vectImages2D.size()-1); projIn3Dlower.initAddOneDim(sliceOrientation); projIn3Dupper.initAddOneDim(sliceOrientation); Image3D::Domain domImage3D (projIn3Dlower(vectImages2D.at(0).domain().lowerBound()), projIn3Dupper(vectImages2D.at(0).domain().upperBound())); Image3D imageResult (domImage3D); for( unsigned int i=0; i<vectImages2D.size(); i++){ Image2D sliceImage = vectImages2D.at(i); DGtal::functors::Projector<DGtal::Z3i::Space> projIn3D(i); projIn3D.initAddOneDim(sliceOrientation); for(Image2D::Domain::ConstIterator it = sliceImage.domain().begin(); it!= sliceImage.domain().end(); it++){ Z3i::Point pt =projIn3D(*it); imageResult.setValue(pt, sliceImage(*it)); } } trace.info() << "Exporting 3d image ... " << std::endl ; GenericWriter<Image3D>::exportFile(outputFileName, imageResult); trace.info() << "[done]"; return 0; }
int main( int argc, char** argv ) { typedef ImageContainerBySTLVector < Z2i::Domain, unsigned int> Image2D; typedef ImageContainerBySTLVector < Z2i::Domain, Z3i::RealPoint> Image2DNormals; // 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>(), "heightfield file." ) ("output,o", po::value<std::string>(), "output image.") ("importNormal", po::value<std::string>(), "import normals from file.") ("specularModel,s", po::value<std::vector<double> >()->multitoken(), "use specular Nayar model with 3 param Kdiff, Kspec, sigma .") ("lx", po::value<double>(), "x light source direction.") ("ly", po::value<double>(), "y light source direction." ) ("lz", po::value<double>(), "z light source direction.") ("px", po::value<double>(), "x light source position.") ("py", po::value<double>(), "y light source position." ) ("pz", po::value<double>(), "z light source position.") ("reflectanceMap,r", po::value<std::string>(), "specify a image as reflectance map.") ; bool parseOK=true; po::variables_map vm; try{ po::store(po::parse_command_line(argc, argv, general_opt), vm); }catch(const std::exception& ex){ parseOK=false; trace.info()<< "Error checking program options: "<< ex.what()<< endl; } po::notify(vm); if( !parseOK || vm.count("help")||argc<=1) { std::cout << "Usage: " << argv[0] << " [input] [output]\n" << "Render a 2D heightfield image into a shading image. You can choose between lambertian model (diffuse reflectance) and specular model (Nayar reflectance model). You can also choose between a single directional light source (using -l{x,y,z} options) or use light source which emits in all direction (by specifying the light source position with -p{x,y,z} option). Another rendering mode is given from a bitmap reflectance map which represents the rendering for a normal vector value (mapped according the x/y coordinates). " << general_opt << "\n"; std::cout << "Example:\n" << "heightfield2shading -i heightfield.pgm -o shading.pgm --lx 0.0 --ly 1.0 --lz 1.0 --importNormal heightfield.pgm.normals -s 0.2 0.8 \n"; return 0; } if(! vm.count("input") ||! vm.count("output")) { trace.error() << " Input and output filename are needed to be defined" << endl; return 0; } string inputFilename = vm["input"].as<std::string>(); string outputFilename = vm["output"].as<std::string>(); double lx, ly, lz, px, py, pz; bool usingAllDirectionLightSource = false; if(vm.count("lx") && vm.count("ly") && vm.count("lz")) { lx = vm["lx"].as<double>(); ly = vm["ly"].as<double>(); lz = vm["lz"].as<double>(); } else if(vm.count("px") && vm.count("py") && vm.count("pz")) { px = vm["px"].as<double>(); py = vm["py"].as<double>(); pz = vm["pz"].as<double>(); usingAllDirectionLightSource = true; } else if (!vm.count("reflectanceMap")) { trace.error() << "You need to specify either the light source direction or position (if you use a all directions model)." << std::endl; exit(0); } LambertianShadindFunctor<Image2D, Z3i::RealPoint> lShade (Z3i::RealPoint(lx,ly,lz)); LambertianShadindFunctorAllDirections<Image2D, Z3i::RealPoint> lShadePosD (Z3i::RealPoint(px ,py, pz)); SpecularNayarShadindFunctor<Image2D, Z3i::RealPoint> lSpecular (Z3i::RealPoint(lx,ly,lz), 0, 0, 0); SpecularNayarShadindFunctorAllDirections<Image2D, Z3i::RealPoint> lSpecularPosD (Z3i::RealPoint(px,py,pz), 0, 0, 0); bool useSpecular = false; if(vm.count("specularModel")){ std::vector<double> vectParam = vm["specularModel"].as<std::vector<double> > (); if(vectParam.size() != 3) { trace.warning() << "You have not specify all specular parameters... using lambertian model instead." << std::endl; } else { useSpecular = true; lSpecular.myKld = vectParam[0]; lSpecular.myKls = vectParam[1]; lSpecular.mySigma = vectParam[2]; lSpecularPosD.myKld = vectParam[0]; lSpecularPosD.myKls = vectParam[1]; lSpecularPosD.mySigma = vectParam[2]; if(vectParam[2]==0.0) { trace.error()<< "a 0 value for sigma is not possible in the Nayar model, please change it. "<< std::endl; exit(1); } } } trace.info() << "Reading input file " << inputFilename ; Image2D inputImage = DGtal::GenericReader<Image2D>::import(inputFilename); Image2DNormals vectNormals (inputImage.domain()); Image2D result (inputImage.domain()); if(vm.count("importNormal")){ std::string normalFileName = vm["importNormal"].as<string>(); importNormals(normalFileName, vectNormals); }else{ computerBasicNormalsFromHeightField(inputImage, vectNormals); } if(vm.count("reflectanceMap")) { ImageMapReflectance<Image2D, Z3i::RealPoint> lMap(vm["reflectanceMap"].as<std::string>()); for(typename Image2D::Domain::ConstIterator it = inputImage.domain().begin(); it != inputImage.domain().end(); it++){ if(vm.count("reflectanceMap")) { result.setValue(*it, lMap(vectNormals(*it))); } } IdColor id; PPMWriter<Image2D, IdColor >::exportPPM(outputFilename, result, id); } else { for(typename Image2D::Domain::ConstIterator it = inputImage.domain().begin(); it != inputImage.domain().end(); it++){ if(usingAllDirectionLightSource) { result.setValue(*it, useSpecular? lSpecularPosD(vectNormals(*it), *it, inputImage(*it)): lShadePosD(vectNormals(*it), *it, inputImage(*it))); } else { result.setValue(*it, useSpecular? lSpecular(vectNormals(*it)):lShade(vectNormals(*it))); } } result >> outputFilename; } return 0; }
int main( int argc, char** argv ) { using namespace DGtal; typedef ImageContainerBySTLVector < Z2i::Domain, unsigned char> Image2D; QApplication application(argc,argv); // parse command line ---------------------------------------------- namespace po = boost::program_options; po::options_description general_opt("Allowed options are: "); general_opt.add_options() ("help,h", "display this message") ("input,i", po::value<std::string>(), "heightfield file." ) ("scale,s", po::value<double>()->default_value(1.0), "set the scale of the maximal level. (default 1.0)") ("volZ,z", po::value<unsigned int>()->default_value(255), "set the Z max value of domain.") ("diff,d", po::value<unsigned int>()->default_value(4), "sets the maximum depth of the surface.") ("R-radius,R", po::value<double>()->default_value( 5 ), "the parameter R in the VCM." ) ("r-radius,r", po::value<double>()->default_value( 3 ), "the parameter r in the VCM." ) ("kernel,k", po::value<std::string>()->default_value( "hat" ), "the function chi_r, either hat or ball." ) ("trivial-radius,t", po::value<double>()->default_value( 3 ), "the parameter r for the trivial normal estimator." ) ("embedding,E", po::value<int>()->default_value( 0 ), "the surfel -> point embedding: 0: Pointels, 1: InnerSpel, 2: OuterSpel." ) ("output,o", po::value<std::string>()->default_value("surface"), "the output base filename (without extension)" ) ; bool parseOK=true; po::variables_map vm; try { po::store(po::parse_command_line(argc, argv, general_opt), vm); } catch(const std::exception& ex) { parseOK=false; trace.info()<< "Error checking program options: "<< ex.what()<< endl; } po::notify(vm); if( !parseOK || vm.count("help") || ! vm.count( "input" ) ) { std::cout << "Usage: " << argv[0] << " -i [file.vol] -R 5\n" << "Reads a vol file, extract a its surface boundary and computes its normals." << general_opt << "\n"; std::cout << "Example:\n" << "vol2offAndNormals -i cat10.vol\n"; return 0; } trace.beginBlock( "Loading image into memory." ); string inputFilename = vm["input"].as<std::string>(); trace.info() << "Reading input file " << inputFilename << std::endl; Image2D inputImage = DGtal::GenericReader<Image2D,2,unsigned char>::import(inputFilename); // Image2D inputImage = DGtal::PGMReader<Image2D>::importPGM(inputFilename); double scale = vm["scale"].as<double>(); unsigned int volz = vm["volZ"].as<unsigned int>(); unsigned int diff = vm["diff"].as<unsigned int>(); trace.info() << " [done] " << std::endl ; typedef SurfelPredicateFromHeightField< KSpace, Image2D > MySurfelPredicate; MySurfelPredicate surfelPred( inputImage, scale, volz, diff ); trace.endBlock(); typedef typename Image2D::Domain Domain2D; typedef typename Image2D::Point Point2D; typedef typename Image2D::Value Value; const Domain2D& domain2d = inputImage.domain(); Point2D p = domain2d.lowerBound(); for ( typename Domain2D::ConstIterator it = domain2d.begin(), itE = domain2d.end(); it != itE; ++it ) { if ( inputImage( *it ) > inputImage( p ) ) p = *it; } typedef SurfelAdjacency<KSpace::dimension> MySurfelAdjacency; typedef KSpace::Surfel Surfel; typedef DGtal::ExplicitDigitalSurface< KSpace, MySurfelPredicate > MySurfaceContainer; typedef DigitalSurface< MySurfaceContainer > MyDigitalSurface; MySurfelAdjacency surfAdj( true ); // interior in all directions. Surfel bel = surfelPred.topSurfel( p ); const KSpace& ks = surfelPred.space(); MySurfaceContainer* container = new MySurfaceContainer( ks, surfelPred, surfAdj, bel, false ); MyDigitalSurface surface( container ); //acquired trace.info() << "Digital surface has " << surface.size() << " surfels." << std::endl; Viewer3D<> viewer( ks ); viewer.show(); viewer.setWindowTitle("Voronoi 3D viewer"); double R = vm["R-radius"].as<double>(); double r = vm["r-radius"].as<double>(); double t = vm["trivial-radius"].as<double>(); int E = vm["embedding"].as<int>(); std::string kernel = vm[ "kernel" ].as<std::string>(); std::string basename = vm[ "output" ].as<std::string>(); if ( kernel == "hat" ) { typedef functors::HatPointFunction<Point,double> KernelFunction; computeSurfaceVCM( viewer, basename, surface, R, r, KernelFunction( 1.0, r ), t, E ); } else if ( kernel == "ball" ) { typedef functors::BallConstantPointFunction<Point,double> KernelFunction; computeSurfaceVCM( viewer, basename, surface, R, r, KernelFunction( 1.0, r ), t, E ); } viewer << Viewer3D<>::updateDisplay; return application.exec(); }