Пример #1
0
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;  
}
Пример #2
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;  
}
Пример #3
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();
}