DGtalTools  0.9.2
vol2heightfield.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/GenericWriter.h"
36 #include "DGtal/io/readers/VolReader.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 
52 
101 int main( int argc, char** argv )
102 {
103  typedef ImageContainerBySTLVector < Z3i::Domain, unsigned char > Image3D;
104  typedef ImageContainerBySTLVector < Z2i::Domain, unsigned char> Image2D;
105  typedef DGtal::ConstImageAdapter<Image3D, Z2i::Domain, DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain>,
106  Image3D::Value, DGtal::functors::Identity > ImageAdapterExtractor;
107 
108  // parse command line ----------------------------------------------
109  po::options_description general_opt("Allowed options are: ");
110  general_opt.add_options()
111  ("help,h", "display this message")
112  ("input,i", po::value<std::string>(), "volumetric file (.vol) " )
113  ("output,o", po::value<std::string>(), "sequence of discrete point file (.sdp) ")
114  ("thresholdMin,m", po::value<int>()->default_value(128), "min threshold (default 128)" )
115  ("thresholdMax,M", po::value<int>()->default_value(255), "max threshold (default 255)" )
116  ("nx", po::value<double>()->default_value(0), "set the x component of the projection direction." )
117  ("ny", po::value<double>()->default_value(0), "set the y component of the projection direction." )
118  ("nz", po::value<double>()->default_value(1), "set the z component of the projection direction." )
119  ("centerX,x", po::value<unsigned int>()->default_value(0), "choose x center of the projected image." )
120  ("centerY,y", po::value<unsigned int>()->default_value(0), "choose y center of the projected image." )
121  ("centerZ,z", po::value<unsigned int>()->default_value(1), "choose z center of the projected image." )
122  ("width", po::value<unsigned int>()->default_value(100), "set the width of the resulting height Field image." )
123  ("height", po::value<unsigned int>()->default_value(100), "set the height of the resulting height Field image." )
124  ("heightFieldMaxScan", po::value<unsigned int>()->default_value(255), "set the maximal scan deep." )
125  ("setBackgroundLastDepth", "change the default background (black with the last filled intensity).");
126 
127 
128 
129  bool parseOK=true;
130  po::variables_map vm;
131  try{
132  po::store(po::parse_command_line(argc, argv, general_opt), vm);
133  }catch(const std::exception& ex){
134  parseOK=false;
135  trace.info()<< "Error checking program options: "<< ex.what()<< endl;
136  }
137  po::notify(vm);
138  if( !parseOK || vm.count("help")||argc<=1)
139  {
140  std::cout << "Usage: " << argv[0] << " [input] [output]\n"
141  << "Convert volumetric file into a projected 2D image given from a normal direction N and from a starting point P. The 3D volume is scanned in this normal direction N starting from P with a step 1. If the intensity of the 3d point is inside the given thresholds its 2D gray values are set to the current scan number."
142  << general_opt << "\n";
143  std::cout << "Example:\n"
144  << "vol2heightfield -i ${DGtal}/examples/samples/lobster.vol -m 60 -M 500 --nx 0 --ny 0.7 --nz -1 -x 150 -y 0 -z 150 --width 300 --height 300 --heightFieldMaxScan 350 -o resultingHeightMap.pgm \n";
145  return 0;
146  }
147 
148  if(! vm.count("input") ||! vm.count("output"))
149  {
150  trace.error() << " Input and output filename are needed to be defined" << endl;
151  return 0;
152  }
153 
154  string inputFilename = vm["input"].as<std::string>();
155  string outputFilename = vm["output"].as<std::string>();
156 
157  trace.info() << "Reading input file " << inputFilename ;
158  Image3D inputImage = DGtal::VolReader<Image3D>::importVol(inputFilename);
159  trace.info() << " [done] " << std::endl ;
160 
161  std::ofstream outStream;
162  outStream.open(outputFilename.c_str());
163  int minTh = vm["thresholdMin"].as<int>();
164  int maxTh = vm["thresholdMax"].as<int>();
165 
166  trace.info() << "Processing image to output file " << outputFilename ;
167 
168  unsigned int widthImageScan = vm["height"].as<unsigned int>();
169  unsigned int heightImageScan = vm["width"].as<unsigned int>();
170  unsigned int maxScan = vm["heightFieldMaxScan"].as<unsigned int>();
171  if(maxScan > std::numeric_limits<Image2D::Value>::max()){
172  maxScan = std::numeric_limits<Image2D::Value>::max();
173  trace.warning()<< "value --setBackgroundLastDepth outside mox value of image. Set to max value:" << maxScan << std::endl;
174  }
175 
176  unsigned int centerX = vm["centerX"].as<unsigned int>();
177  unsigned int centerY = vm["centerY"].as<unsigned int>();
178  unsigned int centerZ = vm["centerZ"].as<unsigned int>();
179 
180  double nx = vm["nx"].as<double>();
181  double ny = vm["ny"].as<double>();
182  double nz = vm["nz"].as<double>();
183 
184 
185  Image2D::Domain aDomain2D(DGtal::Z2i::Point(0,0),
186  DGtal::Z2i::Point(widthImageScan, heightImageScan));
187  Z3i::Point ptCenter (centerX, centerY, centerZ);
188  Z3i::RealPoint normalDir (nx, ny, nz);
189  Image2D resultingImage(aDomain2D);
190 
191  for(Image2D::Domain::ConstIterator it = resultingImage.domain().begin();
192  it != resultingImage.domain().end(); it++){
193  resultingImage.setValue(*it, 0);
194  }
195  DGtal::functors::Identity idV;
196 
197  unsigned int maxDepthFound = 0;
198  for(unsigned int k=0; k < maxScan; k++){
199  DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder(inputImage.domain(),
200  ptCenter+normalDir*k,
201  normalDir,
202  widthImageScan);
203  ImageAdapterExtractor extractedImage(inputImage, aDomain2D, embedder, idV);
204  for(Image2D::Domain::ConstIterator it = extractedImage.domain().begin();
205  it != extractedImage.domain().end(); it++){
206  if( resultingImage(*it)== 0 && extractedImage(*it) < maxTh &&
207  extractedImage(*it) > minTh){
208  maxDepthFound = k;
209  resultingImage.setValue(*it, maxScan-k);
210  }
211  }
212  }
213  if (vm.count("setBackgroundLastDepth")){
214  for(Image2D::Domain::ConstIterator it = resultingImage.domain().begin();
215  it != resultingImage.domain().end(); it++){
216  if( resultingImage(*it)== 0 ){
217  resultingImage.setValue(*it, maxScan-maxDepthFound);
218  }
219  }
220  }
221 
222  resultingImage >> outputFilename;
223 
224  trace.info() << " [done] " << std::endl ;
225  return 0;
226 }
227 
228 
229 
230 
STL namespace.