Iterate Over a Region With a Shaped Neighborhood Iterator Manually¶
Synopsis¶
Iterate over a region of an image with a shaped neighborhood manually.
Results¶
Output:
By default there are 0 active indices.
Now there are 2 active indices.
1 7
New position:
Centered at [0, 0]
Neighborhood index 1 is offset [0, -1] and has value 0 The real index is [0, -1]
Centered at [0, 0]
Neighborhood index 7 is offset [0, 1] and has value 0 The real index is [0, 1]
New position:
Centered at [1, 0]
Neighborhood index 1 is offset [0, -1] and has value 0 The real index is [1, -1]
Centered at [1, 0]
Neighborhood index 7 is offset [0, 1] and has value 0 The real index is [1, 1]
New position:
Centered at [2, 0]
Neighborhood index 1 is offset [0, -1] and has value 0 The real index is [2, -1]
Centered at [2, 0]
Neighborhood index 7 is offset [0, 1] and has value 0 The real index is [2, 1]
[...]
New position:
Centered at [7, 9]
Neighborhood index 1 is offset [0, -1] and has value 0 The real index is [7, 8]
Centered at [7, 9]
Neighborhood index 7 is offset [0, 1] and has value 0 The real index is [7, 10]
New position:
Centered at [8, 9]
Neighborhood index 1 is offset [0, -1] and has value 0 The real index is [8, 8]
Centered at [8, 9]
Neighborhood index 7 is offset [0, 1] and has value 0 The real index is [8, 10]
New position:
Centered at [9, 9]
Neighborhood index 1 is offset [0, -1] and has value 0 The real index is [9, 8]
Centered at [9, 9]
Neighborhood index 7 is offset [0, 1] and has value 0 The real index is [9, 10]
Code¶
C++¶
#include "itkImage.h"
#include "itkShapedNeighborhoodIterator.h"
#include "itkImageRegionIterator.h"
#include "itkNeighborhoodAlgorithm.h"
// Notice that char type pixel values will not appear
// properly on the command prompt therefore for the
// demonstration purposes it is best to use the int
// type, however in real applications iterators have
// no problems with char type images.
// using ImageType = itk::Image<unsigned char, 2>;
using ImageType = itk::Image<unsigned int, 2>;
void
CreateImage(ImageType::Pointer image);
int
main(int, char *[])
{
  ImageType::Pointer image = ImageType::New();
  CreateImage(image);
  using IteratorType = itk::ShapedNeighborhoodIterator<ImageType>;
  itk::Size<2> radius;
  radius.Fill(1);
  IteratorType iterator(radius, image, image->GetLargestPossibleRegion());
  std::cout << "By default there are " << iterator.GetActiveIndexListSize() << " active indices." << std::endl;
  IteratorType::OffsetType top = { { 0, -1 } };
  iterator.ActivateOffset(top);
  IteratorType::OffsetType bottom = { { 0, 1 } };
  iterator.ActivateOffset(bottom);
  std::cout << "Now there are " << iterator.GetActiveIndexListSize() << " active indices." << std::endl;
  IteratorType::IndexListType                 indexList = iterator.GetActiveIndexList();
  IteratorType::IndexListType::const_iterator listIterator = indexList.begin();
  while (listIterator != indexList.end())
  {
    std::cout << *listIterator << " ";
    ++listIterator;
  }
  std::cout << std::endl;
  // Note that ZeroFluxNeumannBoundaryCondition is used by default so even
  // pixels outside of the image will have valid values (equivalent to their neighbors just inside the image)
  for (iterator.GoToBegin(); !iterator.IsAtEnd(); ++iterator)
  {
    std::cout << "New position: " << std::endl;
    IteratorType::ConstIterator ci = iterator.Begin();
    while (!ci.IsAtEnd())
    {
      std::cout << "Centered at " << iterator.GetIndex() << std::endl;
      std::cout << "Neighborhood index " << ci.GetNeighborhoodIndex() << " is offset " << ci.GetNeighborhoodOffset()
                << " and has value " << ci.Get() << " The real index is "
                << iterator.GetIndex() + ci.GetNeighborhoodOffset() << std::endl;
      ci++;
    }
  }
  std::cout << std::endl;
  return EXIT_SUCCESS;
}
void
CreateImage(ImageType::Pointer image)
{
  ImageType::IndexType start;
  start.Fill(0);
  ImageType::SizeType size;
  size.Fill(10);
  ImageType::RegionType region(start, size);
  image->SetRegions(region);
  image->Allocate();
  image->FillBuffer(0);
}
Classes demonstrated¶
- 
template<typename 
TImage, typenameTBoundaryCondition= ZeroFluxNeumannBoundaryCondition<TImage>>
classShapedNeighborhoodIterator: public itk::ConstShapedNeighborhoodIterator<TImage, TBoundaryCondition> A neighborhood iterator which can take on an arbitrary shape.
using ImageType = Image<float, 3>; ShapedNeighborhoodIterator<ImageType> it(radius, image, region); ShapedNeighborhoodIterator<ImageType>::OffsetType offset = {{0,0,0}}; it.ActivateOffset(offset);
- General Information
 The ShapedNeighborhoodIterator is a refinement of NeighborhoodIterator which allows the user to specify which of the neighborhood elements are active and which will be ignored. This is useful for applications which only need to work with a subset of the neighborhood around a pixel such as morphological operations or cellular automata. This iterator can also be used, for example, to specify “cross-shaped” neighborhood where only elements along a spatial axes are significant.
