Apply Custom Operation to Each Pixel in Image#

Synopsis#

Apply a custom operation to each pixel in an image.

Results#

Output:

pixel (1,1) was = [1,0]
pixel (1,1) now = [-4.37144e-08, 1]

Code#

C++#

#include "itkVectorImage.h"
#include "itkVector.h"
#include "itkVariableLengthVector.h"
#include "itkRigid2DTransform.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkMath.h"

template <class TInput, class TOutput>
class RotateVectors
{
public:
  RotateVectors() = default;
  ~RotateVectors() = default;
  bool
  operator!=(const RotateVectors &) const
  {
    return false;
  }
  bool
  operator==(const RotateVectors & other) const
  {
    return !(*this != other);
  }
  inline TOutput
  operator()(const TInput & A) const
  {
    using VectorType = itk::Vector<float, 2>;
    VectorType v;
    v[0] = A[0];
    v[1] = A[1];

    using TransformType = itk::Rigid2DTransform<float>;

    auto transform = TransformType::New();
    transform->SetAngle(itk::Math::pi / 2.0);

    VectorType outputV = transform->TransformVector(v);
    TOutput    transformedVector;
    transformedVector.SetSize(2);
    transformedVector[0] = outputV[0];
    transformedVector[1] = outputV[1];

    return transformedVector;
  }
};

int
main()
{
  using ImageType = itk::VectorImage<float, 2>;

  ImageType::RegionType region;
  ImageType::IndexType  start;
  start[0] = 0;
  start[1] = 0;

  ImageType::SizeType size;
  size[0] = 2;
  size[1] = 3;

  region.SetSize(size);
  region.SetIndex(start);

  auto image = ImageType::New();
  image->SetRegions(region);
  image->SetVectorLength(2);
  image->Allocate();

  ImageType::IndexType pixelIndex;
  pixelIndex[0] = 1;
  pixelIndex[1] = 1;

  using VectorType = itk::VariableLengthVector<float>;
  VectorType v;
  v.SetSize(2);
  v[0] = 1;
  v[1] = 0;

  image->SetPixel(pixelIndex, v);

  using FilterType =
    itk::UnaryFunctorImageFilter<ImageType, ImageType, RotateVectors<ImageType::PixelType, ImageType::PixelType>>;

  auto filter = FilterType::New();
  filter->SetInput(image);
  filter->Update();

  ImageType::PixelType inputPixelValue = image->GetPixel(pixelIndex);
  ImageType::PixelType outputPixelValue = filter->GetOutput()->GetPixel(pixelIndex);

  std::cout << "pixel (1,1) was = " << inputPixelValue << std::endl;
  std::cout << "pixel (1,1) now = " << outputPixelValue << std::endl;

  return EXIT_SUCCESS;
}

Classes demonstrated#

template<typename TInputImage, typename TOutputImage, typename TFunction>
class UnaryFunctorImageFilter : public itk::InPlaceImageFilter<TInputImage, TOutputImage>

Implements pixel-wise generic operation on one image.

This class is parameterized over the type of the input image and the type of the output image. It is also parameterized by the operation to be applied, using a Functor style.

UnaryFunctorImageFilter allows the output dimension of the filter to be larger than the input dimension. Thus subclasses of the UnaryFunctorImageFilter (like the CastImageFilter) can be used to promote a 2D image to a 3D image, etc.

See

UnaryGeneratorImageFilter

See

BinaryFunctorImageFilter TernaryFunctorImageFilter

ITK Sphinx Examples:

See itk::UnaryFunctorImageFilter for additional documentation.