Change Image Origin Spacing Or Direction

Synopsis

Change an Image’s Origin, Spacing, or Direction.

The ChangeInformationImageFilter is commonly used to modify image metadata such as Origin, Spacing, and Orientation. This filter leaves intact the pixel data of the image. This filter should be used with extreme caution, since it can easily change information that is critical for the safety of many medical image analysis tasks, such as measurement the volume of a tumor, or providing guidance for surgery.

Results

Original image: Image (0x3131ce0)
  RTTI typeinfo:   itk::Image<unsigned char, 3u>
  Reference Count: 3
  Modified Time: 195
  Debug: Off
  Object Name:
  Observers:
    none
  Source: (0x312d620)
  Source output name: Primary
  Release Data: Off
  Data Released: False
  Global Release Data: Off
  PipelineMTime: 47
  UpdateMTime: 0
  RealTimeStamp: 0 seconds
  LargestPossibleRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [48, 62, 42]
  BufferedRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [0, 0, 0]
  RequestedRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [0, 0, 0]
  Spacing: [4, 4, 4]
  Origin: [0, 0, 0]
  Direction:
1 0 0
0 1 0
0 0 1

  IndexToPointMatrix:
4 0 0
0 4 0
0 0 4

  PointToIndexMatrix:
0.25 0 0
0 0.25 0
0 0 0.25

  Inverse Direction:
1 0 0
0 1 0
0 0 1

  PixelContainer:
    ImportImageContainer (0x3131fa0)
      RTTI typeinfo:   itk::ImportImageContainer<unsigned long, unsigned char>
      Reference Count: 1
      Modified Time: 34
      Debug: Off
      Object Name:
      Observers:
        none
      Pointer: 0
      Container manages memory: true
      Size: 0
      Capacity: 0

**************************************
Changed image: Image (0x3137100)
  RTTI typeinfo:   itk::Image<unsigned char, 3u>
  Reference Count: 3
  Modified Time: 222
  Debug: Off
  Object Name:
  Observers:
    none
  Source: (0x3132240)
  Source output name: Primary
  Release Data: Off
  Data Released: False
  Global Release Data: Off
  PipelineMTime: 215
  UpdateMTime: 0
  RealTimeStamp: 0 seconds
  LargestPossibleRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [48, 62, 42]
  BufferedRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [0, 0, 0]
  RequestedRegion:
    Dimension: 3
    Index: [0, 0, 0]
    Size: [0, 0, 0]
  Spacing: [8.4, 8.4, 8.4]
  Origin: [8.4, 2.9, 4.4]
  Direction:
0.866025 -0.5 0
0.5 0.866025 0
0 0 1

  IndexToPointMatrix:
7.27461 -4.2 0
4.2 7.27461 0
0 0 8.4

  PointToIndexMatrix:
0.103098 0.0595238 0
-0.0595238 0.103098 0
0 0 0.119048

  Inverse Direction:
0.866025 0.5 0
-0.5 0.866025 0
0 0 1

  PixelContainer:
    ImportImageContainer (0x3137520)
      RTTI typeinfo:   itk::ImportImageContainer<unsigned long, unsigned char>
      Reference Count: 1
      Modified Time: 200
      Debug: Off
      Object Name:
      Observers:
        none
      Pointer: 0
      Container manages memory: true
      Size: 0
      Capacity: 0

Code

C++

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkVersor.h"
#include "itkChangeInformationImageFilter.h"

int
main(int argc, char * argv[])
{
  if (argc < 2)
  {
    std::cerr << "Usage: " << argv[0] << " <inputFileName>"
              << " [scalingFactor]"
              << " [translationX translationY translationZ]"
              << " [rotationZinDegrees]" << std::endl;
    return EXIT_FAILURE;
  }

  const char * inputFileName = argv[1];
  double       scalingFactor = 1.0;
  if (argc > 3)
  {
    scalingFactor = std::stod(argv[3]);
  }
  double translationX = 0.0;
  if (argc > 3)
  {
    translationX = std::stod(argv[3]);
  }
  double translationY = 0.0;
  if (argc > 4)
  {
    translationY = std::stod(argv[4]);
  }
  double translationZ = 0.0;
  if (argc > 5)
  {
    translationZ = std::stod(argv[5]);
  }
  double rotationZ = 0.0;
  if (argc > 6)
  {
    rotationZ = std::stod(argv[6]);
  }

  constexpr unsigned int Dimension = 3;

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

  using ReaderType = itk::ImageFileReader<ImageType>;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(inputFileName);
  try
  {
    reader->UpdateOutputInformation();
  }
  catch (itk::ExceptionObject & error)
  {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
  }
  ImageType::ConstPointer inputImage = reader->GetOutput();
  std::cout << "Original image: " << inputImage << std::endl;

  using FilterType = itk::ChangeInformationImageFilter<ImageType>;
  FilterType::Pointer filter = FilterType::New();
  filter->SetInput(reader->GetOutput());

  const ImageType::SpacingType spacing(scalingFactor);
  filter->SetOutputSpacing(spacing);
  filter->ChangeSpacingOn();

  ImageType::PointType::VectorType translation;
  translation[0] = translationX;
  translation[1] = translationY;
  translation[2] = translationZ;
  ImageType::PointType origin = inputImage->GetOrigin();
  origin += translation;
  filter->SetOutputOrigin(origin);
  filter->ChangeOriginOn();

  itk::Versor<double> rotation;
  const double        angleInRadians = rotationZ * itk::Math::pi / 180.0;
  rotation.SetRotationAroundZ(angleInRadians);
  const ImageType::DirectionType direction = inputImage->GetDirection();
  const ImageType::DirectionType newDirection = direction * rotation.GetMatrix();
  filter->SetOutputDirection(newDirection);
  filter->ChangeDirectionOn();

  try
  {
    filter->UpdateOutputInformation();
  }
  catch (itk::ExceptionObject & error)
  {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
  }
  std::cout << "**************************************" << std::endl;
  ImageType::ConstPointer output = filter->GetOutput();
  std::cout << "Changed image: " << output << std::endl;

  return EXIT_SUCCESS;
}

Classes demonstrated

template<typename TInputImage>
class ChangeInformationImageFilter : public itk::ImageToImageFilter<TInputImage, TInputImage>

Change the origin, spacing and/or region of an Image.

Change the origin, spacing, direction and/or buffered region of an itkImage. This “Information” along with an Image’s container comprise the itkImage. By default, the output’s information is set to the input’s information. The methods ChangeSpacingOn/Off, ChangeOriginOn/Off, ChangeDirectionOn/Off and ChangeRegionOn/Off control whether the default origin, spacing, direction or buffered region should be changed. If On, the associated information will be replaced with either the ReferenceImage information (if UseReferenceImage is true) or the ivars OutputSpacing, OutputOrigin, OutputDirection, OutputOffset.

In addition, the method CenterImageOn will recompute the output image origin (using the selected output spacing) the align the center of the image with the coordinate 0.

See itk::ChangeInformationImageFilter for additional documentation.