DGtalTools  0.9.2
heightfield2vol.cpp
1 
29 #include <iostream>
31 #include <fstream>
32 #include "DGtal/base/Common.h"
33 #include "DGtal/helpers/StdDefs.h"
34 #include "DGtal/images/ImageContainerBySTLVector.h"
35 #include "DGtal/io/writers/VolWriter.h"
36 #include "DGtal/io/readers/GenericReader.h"
37 #include "DGtal/images/ConstImageAdapter.h"
38 #include "DGtal/kernel/BasicPointFunctors.h"
39 
40 
41 #include <boost/program_options/options_description.hpp>
42 #include <boost/program_options/parsers.hpp>
43 #include <boost/program_options/variables_map.hpp>
44 
45 using namespace std;
46 using namespace DGtal;
47 
48 
50 namespace po = boost::program_options;
51 
86 // Defining a Helper to get the 3D point functor from an 2DImage
87 template<typename TImage2D, typename TPoint3D >
88 struct Image3DPredicatFrom2DImage{
89  typedef TPoint3D Point3D;
90  typedef HyperRectDomain<Z3i::Space> Domain;
91  typedef typename TImage2D::Value Value;
95  Image3DPredicatFrom2DImage(DGtal::ConstAlias<TImage2D> anImage, double aScale,
96  unsigned int maxHeight,
97  unsigned int fg, unsigned int bg
98  ):myImageRef(anImage),
99  myScale(aScale),
100  myMaxHeight(maxHeight),
101  myBG(bg), myFG(fg){
102  }
103  inline
104  unsigned int operator()(const Point3D &aPoint) const {
105  functors::Projector<SpaceND<2, typename TImage2D::Integer> > projXY;
106  return (*myImageRef)(projXY(aPoint))*myScale >= aPoint[2] ? myFG: myBG ;
107  }
108 
109  inline
110  Domain domain() const {
111  return Domain(Z3i::Point(0,0,0), Z3i::Point(myImageRef->domain().upperBound()[0],
112  myImageRef->domain().upperBound()[1],
113  myMaxHeight) );
114  }
115  CountedConstPtrOrConstPtr<TImage2D> myImageRef;
116  double myScale;
117  unsigned int myMaxHeight;
118  unsigned int myFG;
119  unsigned int myBG;
120 };
121 
122 
123 
124 int main( int argc, char** argv )
125 {
126  typedef ImageContainerBySTLVector < Z3i::Domain, unsigned char > Image3D;
127  typedef ImageContainerBySTLVector < Z2i::Domain, unsigned char> Image2D;
128 
129  typedef DGtal::ConstImageAdapter<Image3D, Z2i::Domain, DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain>,
130  Image3D::Value, DGtal::functors::Identity > ImageAdapterExtractor;
131 
132  // parse command line ----------------------------------------------
133  po::options_description general_opt("Allowed options are: ");
134  general_opt.add_options()
135  ("help,h", "display this message")
136  ("input,i", po::value<std::string>(), "heightfield file." )
137  ("output,o", po::value<std::string>(), "volumetric file ")
138  ("scale,s", po::value<double>()->default_value(1.0), "set the scale factor on height values. (default 1.0)")
139  ("volZ,z", po::value<unsigned int>()->default_value(255), "set the Z max value of domain.")
140  ("foregroundValue,f", po::value<unsigned int>()->default_value(128), "specify the foreground value of the resulting voxel." )
141  ("backgroundValue,b", po::value<unsigned int>()->default_value(0), "specify the background value of the resulting volumetric file.");
142 
143  bool parseOK=true;
144  po::variables_map vm;
145  try{
146  po::store(po::parse_command_line(argc, argv, general_opt), vm);
147  }catch(const std::exception& ex){
148  parseOK=false;
149  trace.info()<< "Error checking program options: "<< ex.what()<< endl;
150  }
151  po::notify(vm);
152  if( !parseOK || vm.count("help")||argc<=1)
153  {
154  std::cout << "Usage: " << argv[0] << " [input] [output]\n"
155  << "Convert a 2D heightfield image into a volumetric file. "
156  << general_opt << "\n";
157  std::cout << "Example:\n"
158  << "heightfield2vol -i ${DGtal}/examples/samples/church.pgm -o volResu.vol -s 0.3 -z 50 \n";
159  return 0;
160  }
161 
162  if(! vm.count("input") ||! vm.count("output"))
163  {
164  trace.error() << " Input and output filename are needed to be defined" << endl;
165  return 0;
166  }
167 
168  string inputFilename = vm["input"].as<std::string>();
169  string outputFilename = vm["output"].as<std::string>();
170 
171  trace.info() << "Reading input file " << inputFilename ;
172  Image2D inputImage = DGtal::GenericReader<Image2D>::import(inputFilename);
173  double scale = vm["scale"].as<double>();
174  unsigned int maxZ = vm["volZ"].as<unsigned int>();
175  trace.info() << " [done] " << std::endl ;
176 
177  unsigned int foregroundValue = vm["foregroundValue"].as<unsigned int>();
178  unsigned int backgroundValue = vm["backgroundValue"].as<unsigned int>();
179 
180  typedef Image3DPredicatFrom2DImage<Image2D, Z3i::Point> HeightMapVol;
181  Image3DPredicatFrom2DImage<Image2D, Z3i::Point> image3Dpredicate(inputImage, scale, maxZ, foregroundValue, backgroundValue);
182  trace.info() << "Processing image to output file " << outputFilename ;
183 
184  VolWriter<HeightMapVol>::exportVol(outputFilename, image3Dpredicate);
185 
186  trace.info() << " [done] " << std::endl ;
187  return 0;
188 }
STL namespace.