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>;

    TransformType::Pointer 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(int, char *[])
{
  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);

  ImageType::Pointer 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>>;

  FilterType::Pointer 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.