Make Out of Bounds Pixels Return Constant Value#

Synopsis#

Make out of bounds pixels return a constant value.

Results#

VTK Window

Output In VTK Window#

Output:

Index: [-1, -1] Pixel: 0 = 0
Index: [0, -1] Pixel: 1 = 0
Index: [1, -1] Pixel: 2 = 0
Index: [-1, 0] Pixel: 3 = 0
Index: [0, 0] Pixel: 4 = 255
Index: [1, 0] Pixel: 5 = 255
Index: [-1, 1] Pixel: 6 = 0
Index: [0, 1] Pixel: 7 = 255
Index: [1, 1] Pixel: 8 = 255
Index: [0, -1] Pixel: 0 = 0
Index: [1, -1] Pixel: 1 = 0
Index: [2, -1] Pixel: 2 = 0
Index: [0, 0] Pixel: 3 = 255
Index: [1, 0] Pixel: 4 = 255
Index: [2, 0] Pixel: 5 = 255
Index: [0, 1] Pixel: 6 = 255
Index: [1, 1] Pixel: 7 = 255
Index: [2, 1] Pixel: 8 = 255
Index: [1, -1] Pixel: 0 = 0
Index: [2, -1] Pixel: 1 = 0
Index: [3, -1] Pixel: 2 = 0
Index: [1, 0] Pixel: 3 = 255
Index: [2, 0] Pixel: 4 = 255
Index: [3, 0] Pixel: 5 = 255
Index: [1, 1] Pixel: 6 = 255
Index: [2, 1] Pixel: 7 = 255
Index: [3, 1] Pixel: 8 = 255
Index: [2, -1] Pixel: 0 = 0
Index: [3, -1] Pixel: 1 = 0
Index: [4, -1] Pixel: 2 = 0
Index: [2, 0] Pixel: 3 = 255
Index: [3, 0] Pixel: 4 = 255
Index: [4, 0] Pixel: 5 = 255
Index: [2, 1] Pixel: 6 = 255
Index: [3, 1] Pixel: 7 = 255
Index: [4, 1] Pixel: 8 = 255
Index: [3, -1] Pixel: 0 = 0
Index: [4, -1] Pixel: 1 = 0
Index: [5, -1] Pixel: 2 = 0
Index: [3, 0] Pixel: 3 = 255
Index: [4, 0] Pixel: 4 = 255
Index: [5, 0] Pixel: 5 = 0
Index: [3, 1] Pixel: 6 = 255
Index: [4, 1] Pixel: 7 = 255
Index: [5, 1] Pixel: 8 = 0

Code#

C++#

#include "itkImage.h"
#include "itkConstNeighborhoodIterator.h"
#include "itkConstantBoundaryCondition.h"
#include "itkImageRegionIterator.h"

#include <itkImageToVTKImageFilter.h>

#include "vtkVersion.h"
#include "vtkImageViewer.h"
#include "vtkImageMapper3D.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkImageActor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkRenderer.h"

using ImageType = itk::Image<unsigned char, 2>;
static void
CreateImage(ImageType::Pointer image);

int
main()
{
  auto image = ImageType::New();
  CreateImage(image);

  ImageType::SizeType regionSize;
  regionSize[0] = 50;
  regionSize[1] = 1;

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

  ImageType::RegionType region;
  region.SetSize(regionSize);
  region.SetIndex(regionIndex);

  ImageType::SizeType radius;
  radius[0] = 1;
  radius[1] = 1;

  using BoundaryConditionType = itk::ConstantBoundaryCondition<ImageType>;
  itk::ConstNeighborhoodIterator<ImageType, BoundaryConditionType> iterator(radius, image, region);

  while (!iterator.IsAtEnd())
  {
    for (unsigned int i = 0; i < 9; ++i)
    {
      ImageType::IndexType index = iterator.GetIndex(i);

      std::cout << "Index: " << index << " Pixel: " << i << " = " << (int)iterator.GetPixel(i) << std::endl;
    }
    ++iterator;
  }

  // Visualize
  using ConnectorType = itk::ImageToVTKImageFilter<ImageType>;
  auto connector = ConnectorType::New();
  connector->SetInput(image);

  vtkSmartPointer<vtkImageActor> actor = vtkSmartPointer<vtkImageActor>::New();
#if VTK_MAJOR_VERSION <= 5
  actor->SetInput(connector->GetOutput());
#else
  connector->Update();
  actor->GetMapper()->SetInputData(connector->GetOutput());
#endif

  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();

  vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  interactor->SetRenderWindow(renderWindow);

  vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
  renderWindow->AddRenderer(renderer);

  renderer->AddActor(actor);
  renderer->ResetCamera();

  renderWindow->Render();

  vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();

  interactor->SetInteractorStyle(style);

  interactor->Start();

  return EXIT_SUCCESS;
}

void
CreateImage(ImageType::Pointer image)
{
  // Create an image with 2 connected components
  ImageType::RegionType region;
  ImageType::IndexType  start;
  start[0] = 0;
  start[1] = 0;

  ImageType::SizeType size;
  unsigned int        NumRows = 5;
  unsigned int        NumCols = 5;
  size[0] = NumRows;
  size[1] = NumCols;

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

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

  itk::ImageRegionIterator<ImageType> imageIterator(image, region);

  // Set all pixels to white
  while (!imageIterator.IsAtEnd())
  {
    imageIterator.Set(255);
    ++imageIterator;
  }
}

Classes demonstrated#

template<typename TInputImage, typename TOutputImage = TInputImage>
class ConstantBoundaryCondition : public itk::ImageBoundaryCondition<TInputImage, TOutputImage>

This boundary condition returns a constant value for out-of-bounds image pixels.

For example, invoking this function object with a constant value of zero (the default) on each out-of-bounds element of a 7x5 iterator that masks a region at an image corner (iterator is centered on the 2):

          * * * * * * *
          * * * * * * *
          * * 1 2 3 4 5  (where * denotes pixels that lie
          * * 3 3 5 5 6          outside of the image boundary)
          * * 4 4 6 7 8

would produce the following neighborhood of values:

          0 0 0 0 0 0 0
          0 0 0 0 0 0 0
          0 0 1 2 3 4 5
          0 0 3 3 5 5 6
          0 0 4 4 6 7 8

Note

If you are using an image with Array as the pixel type, you will need to set the constant explicitly with an array of the appropriate length. This is also true if your image type is a VectorImage.

See

ImageBoundaryCondition

ITK Sphinx Examples:

See itk::ConstantBoundaryCondition for additional documentation.