DGtalTools  0.9.4
vol2slice.cpp
1 
29 #include <iostream>
31 #include "DGtal/base/Common.h"
32 #include "DGtal/helpers/StdDefs.h"
33 
34 #include "DGtal/io/readers/GenericReader.h"
35 #include "DGtal/io/writers/GenericWriter.h"
36 #include "DGtal/images/ConstImageAdapter.h"
37 #include "DGtal/kernel/BasicPointFunctors.h"
38 
39 #include <boost/program_options/options_description.hpp>
40 #include <boost/program_options/parsers.hpp>
41 #include <boost/program_options/variables_map.hpp>
42 #include <boost/format.hpp>
43 
44 
45 
46 using namespace std;
47 using namespace DGtal;
48 
49 
51 namespace po = boost::program_options;
52 
102 int main( int argc, char** argv )
103 {
107  Image3D::Value, DGtal::functors::Identity > SliceImageAdapter;
108 
109 
110  // parse command line ----------------------------------------------
111  po::options_description general_opt("Allowed options are: ");
112  general_opt.add_options()
113  ("help,h", "display this message")
114  ("input,i", po::value<std::string>(), "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." )
115  ("output,o", po::value<std::string>(), "base_name.extension: extracted 2D slice volumetric files (will result n files base_name_xxx.extension) " )
116  ("setFirstSlice,f", po::value<unsigned int>()->default_value(0), "Set the first slice index to be extracted.")
117  ("setLastSlice,l", po::value<unsigned int>(), "Set the last slice index to be extracted (by default set to maximal value according to the given volume).")
118  ("sliceOrientation,s", po::value<unsigned int>()->default_value(2), "specify the slice orientation for which the slice are defined (by default =2 (Z direction))" )
119  ("rescaleInputMin", po::value<DGtal::int64_t>()->default_value(0), "min value used to rescale the input intensity (to avoid basic cast into 8 bits image).")
120  ("rescaleInputMax", po::value<DGtal::int64_t>()->default_value(255), "max value used to rescale the input intensity (to avoid basic cast into 8 bits image).");
121 
122 
123  bool parseOK=true;
124  po::variables_map vm;
125  try{
126  po::store(po::parse_command_line(argc, argv, general_opt), vm);
127  }catch(const std::exception& ex){
128  parseOK=false;
129  trace.info()<< "Error checking program options: "<< ex.what()<< endl;
130  }
131  po::notify(vm);
132 
133 
134  if( !parseOK || ! vm.count("input")||! vm.count("output") || vm.count("help"))
135  {
136  std::cout << "Usage: " << argv[0] << " [inputs] [output]\n"
137  << "Convert a volumetric file (.vol, .longvol, .pgm3d) into a set of 2D slice images."
138  << general_opt << "\n";
139  std::cout << "Example: to extract all slices defined in Y plane (y=cst): \n"
140  << "vol2slice -i image3d.vol -s 1 -o slice.pgm \n"
141  << "see slice2vol"<< endl;
142  return 0;
143  }
144 
145  if(! vm.count("input")||! vm.count("output"))
146  {
147  trace.error() << " Input and output filename are needed to be defined" << endl;
148  return 0;
149  }
150 
151 
152 
153 
154  std::string inputFileName = vm["input"].as<std::string>();
155  std::string outputFileName = vm["output"].as<std::string>();
156  std::string outputExt = outputFileName.substr(outputFileName.find_last_of(".")+1);
157  std::string outputBasename = outputFileName.substr(0, outputFileName.find_last_of("."));
158  unsigned int sliceOrientation = vm["sliceOrientation"].as<unsigned int>();
159  DGtal::int64_t rescaleInputMin = vm["rescaleInputMin"].as<DGtal::int64_t>();
160  DGtal::int64_t rescaleInputMax = vm["rescaleInputMax"].as<DGtal::int64_t>();
161 
162 
163  trace.info()<< "Importing volume file base name: " << outputBasename << " extension: " << outputExt << " ..." ;
165  Image3D input3dImage = GenericReader< Image3D >::importWithValueFunctor( inputFileName,RescalFCT(rescaleInputMin,
166  rescaleInputMax,
167  0, 255) );
168 
169  trace.info()<< "[done]" << endl;
170 
171  unsigned int startSlice=0;
172  unsigned int endSlice=input3dImage.domain().upperBound()[sliceOrientation];
173 
174  if(vm.count("setFirstSlice")){
175  startSlice = vm["setFirstSlice"].as<unsigned int>();
176  }
177  if(vm.count("setLastSlice")){
178  endSlice = vm["setLastSlice"].as<unsigned int>();
179  }
180 
181  //Processing each slice
182 #pragma omp parallel for schedule(dynamic)
183  for( unsigned int i=startSlice; i <= endSlice; i++){
184  trace.info() << "Exporting slice image "<< i ;
185  DGtal::functors::Projector<DGtal::Z2i::Space> invFunctor; invFunctor.initRemoveOneDim(sliceOrientation);
186  DGtal::Z2i::Domain domain2D(invFunctor(input3dImage.domain().lowerBound()),
187  invFunctor(input3dImage.domain().upperBound()));
188  DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(i); aSliceFunctor.initAddOneDim(sliceOrientation);
189  const DGtal::functors::Identity identityFunctor{};
190  SliceImageAdapter sliceImage( input3dImage, domain2D, aSliceFunctor, identityFunctor );
191  stringstream outName; outName << outputBasename << "_" << boost::format("%|05|")% i <<"."<< outputExt ;
192  trace.info() << ": "<< outName.str() ;
193  GenericWriter<SliceImageAdapter>::exportFile(outName.str(), sliceImage);
194  trace.info() << " [done]"<< endl;
195  }
196 
197 
198  return 0;
199 }
STL namespace.
void initRemoveOneDim(const Dimension &dimRemoved)
Trace trace(traceWriterTerm)
std::ostream & info()
const Domain & domain() const
std::ostream & error()
boost::int64_t int64_t