DGtalTools  1.2.0
vol2heightfield.cpp
1 
30 #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/GenericReader.h"
37 #include "DGtal/images/ConstImageAdapter.h"
38 #include "DGtal/kernel/BasicPointFunctors.h"
39 
40 #include "CLI11.hpp"
41 
42 using namespace std;
43 using namespace DGtal;
44 
45 
46 
99 int main( int argc, char** argv )
100 {
101  typedef ImageContainerBySTLVector < Z3i::Domain, unsigned char > Image3D;
102  typedef ImageContainerBySTLVector < Z2i::Domain, unsigned char> Image2D;
103  typedef DGtal::ConstImageAdapter<Image3D, Z2i::Domain, DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain>,
104  Image3D::Value, DGtal::functors::Identity > ImageAdapterExtractor;
105 
106 // parse command line using CLI ----------------------------------------------
107  CLI::App app;
108  std::string inputFileName;
109  std::string outputFileName {"result.pgm"};
110  int thresholdMin {128};
111  int thresholdMax {255};
112  DGtal::int64_t rescaleInputMin {0};
113  DGtal::int64_t rescaleInputMax {255};
114  double nx {0};
115  double ny {0};
116  double nz {1};
117  unsigned int centerX {0};
118  unsigned int centerY {0};
119  unsigned int centerZ {0};
120  unsigned int heightImageScan {100};
121  unsigned int widthImageScan {100};
122  unsigned int heightFieldMaxScan {255};
123  unsigned int maxScan;
124  bool bgLastDepth = false;
125 
126  app.description("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.\n Example:\n 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");
127  app.add_option("-i,--input,1", inputFileName, "vol file (.vol, .longvol .p3d, .pgm3d and if WITH_ITK is selected: dicom, dcm, mha, mhd). For longvol, dicom, dcm, mha or mhd formats, the input values are linearly scaled between 0 and 255." )
128  ->required()
129  ->check(CLI::ExistingFile);
130  app.add_option("-o,--output,2", outputFileName, "resulting image filename (in pgm or other).");
131  app.add_option("--thresholdMin,-m", thresholdMin, "threshold min (excluded) to define binary shape.", true);
132  app.add_option("--thresholdMax,-M", thresholdMax, "threshold max (included) to define binary shape.", true);
133  app.add_option("--rescaleInputMin", rescaleInputMin, "min value used to rescale the input intensity (to avoid basic cast into 8 bits image).", true);
134  app.add_option("--rescaleInputMax", rescaleInputMax, "max value used to rescale the input intensity (to avoid basic cast into 8 bits image).", true);
135 
136  app.add_option("--nx",nx, "set the x component of the projection direction.", true);
137  app.add_option("--ny",ny, "set the y component of the projection direction.", true);
138  app.add_option("--nz",nz, "set the z component of the projection direction.", true);
139  app.add_option("--centerX,-x", centerX, "choose x center of the projected image.", true);
140  app.add_option("--centerY,-y", centerY, "choose y center of the projected image.", true);
141  app.add_option("--centerZ,-z", centerZ, "choose z center of the projected image.", true);
142  app.add_option("--width,-w", widthImageScan, "set the width of the resulting height Field image.", true);
143  app.add_option("--height", heightImageScan, "set the height of the resulting height Field image.", true);
144  app.add_option("--heightFieldMaxScan",maxScan, "set the maximal scan deep.");
145  app.add_flag("--setBackgroundLastDepth", bgLastDepth,"change the default background (black with the last filled intensity).");
146 
147 
148  app.get_formatter()->column_width(40);
149  CLI11_PARSE(app, argc, argv);
150  // END parse command line using CLI ----------------------------------------------
151 
152 
153  trace.info() << "Reading input file " << inputFileName ;
154 
155  typedef DGtal::functors::Rescaling<DGtal::int64_t ,unsigned char > RescalFCT;
156  Image3D inputImage = GenericReader< Image3D >::importWithValueFunctor( inputFileName,RescalFCT(rescaleInputMin,
157  rescaleInputMax,
158  0, 255) );
159 
160  trace.info() << " [done] " << std::endl ;
161  std::ofstream outStream;
162  outStream.open(outputFileName.c_str());
163 
164  trace.info() << "Processing image to output file " << outputFileName << std::endl;
165 
166  if(maxScan > std::numeric_limits<Image2D::Value>::max()){
167  maxScan = std::numeric_limits<Image2D::Value>::max();
168  trace.warning()<< "value --setBackgroundLastDepth outside mox value of image. Set to max value:" << maxScan << std::endl;
169  }
170 
171 
172  Image2D::Domain aDomain2D(DGtal::Z2i::Point(0,0),
173  DGtal::Z2i::Point(widthImageScan, heightImageScan));
174  Z3i::Point ptCenter (centerX, centerY, centerZ);
175  Z3i::RealPoint normalDir (nx, ny, nz);
176  Image2D resultingImage(aDomain2D);
177 
178  for(Image2D::Domain::ConstIterator it = resultingImage.domain().begin();
179  it != resultingImage.domain().end(); it++){
180  resultingImage.setValue(*it, 0);
181  }
182  DGtal::functors::Identity idV;
183 
184  unsigned int maxDepthFound = 0;
185  for(unsigned int k=0; k < maxScan; k++){
186  Z3i::Point c (ptCenter+normalDir*k, DGtal::functors::Round<>());
187  DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder(inputImage.domain(),
188  c,
189  normalDir,
190  widthImageScan);
191  ImageAdapterExtractor extractedImage(inputImage, aDomain2D, embedder, idV);
192  for(Image2D::Domain::ConstIterator it = extractedImage.domain().begin();
193  it != extractedImage.domain().end(); it++){
194  if( resultingImage(*it)== 0 && extractedImage(*it) < thresholdMax &&
195  extractedImage(*it) > thresholdMin){
196  maxDepthFound = k;
197  resultingImage.setValue(*it, maxScan-k);
198  }
199  }
200  }
201  if (bgLastDepth) {
202  for(Image2D::Domain::ConstIterator it = resultingImage.domain().begin();
203  it != resultingImage.domain().end(); it++){
204  if( resultingImage(*it)== 0 ){
205  resultingImage.setValue(*it, maxScan-maxDepthFound);
206  }
207  }
208  }
209  resultingImage >> outputFileName;
210  trace.info() << " [done] " << std::endl ;
211  return EXIT_SUCCESS;
212 }
Definition: ATu0v1.h:57