31 #include "DGtal/base/Common.h"
32 #include "DGtal/helpers/StdDefs.h"
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"
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>
47 using namespace DGtal;
51 namespace po = boost::program_options;
93 int main(
int argc,
char** argv )
95 typedef ImageContainerBySTLVector < Z3i::Domain, unsigned char > Image3D;
96 typedef ImageContainerBySTLVector < Z2i::Domain, unsigned char > Image2D;
97 typedef DGtal::ConstImageAdapter<Image3D, Image2D::Domain, DGtal::functors::Projector< DGtal::Z3i::Space>,
98 Image3D::Value, DGtal::functors::Identity > SliceImageAdapter;
102 po::options_description general_opt(
"Allowed options are: ");
103 general_opt.add_options()
104 (
"help,h",
"display this message")
105 (
"input,i", po::value<std::string >(),
"input volumetric file (.vol, .longvol, .pgm3d) " )
106 (
"output,o", po::value<std::string>(),
"base_name.extension: extracted 2D slice volumetric files (will result n files base_name_xxx.extension) " )
107 (
"setFirstSlice,f", po::value<unsigned int>()->default_value(0),
"Set the first slice index to be extracted.")
108 (
"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).")
109 (
"sliceOrientation,s", po::value<unsigned int>()->default_value(2),
"specify the slice orientation for which the slice are defined (by default =2 (Z direction))" );
113 po::variables_map vm;
115 po::store(po::parse_command_line(argc, argv, general_opt), vm);
116 }
catch(
const std::exception& ex){
118 trace.info()<<
"Error checking program options: "<< ex.what()<< endl;
123 if( !parseOK || ! vm.count(
"input")||! vm.count(
"output") || vm.count(
"help"))
125 std::cout <<
"Usage: " << argv[0] <<
" [inputs] [output]\n"
126 <<
"Convert a volumetric file (.vol, .longvol, .pgm3d) into a set of 2D slice images."
127 << general_opt <<
"\n";
128 std::cout <<
"Example: to extract all slices defined in Y plane (y=cst): \n"
129 <<
"vol2slice -i image3d.vol -s 1 -o slice.pgm \n"
130 <<
"see slice2vol"<< endl;
134 if(! vm.count(
"input")||! vm.count(
"output"))
136 trace.error() <<
" Input and output filename are needed to be defined" << endl;
143 std::string inputFileName = vm[
"input"].as<std::string>();
144 std::string outputFileName = vm[
"output"].as<std::string>();
145 std::string outputExt = outputFileName.substr(outputFileName.find_last_of(
".")+1);
146 std::string outputBasename = outputFileName.substr(0, outputFileName.find_last_of(
"."));
147 unsigned int sliceOrientation = vm[
"sliceOrientation"].as<
unsigned int>();
150 trace.info()<<
"Importing volume file base name: " << outputBasename <<
" extension: " << outputExt <<
" ..." ;
151 Image3D input3dImage = GenericReader<Image3D>::import(inputFileName);
152 trace.info()<<
"[done]" << endl;
154 unsigned int startSlice=0;
155 unsigned int endSlice=input3dImage.domain().upperBound()[sliceOrientation];
157 if(vm.count(
"setFirstSlice")){
158 startSlice = vm[
"setFirstSlice"].as<
unsigned int>();
160 if(vm.count(
"setLastSlice")){
161 endSlice = vm[
"setLastSlice"].as<
unsigned int>();
165 #pragma omp parallel for schedule(dynamic)
166 for(
unsigned int i=startSlice; i <= endSlice; i++){
167 trace.info() <<
"Exporting slice image "<< i ;
168 DGtal::functors::Projector<DGtal::Z2i::Space> invFunctor; invFunctor.initRemoveOneDim(sliceOrientation);
169 DGtal::Z2i::Domain domain2D(invFunctor(input3dImage.domain().lowerBound()),
170 invFunctor(input3dImage.domain().upperBound()));
171 DGtal::functors::Projector<DGtal::Z3i::Space> aSliceFunctor(i); aSliceFunctor.initAddOneDim(sliceOrientation);
172 const DGtal::functors::Identity identityFunctor{};
173 SliceImageAdapter sliceImage( input3dImage, domain2D, aSliceFunctor, identityFunctor );
174 stringstream outName; outName << outputBasename <<
"_" << boost::format(
"%|05|")% i <<
"."<< outputExt ;
175 trace.info() <<
": "<< outName.str() ;
176 GenericWriter<SliceImageAdapter>::exportFile(outName.str(), sliceImage);
177 trace.info() <<
" [done]"<< endl;