Re-Run Pipeline With Changing Largest Possible Region

Synopsis

Re-run a pipeline where the LargestPossibleRegion in the pipeline is expected to change on consecutive runs. The pipeline does not detect this condition, and it will throw an exception,

Requested region is (at least partially) outside the largest possible region.

In this case, an UpdateLargestPossibleRegion() call is required instead of Update().

Results

Output:

Initial LargestPossibleRegion: ImageRegion (0x7fff11257330)
Dimension: 3
Index: [0, 0, 0]
Size: [256, 256, 3]


Trying to call Update() after shrinking the LargestPossibleRegion...

Error:
itk::InvalidRequestedRegionError (0x28cd880)
Location: "unknown"
File: /home/matt/bin/ITKExamples-Clang-RelWithDebInfo/ITK/Modules/Core/Common/src/itkDataObject.cxx
Line: 411
Description: Requested region is (at least partially) outside the largest possible region.


Trying to call UpdateLargestPossibleRegion() after shrinking the LargestPossibleRegion...

Shrunk LargestPossibleRegion: ImageRegion (0x7fff11257330)
  Dimension: 3
  Index: [0, 0, 0]
  Size: [256, 256, 2]

Code

C++

#include "itkImageSeriesReader.h"
#include "itkNumericSeriesFileNames.h"

