DGtalTools  1.2.0
vol2slice.cpp
1 
30 #include <iostream>
31 #include "DGtal/base/Common.h"
32 #include "DGtal/helpers/StdDefs.h"
33 #include <boost/format.hpp>
34 
35 #include "DGtal/io/readers/GenericReader.h"
36 #include "DGtal/io/writers/GenericWriter.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 
47 
95 int main( int argc, char** argv )
96 {
97  typedef ImageContainerBySTLVector < Z3i::Domain, unsigned char > Image3D;
98  typedef ImageContainerBySTLVector < Z2i::Domain, unsigned char > Image2D;
99  typedef DGtal::ConstImageAdapter<Image3D, Image2D::Domain, DGtal::functors::Projector< DGtal::Z3i::Space>,
100  Image3D::Value, DGtal::functors::Identity > SliceImageAdapter;
101 
102  CLI::App app;
103 
104 
105  std::string inputFileName;
106  std::string outputFileName = "result.pgm";
107  DGtal::int64_t rescaleInputMin {0};
108  DGtal::int64_t rescaleInputMax {255};
109  int userStartSlice {0};
110  int userEndSlice;
111  unsigned int sliceOrientation {2};
112 
113 
114  app.description("Convert a volumetric file (.vol, .longvol, .pgm3d) into a set of 2D slice images. \n Typical use: to extract all slices defined in Y plane (y=cst): \n vol2slice image3d.vol slice.pgm -s 1 \n");
115 
116  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.")
117  ->required()
118  ->check(CLI::ExistingFile);
119 
120  app.add_option("--output,-o,2",outputFileName ,"base_name.extension: extracted 2D slice volumetric files (will result n files base_name_xxx.extension)", true);
121  app.add_option("--setFirstSlice,-f", userStartSlice, "Set the first slice index to be extracted.", true)
122  -> check(CLI::Number);
123  app.add_option("--setLastSlice,-l", userEndSlice, "Set the last slice index to be extracted (by default set to maximal value according to the given volume).")
124  -> check(CLI::Number);
125  app.add_option("--sliceOrientation,-s", sliceOrientation, "specify the slice orientation for which the slice are defined (by default =2 (Z direction))", true)
126  -> check(CLI::IsMember({0, 1, 2}));
127  app.add_option("--rescaleInputMin", rescaleInputMin, "min value used to rescale the input intensity (to avoid basic cast into 8 bits image).", true);
128  app.add_option("--rescaleInputMax", rescaleInputMax, "max value used to rescale the input intensity (to avoid basic cast into 8 bits image).", true);
129  app.get_formatter()->column_width(40);
130 
131  CLI11_PARSE(app, argc, argv);
132 
133  std::string outputExt = outputFileName.substr(outputFileName.find_last_of(".")+1);
134  std::string outputBasename = outputFileName.substr(0, outputFileName.find_last_of("."));
135 
136 
137  trace.info()<< "Importing volume file base name: " << outputBasename << " extension: " << outputExt << " ..." ;
138  typedef DGtal::functors::Rescaling<DGtal::int64_t ,unsigned char > RescalFCT;
139  Image3D input3dImage = GenericReader< Image3D >::importWithValueFunctor( inputFileName,RescalFCT(rescaleInputMin,
140  rescaleInputMax,
141  0, 255) );
142 
143  trace.info()<< "[done]" << endl;
144 
145  unsigned int startSlice=0;
146  unsigned int endSlice=input3dImage.domain().upperBound()[sliceOrientation];
147 
148  if(userStartSlice !=0){
149  startSlice = userStartSlice;
150  }
151  if(userEndSlice != 0){
152  endSlice = userEndSlice;
153  }
154 
155  //Processing each slice
156 #pragma omp parallel for schedule(dynamic)
157  for( unsigned int i=startSlice; i <= endSlice; i++){
158  trace.info() << "Exporting slice image "<< i ;
159  DGtal::functors::Projector<DGtal::Z2i::Space> invFunctor; invFunctor.initRemoveOneDim(sliceOrientation);
160  DGtal::Z2i::Domain domain2D(invFunctor(input3dImage.domain().lowerBound()),
161  invFunctor(input3dImage.domain().upperBound()));
162  DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(i); aSliceFunctor.initAddOneDim(sliceOrientation);
163  const DGtal::functors::Identity identityFunctor{};
164  SliceImageAdapter sliceImage( input3dImage, domain2D, aSliceFunctor, identityFunctor );
165  stringstream outName; outName << outputBasename << "_" << boost::format("%|05|")% i <<"."<< outputExt ;
166  trace.info() << ": "<< outName.str() ;
167  GenericWriter<SliceImageAdapter>::exportFile(outName.str(), sliceImage);
168  trace.info() << " [done]"<< endl;
169  }
170 
171 
172  return 0;
173 }
Definition: ATu0v1.h:57