Join Images#

Synopsis#

Join images, stacking their components

Results#

Output:

0
10

Code#

C++#

#include "itkImage.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkJoinImageFilter.h"
#include "itkVectorImageToImageAdaptor.h"

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

static void
CreateImage(ImageType::Pointer image, unsigned char value);

int
main()
{
  auto image1 = ImageType::New();
  CreateImage(image1, 0);

  auto image2 = ImageType::New();
  CreateImage(image2, 10);

  using JoinImageFilterType = itk::JoinImageFilter<ImageType, ImageType>;

  auto joinFilter = JoinImageFilterType::New();
  joinFilter->SetInput1(image1);
  joinFilter->SetInput2(image2);
  joinFilter->Update();

  itk::Index<2> index;
  index[0] = 0;
  index[1] = 0;

  std::cout << static_cast<int>(joinFilter->GetOutput()->GetPixel(index)[0]) << std::endl;
  std::cout << static_cast<int>(joinFilter->GetOutput()->GetPixel(index)[1]) << std::endl;

  return EXIT_SUCCESS;
}

void
CreateImage(ImageType::Pointer image, unsigned char value)
{
  // Create an image
  ImageType::IndexType start;
  start.Fill(0);

  ImageType::SizeType size;
  size.Fill(100);

  ImageType::RegionType region(start, size);

  image->SetRegions(region);
  image->Allocate();
  image->FillBuffer(value);
}

Classes demonstrated#

template<typename TInputImage1, typename TInputImage2>
class JoinImageFilter : public itk::BinaryGeneratorImageFilter<TInputImage1, TInputImage2, Functor::MakeJoin<TInputImage1, TInputImage2>::ImageType>

Join two images, resulting in an image where each pixel has the components of the first image followed by the components of the second image.

JoinImageFilter combines two images by appending the components of one image to the components of another image. The output image type is always a itk::Vector image and the vector value type will the smallest type that can represent the dynamic range of both the input value types. Hence, joining an image of char and unsigned char results in an image of shorts since that is the smallest datatype with a large enough dynamic range. To define a consistent behavior across different architectures, the join of an int and an unsigned int is float. On a 64 bit architecture, this join could be represented in a long. But on 32 bit architectures, the only safe join value type is a float. For this and similar ambiguous cases, the join value type is promoted to a float.

Note that this filter is not templated over its output image type. Rather the filter determines what its output image type is based on the input data types. To determine the output type, use JoinImageFilter<Image1, Image2>::OutputImageType

ITK Sphinx Examples:

See itk::JoinImageFilter for additional documentation.