int
main(int argc, char * argv[])
{
  if (argc != 4)
  {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0];
    std::cerr << " <seriesFormat> <startIndex> <endIndex>";
    std::cerr << std::endl;
    return EXIT_FAILURE;
  }

  const char * seriesFormat = argv[1];
  unsigned int startIndex = std::stoi(argv[2]);
  unsigned int endIndex = std::stoi(argv[3]);

  constexpr unsigned int Dimension = 3;

  using PixelType = unsigned char;
  using ImageType = itk::Image<PixelType, Dimension>;

  using NameGeneratorType = itk::NumericSeriesFileNames;
  NameGeneratorType::Pointer nameGenerator = NameGeneratorType::New();
  nameGenerator->SetSeriesFormat(seriesFormat);
  nameGenerator->SetStartIndex(startIndex);
  nameGenerator->SetEndIndex(endIndex);
  std::vector<std::string> fileNames = nameGenerator->GetFileNames();

  using ReaderType = itk::ImageSeriesReader<ImageType>;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileNames(fileNames);

  try
  {
    reader->Update();

    ImageType::ConstPointer     output = reader->GetOutput();
    const ImageType::RegionType largestRegion = output->GetLargestPossibleRegion();
    std::cout << "Initial LargestPossibleRegion: ";
    std::cout << largestRegion << std::endl;
    ;
  }
  catch (itk::ExceptionObject & error)
  {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
  }

  fileNames.pop_back();

  try
  {
    std::cout << "\nTrying to call Update() "
              << "after shrinking the LargestPossibleRegion...\n"
              << std::endl;
    reader->SetFileNames(fileNames);
    reader->Update();
  }
  catch (itk::ExceptionObject & error)
  {
    // Print out the error that occurs
    std::cout << "Error: " << error << std::endl;
  }

  try
  {
    std::cout << "Trying to call UpdateLargestPossibleRegion() "
              << "after shrinking the LargestPossibleRegion...\n"
              << std::endl;
    reader->SetFileNames(fileNames);
    reader->UpdateLargestPossibleRegion();

    ImageType::ConstPointer     output = reader->GetOutput();
    const ImageType::RegionType largestRegion = output->GetLargestPossibleRegion();
    std::cout << "Shrunk LargestPossibleRegion: ";
    std::cout << largestRegion << std::endl;
    ;
  }
  catch (itk::ExceptionObject & error)
  {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

Classes demonstrated

class ProcessObject : public itk::Object

The base class for all process objects (source, filters, mappers) in the Insight data processing pipeline.

ProcessObject is an abstract object that specifies behavior and interface of network process objects (sources, filters, mappers). Source objects are creators of visualization data; filters input, process, and output image data; and mappers transform data into another form (like transforming coordinates or writing data to a file).

A major role of ProcessObject is to define the inputs and outputs of a filter. More than one input and/or output may exist for a given filter. Some classes (e.g., source objects or mapper objects) will not use inputs (the source) or outputs (mappers). In this case, the inputs or outputs is just ignored.

VOCABULARY:

  • named entry - an entry indexed by a DataObjectIdentifierType or string.

  • index entry - an entry indexed by an integer, which also always has a string identifier.

  • define an input/output - adds a named entry or a indexed entry.

  • required input - a precondition that the inputs is set before updating.

  • set the value - set the value of an input or output, and automatically define the entry if it does not exist.

The inputs and outputs are referenced by name and optionally by an integer index. The

Primary input and the Primary output play a special role: they drive the pipeline.
Note

  • The Primary Input is always defined internally, and is handled as a special case for many methods.

  • Some inputs can be defined as required. Either explicitly by name or the older ITKv3 style where a certain number of index inputs are required.

In addition to the reference by name, it is possible to access the inputs and outputs with an index. The index by default is mapped internally to a name with ‘_’ followed by the index number. This default name can be changed with the AddRequiredInputName method. The indexed input or output 0 is mapped to the Primary input or output. The name of the Primary input or output defaults to “Primary”, but this can be changed with SetPrimaryInputName and SetPrimaryOutputName.

For complicated filters which have optional, or varied required inputs, named input access is preferred. However, indexed input access provides constant time access to input and output DataObjects, and so are more efficient. A name can also be associated with an indexed input. Neither type of input or output should be accessed in a tight loop.

ProcessObject invokes the following events: Command::StartEvent, Command::EndEvent These are convenience events you can use for any purpose (e.g., debugging info, highlighting/notifying user interface, etc.) See Command and LightObject for information on using AddObserver.

Another event Command::ProgressEvent can be observed. Some filters invoke this event periodically during their execution (with the progress, parameter, the fraction of work done). The use is similar to that of StartEvent and EndEvent. Filters may also check their AbortGenerateData flag to determine whether to prematurely end their execution.

An important feature of subclasses of ProcessObject is that it is possible to control the memory-management model (i.e., retain output versus delete output data). The ReleaseDataFlag enables the deletion of the output data once the downstream process object finishes processing the data (please see text). The ReleaseDataBeforeUpdateFlag enables the deletion of the ProcessObject’s output data from a previous update if that output data is slated to be regenerated by the pipeline process. Setting this flag can control peak memory usage during a subsequent pipeline update. For a ProcessObject, the ReleaseDataFlag defaults to false and the ReleaseDataBeforeUpdateFlag defaults to true. Some subclasses of ProcessObject, for example ImageSource, use a default setting of false for the ReleaseDataBeforeUpdateFlag.

Subclasses of ProcessObject may override 4 of the methods of this class to control how a given filter may interact with the pipeline (dataflow). These methods are: GenerateOutputInformation(), EnlargeOutputRequestedRegion(), GenerateInputRequestedRegion(), and GenerateOutputRequestedRegion(). By overriding these methods, a filter can deviate from the base assumptions of the pipeline execution model.

Subclassed by itk::ImageSource< Functor::MakeJoin< TInputImage1, TInputImage2 >::ImageType >, itk::ImageSource< Image< CovariantVector< TDataType, TInputImage::ImageDimension >, TInputImage::ImageDimension > >, itk::ImageSource< Image< DiffusionTensor3D< TTensorPixelType >, 3 > >, itk::ImageSource< Image< IdentifierType, TInputImage::ImageDimension > >, itk::ImageSource< Image< TLabelsType, TInputVectorImage::ImageDimension > >, itk::ImageSource< Image< TOutputPixelType, 2 > >, itk::ImageSource< Image< TOutputPixelType, TInputImage::ImageDimension > >, itk::ImageSource< Image< TPixel, 3 > >, itk::ImageSource< Image< TPixel, VImageDimension > >, itk::ImageSource< ImageType >, itk::ImageSource< TClassifiedImage >, itk::ImageSource< TDisplacementField >, itk::ImageSource< TEigenValueImage >, itk::ImageSource< TImage >, itk::ImageSource< TImageType >, itk::ImageSource< TInputImage >, itk::ImageSource< TInputImage1 >, itk::ImageSource< TIntensityImage >, itk::ImageSource< TLabelImage >, itk::ImageSource< TLevelSet >, itk::ImageSource< TOutputImageType >, itk::ImageSource< TSparseOutputImage >, itk::ImageSource< TSparseOutputImageType >, itk::ImageSource< VectorImage< TProbabilityPrecisionType, TInputImage::ImageDimension > >, itk::DCMTKSeriesFileNames, itk::GDCMSeriesFileNames, itk::HistogramThresholdCalculator< THistogram, TOutput >, itk::ImageFileWriter< TInputImage >, itk::ImageRegistrationMethod< TFixedImage, TMovingImage >, itk::ImageRegistrationMethodv4< TFixedImage, TMovingImage, TOutputTransform, TVirtualImage, TPointSet >, itk::ImageSeriesWriter< TInputImage, TOutputImage >, itk::ImageSource< TOutputImage >, itk::ImageToSpatialObjectRegistrationMethod< TFixedImage, TMovingSpatialObject >, itk::ImageToVTKImageFilter< TInputImage >, itk::MeshFileWriter< TInputMesh >, itk::MeshSource< TOutputMesh >, itk::MultiResolutionImageRegistrationMethod< TFixedImage, TMovingImage >, itk::PathSource< TOutputPath >, itk::PointSetToImageRegistrationMethod< TFixedPointSet, TMovingImage >, itk::PointSetToPointSetRegistrationMethod< TFixedPointSet, TMovingPointSet >, itk::PointSetToSpatialObjectDemonsRegistration< TFixedPointSet, TMovingSpatialObject >, itk::Statistics::CovarianceSampleFilter< TSample >, itk::Statistics::HistogramToRunLengthFeaturesFilter< THistogram >, itk::Statistics::HistogramToTextureFeaturesFilter< THistogram >, itk::Statistics::ImageToListSampleFilter< TImage, TMaskImage >, itk::Statistics::MeanSampleFilter< TSample >, itk::Statistics::SampleClassifierFilter< TSample >, itk::Statistics::SampleToHistogramFilter< TSample, THistogram >, itk::Statistics::SampleToSubsampleFilter< TSample >, itk::Statistics::ScalarImageToCooccurrenceListSampleFilter< TImage >, itk::Statistics::ScalarImageToCooccurrenceMatrixFilter< TImageType, THistogramFrequencyContainer >, itk::Statistics::ScalarImageToRunLengthFeaturesFilter< TImageType, THistogramFrequencyContainer >, itk::Statistics::ScalarImageToRunLengthMatrixFilter< TImageType, THistogramFrequencyContainer >, itk::Statistics::ScalarImageToTextureFeaturesFilter< TImageType, THistogramFrequencyContainer >, itk::Statistics::StandardDeviationPerComponentSampleFilter< TSample >, itk::StreamingProcessObject, itk::TemporalProcessObject, itk::VTKImageExportBase, itk::watershed::BoundaryResolver< TPixelType, TDimension >, itk::watershed::EquivalenceRelabeler< TScalar, TImageDimension >, itk::watershed::Relabeler< TScalar, TImageDimension >, itk::watershed::Segmenter< TInputImage >, itk::watershed::SegmentTreeGenerator< TScalar >, itk::MeshSource< TDisplacements >, itk::MeshSource< TFeatures >, itk::MeshSource< TOutput >, itk::MeshSource< TOutputPointSet >, itk::MeshSource< VoronoiDiagram2D< TCoordType > >, itk::PathSource< OrthogonallyCorrected2DParametricPath >, itk::PathSource< PolyLineParametricPath< 2 > >, itk::PathSource< TOutputChainCodePath >, itk::PathSource< TOutputFourierSeriesPath >, itk::watershed::Relabeler< ScalarType, Self::ImageDimension >, itk::watershed::Segmenter< InputImageType >, itk::watershed::SegmentTreeGenerator< ScalarType >

See itk::ProcessObject for additional documentation.
template<typename TOutputImage>
class ImageSeriesReader : public itk::ImageSource<TOutputImage>

Data source that reads image data from a series of disk files.

This class builds an n-dimension image from multiple n-1 dimension image files. The files stored in a vector of strings are read using the ImageFileReader. File format may vary between the files, but the image data must have the same Size for all dimensions.

See

GDCMSeriesFileNames

See

NumericSeriesFileNames

See itk::ImageSeriesReader for additional documentation.