1 #include <tclap/CmdLine.h> 4 #include <itkCommand.h> 5 #include <itkExtractImageFilter.h> 6 #include <itkImageRegionIteratorWithIndex.h> 12 void eventCallback (itk::Object* caller,
const itk::EventObject& event,
void* clientData)
14 itk::ProcessObject * processObject = (itk::ProcessObject*) caller;
15 std::cout<<
"\033[K\rProgression: "<<(int)(processObject->GetProgress() * 100)<<
"%"<<std::flush;
24 template <
class InputImageType,
unsigned int OutputDimension>
28 typename InputImageType::Pointer
input = anima::readImage<InputImageType>(args.
input);
30 typename InputImageType::SizeType inputSize;
31 inputSize = input->GetLargestPossibleRegion().GetSize();
33 typename InputImageType::RegionType extractRegion;
34 typename InputImageType::SizeType extractSize;
35 typename InputImageType::IndexType extractIndex;
40 for (
unsigned int d = 0; d < InputImageType::ImageDimension; ++d)
42 extractIndex[d] = indexes[d];
43 if(sizes[d] == -1 || indexes[d] + sizes[d] > inputSize[d])
44 extractSize[d] = inputSize[d] - extractIndex[d];
46 extractSize[d] = sizes[d];
49 extractRegion.SetIndex(extractIndex);
50 extractRegion.SetSize(extractSize);
52 std::cout<<
"Input will be crop using ROI of dimensions:" << extractRegion << std::endl;
54 if(input->GetNumberOfComponentsPerPixel() == 1)
56 typedef itk::Image<typename InputImageType::PixelType, OutputDimension> OutputImageType;
58 typedef itk::ExtractImageFilter<InputImageType, OutputImageType> ExtractFilterType;
59 typename ExtractFilterType::Pointer extractFilter = ExtractFilterType::New();
60 extractFilter->SetExtractionRegion(extractRegion);
61 extractFilter->SetDirectionCollapseToGuess();
62 extractFilter->SetInput(input);
64 itk::CStyleCommand::Pointer callback = itk::CStyleCommand::New();
66 extractFilter->AddObserver(itk::ProgressEvent(), callback);
67 extractFilter->Update();
69 typename OutputImageType::Pointer
output = extractFilter->GetOutput();
71 std::cout <<
"\n\nOutput dimensions: " << output->GetLargestPossibleRegion();
76 typedef itk::VectorImage<typename InputImageType::InternalPixelType, OutputDimension> OutputImageType;
78 typedef itk::ExtractImageFilter<InputImageType, OutputImageType> ExtractFilterType;
79 typename ExtractFilterType::Pointer extractFilter = ExtractFilterType::New();
80 extractFilter->SetExtractionRegion(extractRegion);
81 extractFilter->SetDirectionCollapseToGuess();
82 extractFilter->SetInput(input);
84 itk::CStyleCommand::Pointer callback = itk::CStyleCommand::New();
86 extractFilter->AddObserver(itk::ProgressEvent(), callback);
87 extractFilter->Update();
89 typename OutputImageType::Pointer
output = extractFilter->GetOutput();
91 std::cout <<
"\n\nOutput dimensions: " << output->GetLargestPossibleRegion();
98 template <
class InputImageType>
102 unsigned int imageDim = InputImageType::ImageDimension;
108 unsigned int outputDim = 2;
109 outputDim -= (args.
xsize == 0)? 1 :0;
110 outputDim -= (args.
ysize == 0)? 1 :0;
114 if constexpr (InputImageType::ImageDimension >= 1)
115 extract<InputImageType, 1>(args);
118 if constexpr (InputImageType::ImageDimension >= 2)
119 extract<InputImageType, 2>(args);
122 std::string msg =
"Number of collapsed dimension not supported.";
123 itk::ExceptionObject excp(__FILE__, __LINE__,msg , ITK_LOCATION);
130 unsigned int outputDim = 3;
131 outputDim -= (args.
xsize == 0)? 1 :0;
132 outputDim -= (args.
ysize == 0)? 1 :0;
133 outputDim -= (args.
zsize == 0)? 1 :0;
137 if constexpr (InputImageType::ImageDimension >= 1)
138 extract<InputImageType, 1>(args);
141 if constexpr (InputImageType::ImageDimension >= 2)
142 extract<InputImageType, 2>(args);
145 if constexpr (InputImageType::ImageDimension >= 3)
146 extract<InputImageType, 3>(args);
149 std::string msg =
"Number of collapsed dimension not supported.";
150 itk::ExceptionObject excp(__FILE__, __LINE__,msg , ITK_LOCATION);
157 unsigned int outputDim = 4;
158 outputDim -= (args.
xsize == 0)? 1 :0;
159 outputDim -= (args.
ysize == 0)? 1 :0;
160 outputDim -= (args.
zsize == 0)? 1 :0;
161 outputDim -= (args.
tsize == 0)? 1 :0;
165 if constexpr (InputImageType::ImageDimension >= 1)
166 extract<InputImageType, 1>(args);
169 if constexpr (InputImageType::ImageDimension >= 2)
170 extract<InputImageType, 2>(args);
173 if constexpr (InputImageType::ImageDimension >= 3)
174 extract<InputImageType, 3>(args);
177 if constexpr (InputImageType::ImageDimension >= 4)
178 extract<InputImageType, 4>(args);
181 std::string msg =
"Number of collapsed dimension not supported.";
182 itk::ExceptionObject excp(__FILE__, __LINE__,msg , ITK_LOCATION);
188 std::string msg =
"Number of collapsed dimension not supported.";
189 itk::ExceptionObject excp(__FILE__, __LINE__,msg , ITK_LOCATION);
194 template <
class ComponentType,
int dimension>
202 template <
class ComponentType >
209 int main(
int ac,
const char** av)
212 TCLAP::CmdLine cmd(
"The animaCropImage uses an itkExtractImage filter to crop " 213 "an image given as input.\n" 214 "The lower case arguments(x<xindex>, y<yindex>, z<zindex>, t<tindex>)" 215 " are the starting indexes of the input region to keep. The default value is 0\n" 216 "The upper case arguments(X<xsize>, Y<ysize>, Z<zsize>, T<tsize>) are the sizes of " 217 "the input region to keep. The default value is the largest possible sizes given the " 218 "corresponding indexes.\nIf you give args size of zero the corresponding dimension will " 219 "be collapsed.\nExample: for args a 4D image 4x4x4x4 the arguments :\n --xindex 1" 220 " --zindex 1 --zsize 2 --tindex 3 --tsize 0\n will result on an image 3x4x2\n" 221 "Where the x dim corresponds to [1,2,3] of the input, y[0,3], zindex[1,2] and tindex is " 222 "collapsed, only the last sequence has been kept." 223 "INRIA / IRISA - VisAGeS/Empenn Team",
227 TCLAP::ValueArg<std::string> inputArg(
"i",
229 "Input image to crop",
232 "Input image to crop",
235 TCLAP::ValueArg<std::string> outputArg(
"o",
237 "Output cropped image",
240 "Output cropped image",
243 TCLAP::ValueArg<std::string> maskArg(
"m",
245 "A mask used instead of other arguments to determine a bounding box",
251 TCLAP::ValueArg<unsigned int> xArg(
"x",
253 "The resulting croped image will go from xindex to xsize along the xindex axis.",
256 "Start of ROI for the xindex dimension",
259 TCLAP::ValueArg<unsigned int> XArg(
"X",
261 "The resulting croped image will go from xindex to xsize along the xindex axis. If 0 the dimension is collapsed.",
264 "Size of ROI for the xindex dimension",
267 TCLAP::ValueArg<unsigned int> yArg(
"y",
269 "The resulting croped image will go from yindex to ysize along the yindex axis.",
272 "Start of ROI for the yindex dimension",
275 TCLAP::ValueArg<unsigned int> YArg(
"Y",
277 "The resulting croped image will go from yindex to ysize along the yindex axis. If 0 the dimension is collapsed.",
280 "Size of ROI for the yindex dimension",
282 TCLAP::ValueArg<unsigned int> zArg(
"z",
284 "The resulting croped image will go from yindex to ysize along the zindex axis.",
287 "Start of ROI for the zindex dimension",
290 TCLAP::ValueArg<unsigned int> ZArg(
"Z",
292 "The resulting croped image will go from zindex to zsize along the zindex axis. If 0 the dimension is collapsed.",
295 "Size of ROI for the zindex dimension",
297 TCLAP::ValueArg<unsigned int> tArg(
"t",
299 "The resulting croped image will go from tindex to tsize along the tindex axis.",
302 "Start of ROI for the tindex dimension",
305 TCLAP::ValueArg<unsigned int> TArg(
"T",
307 "The resulting croped image will go from tindex to tsize along the tindex axis. If 0 the dimension is collapsed.",
310 "Size of ROI for the tindex dimension",
317 catch (TCLAP::ArgException& e)
319 std::cerr <<
"Error: " << e.error() <<
"for argument " << e.argId() << std::endl;
324 itk::ImageIOBase::Pointer
imageIO = itk::ImageIOFactory::CreateImageIO(inputArg.getValue().c_str(),
325 itk::ImageIOFactory::ReadMode);
329 std::cerr <<
"Itk could not find suitable IO factory for the input" << std::endl;
334 imageIO->SetFileName(inputArg.getValue());
335 imageIO->ReadImageInformation();
337 std::cout<<
"\npreparing filter...\n";
340 args.
xindex = xArg.getValue(); args.
xsize = XArg.getValue();
341 args.
yindex = yArg.getValue(); args.
ysize = YArg.getValue();
342 args.
zindex = zArg.getValue(); args.
zsize = ZArg.getValue();
343 args.
tindex = tArg.getValue(); args.
tsize = TArg.getValue();
345 if (maskArg.getValue() !=
"")
347 typedef itk::Image <unsigned char, 3> MaskImageType;
348 MaskImageType::Pointer maskIm = anima::readImage<MaskImageType>(maskArg.getValue());
349 unsigned int xMax = maskIm->GetLargestPossibleRegion().GetIndex()[0];
350 unsigned int yMax = maskIm->GetLargestPossibleRegion().GetIndex()[1];
351 unsigned int zMax = maskIm->GetLargestPossibleRegion().GetIndex()[2];
352 unsigned int xMin = maskIm->GetLargestPossibleRegion().GetIndex()[0] + maskIm->GetLargestPossibleRegion().GetSize()[0];
353 unsigned int yMin = maskIm->GetLargestPossibleRegion().GetIndex()[1] + maskIm->GetLargestPossibleRegion().GetSize()[1];
354 unsigned int zMin = maskIm->GetLargestPossibleRegion().GetIndex()[2] + maskIm->GetLargestPossibleRegion().GetSize()[2];
356 typedef itk::ImageRegionIteratorWithIndex <MaskImageType> MaskIteratorType;
357 typedef MaskImageType::IndexType IndexType;
358 MaskIteratorType maskIt(maskIm,maskIm->GetLargestPossibleRegion());
359 while (!maskIt.IsAtEnd())
361 if (maskIt.Get() != 0)
363 IndexType tmpIndex = maskIt.GetIndex();
364 if (xMax < tmpIndex[0])
366 if (yMax < tmpIndex[1])
368 if (zMax < tmpIndex[2])
371 if (xMin > tmpIndex[0])
373 if (yMin > tmpIndex[1])
375 if (zMin > tmpIndex[2])
386 args.
xsize = xMax - xMin + 1;
387 args.
ysize = yMax - yMin + 1;
388 args.
zsize = zMax - zMin + 1;
391 args.
input = inputArg.getValue(); args.
output = outputArg.getValue();
397 catch ( itk::ExceptionObject & err )
399 std::cerr <<
"Itk cannot extract, be sure to use valid arguments..." << std::endl;
400 std::cerr << err << std::endl;
void evaluateOutputType(const arguments &args)
void extract(const arguments &args)
void checkIfComponentsAreVectors(itk::ImageIOBase::Pointer imageIO, const arguments &args)
itk::ImageIOBase::Pointer imageIO
int main(int ac, const char **av)
#define ANIMA_RETRIEVE_COMPONENT_TYPE(imageIO, function,...)
void retrieveNbDimensions(itk::ImageIOBase::Pointer imageIO, const arguments &args)
#define ANIMA_RETRIEVE_NUMBER_OF_DIMENSIONS(imageIO, ComponentType, function,...)
void eventCallback(itk::Object *caller, const itk::EventObject &event, void *clientData)
#define ANIMA_CHECK_IF_COMPONENTS_ARE_VECTORS(imageIO, ComponentType, Dimension, function,...)