Filter Image Without Copying Its Data#

Synopsis#

Filter an image without copying its data.

Results#

Output:

3

Code#

C++#

#include "itkImage.h"

#include "MyInPlaceImageFilter.h"

template <typename TImage>
static void
CreateImage(TImage * const image);

int
main()
{
  // Setup types
  using ImageType = itk::Image<int, 2>;
  using FilterType = itk::MyInPlaceImageFilter<ImageType>;

  auto image = ImageType::New();
  CreateImage(image.GetPointer());

  // Create and the filter
  auto filter = FilterType::New();
  filter->SetInput(image);
  filter->SetInPlace(true);
  filter->Update();

  itk::Index<2> cornerPixel = image->GetLargestPossibleRegion().GetIndex();

  // The output here should be "3"
  std::cout << "Filter output:" << std::endl;
  std::cout << filter->GetOutput()->GetPixel(cornerPixel) << std::endl;

  // The follow calls fail. This is because the output has stolen the input's
  // buffer and the input has no image buffer.
  //   std::cout << "Image output:" << std::endl;
  //   std::cout << image->GetPixel(cornerPixel) << std::endl;

  return EXIT_SUCCESS;
}


template <typename TImage>
void
CreateImage(TImage * const image)
{
  // Create an image with 2 connected components
  typename TImage::IndexType corner = { { 0, 0 } };

  unsigned int              NumRows = 200;
  unsigned int              NumCols = 300;
  typename TImage::SizeType size = { { NumRows, NumCols } };

  typename TImage::RegionType region(corner, size);

  image->SetRegions(region);
  image->Allocate();

  image->FillBuffer(0);
}

Classes demonstrated#

template<typename TInputImage, typename TOutputImage = TInputImage>
class InPlaceImageFilter : public itk::ImageToImageFilter<TInputImage, TOutputImage>

Base class for filters that take an image as input and overwrite that image as the output.

InPlaceImageFilter is the base class for all process objects whose output image data is constructed by overwriting the input image data. In other words, the output bulk data is the same block of memory as the input bulk data. This filter provides the mechanisms for in place image processing while maintaining general pipeline mechanics. InPlaceImageFilters use less memory than standard ImageToImageFilters because the input buffer is reused as the output buffer. However, this benefit does not come without a cost. Since the filter overwrites its input, the ownership of the bulk data is transitioned from the input data object to the output data object. When a data object has multiple consumers with one of the consumers being an in place filter, the in place filter effectively destroys the bulk data for the data object. Upstream filters will then have to re-execute to regenerate the data object’s bulk data for the remaining consumers.

Since an InPlaceImageFilter reuses the input bulk data memory for the output bulk data memory, the input image type must match the output image type. If the input and output image types are not identical, the filter reverts to a traditional ImageToImageFilter behaviour where an output image is allocated. Additionally, the requested region of the output must match that of the input. In place operation can also be controlled (when the input and output image type match) via the methods InPlaceOn() and InPlaceOff().

Subclasses of InPlaceImageFilter must take extra care in how they manage memory using (and perhaps overriding) the implementations of ReleaseInputs() and AllocateOutputs() provided here.

ITK Sphinx Examples:

Subclassed by itk::BinaryGeneratorImageFilter< TInputImage, TLabelImage, TOutputImage >, itk::BinaryGeneratorImageFilter< TInputImage, TMaskImage, TOutputImage >, itk::BinaryContourImageFilter< TInputImage, TOutputImage >, itk::CastImageFilter< TInputImage, TOutputImage >, itk::ExtractImageFilter< TInputImage, TOutputImage >, itk::FiniteDifferenceImageFilter< TInputImage, TOutputImage >, itk::GradientMagnitudeRecursiveGaussianImageFilter< TInputImage, TOutputImage >, itk::LabelContourImageFilter< TInputImage, TOutputImage >, itk::NaryFunctorImageFilter< TInputImage, TOutputImage, TFunction >, itk::NoiseBaseImageFilter< TInputImage, TOutputImage >, itk::PasteImageFilter< TInputImage, TSourceImage, TOutputImage >, itk::RecursiveSeparableImageFilter< TInputImage, TOutputImage >, itk::RelabelComponentImageFilter< TInputImage, TOutputImage >, itk::SmoothingRecursiveGaussianImageFilter< TInputImage, TOutputImage >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, TFunction >, itk::UnaryGeneratorImageFilter< TInputImage, TOutputImage >, itk::NaryFunctorImageFilter< TInputImage, TOutputImage, Functor::Add1< TInputImage::PixelType, TInputImage::PixelType > >, itk::NaryFunctorImageFilter< TInputImage, TOutputImage, Functor::Maximum1< TInputImage::PixelType, TInputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::AccessorFunctor< TInputImage::PixelType, TAccessor > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::BinaryThreshold< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::ChangeLabel< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::Clamp< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::ExpNegative< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::IntensityLinearTransform< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::IntensityWindowingTransform< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::InvertIntensityTransform< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::MatrixIndexSelection< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::NOT< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::Sigmoid< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::SymmetricEigenAnalysisFixedDimensionFunction< TMatrixDimension, TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::SymmetricEigenAnalysisFunction< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::TensorFractionalAnisotropyFunction< TInputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::TensorRelativeAnisotropyFunction< TInputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::ThresholdLabeler< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::VectorIndexSelectionCast< TInputImage::PixelType, TOutputImage::PixelType > >, itk::UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::VectorMagnitudeLinearTransform< TInputImage::PixelType, TOutputImage::PixelType > >

See itk::InPlaceImageFilter for additional documentation.