- Constructing a shaped neighborhood iterator
 A shaped neighborhood iterator is constructed by constructing a list of active neighbor locations. The list is called the ActiveIndexList. The methods ActivateOffset, DeactivateOffset, and ClearActiveList are used to construct the ActiveIndexList. The argument to Activate/DeactivateOffset is an itk::Offset which represents the ND spatial offset from the center of the neighborhood. For example, to activate the center pixel in the neighborhood, you would do the following:
where radius, image, and region are as described in NeighborhoodIterator.
Once a neighborhood location has been activated, iteration (operator++, operator–, operator+=, operator-=) will update the value at the active location. Note that values at inactive locations will NOT be valid if queried.
A second way to access active shaped neighborhood values is through a
ShapedNeighborhoodIterator::Iterator or ConstShapedNeighborhoodIterator::ConstIterator. The following example demonstrates the use of these iterators.- Accessing elements in a shaped neighborhood.
 To access the value at an active neighborhood location, you can use the standard GetPixel, SetPixel methods. SetPixel is not defined for ConstShapedNeighborhoodIterator. The class will not complain if you attempt to access a value at a non-active location, but be aware that the result will be undefined. Error checking is not done in this case for the sake of efficiency.
using ImageType = Image<float, 3>; ShapedNeighborhoodIterator<ImageType> it(radius, image, region); ... it.ActivateOffset(offset1); it.ActivateOffset(offset2); it.ActivateOffset(offset3); // etc.. ... ShapedNeighborhoodIterator<ImageType>::Iterator i; for (i = it.Begin(); ! i.IsAtEnd(); ++i) { i.Set(i.Get() + 1.0); } // you may also use i != i.End(), but IsAtEnd() may be slightly faster.
You can also iterate backward through the neighborhood active list.
i = it.End(); i--; while (i != it.Begin()) { i.Set(i.Get() + 1.0); i--; } i.Set(i.Get() + 1.0);
The Get() Set() syntax was chosen versus defining operator* for these iterators because lvalue vs. rvalue context information is needed to determine whether bounds checking must take place.
- See
 Neighborhood
- MORE INFORMATION
 For a complete description of the ITK Image Iterators and their API, please see the Iterators chapter in the ITK Software Guide. The ITK Software Guide is available in print and as a free .pdf download from https://www.itk.org.
- See
 ImageConstIterator
- See
 ConditionalConstIterator
- See
 ConstNeighborhoodIterator
- See
 ConstShapedNeighborhoodIterator
- See
 ConstSliceIterator
- See
 CorrespondenceDataStructureIterator
- See
 FloodFilledFunctionConditionalConstIterator
- See
 FloodFilledImageFunctionConditionalConstIterator
- See
 FloodFilledImageFunctionConditionalIterator
- See
 FloodFilledSpatialFunctionConditionalConstIterator
- See
 FloodFilledSpatialFunctionConditionalIterator
- See
 ImageConstIterator
- See
 ImageConstIteratorWithIndex
- See
 ImageIterator
- See
 ImageIteratorWithIndex
- See
 ImageLinearConstIteratorWithIndex
- See
 ImageLinearIteratorWithIndex
- See
 ImageRandomConstIteratorWithIndex
- See
 ImageRandomIteratorWithIndex
- See
 ImageRegionConstIterator
- See
 ImageRegionConstIteratorWithIndex
- See
 ImageRegionExclusionConstIteratorWithIndex
- See
 ImageRegionExclusionIteratorWithIndex
- See
 ImageRegionIterator
- See
 ImageRegionIteratorWithIndex
- See
 ImageRegionReverseConstIterator
- See
 ImageRegionReverseIterator
- See
 ImageReverseConstIterator
- See
 ImageReverseIterator
- See
 ImageSliceConstIteratorWithIndex
- See
 ImageSliceIteratorWithIndex
- See
 NeighborhoodIterator
- See
 PathConstIterator
- See
 PathIterator
- See
 ShapedNeighborhoodIterator
- See
 SliceIterator
- See
 ImageConstIteratorWithIndex
- See
 ShapedImageNeighborhoodRange
- ITK Sphinx Examples:
 

