How to get pixels within a radius from a specific pixel?

Hello,

I was wondering if there is a way to get the indices of pixels within a certain radius from a center pixel with a specific ID. itk::NeighborhoodIterator was the closest thing I found to this, but how can I use it to get the neighbor pixel indices when I only want to do this for specific center pixels in various different locations in the image? This iterator seems great if I want to apply a filter in the entire image, but can it be used to only iterate over pixels with specific indices?

Thank you very much.

1 Like

One option is to create a new NeighborhoodIterator for each center pixel you care about (region with the desired start index and size of [1,1,1]).

3 Likes

It seems to me that GenerateRectangularImageNeighborhoodOffsets(radius) might also be helpful to you. It expects an N-dimensional radius. Suppose your image is 2-D, then you could choose itk::Size<2>{r, r} as a 2-dimensional radius, having r > 0. (For example, r = 1 would yield a neighborhood of 3 x 3 pixels, including the center pixel).

For 2-D, GenerateRectangularImageNeighborhoodOffsets(radius) returns an std::vector of 2-dimensional offsets (itk::Offset<2>) relative to your center pixel, denoting the neighborhood with that particular radius.

Suppose you have your center pixel located at itk::Index<2> { i, j }. You could then add any of those offsets to that index, to get the index of the corresponding neighbor pixel.

// Untested, just for you to get the idea:
std::vector<itk::Index<2>> neighborIndices;
for(auto offset: offsets)
  neighborIndices.push_back(centerIndex + offset);

HTH, Niels

4 Likes

@dzenanz I tried this approach and it works, however it is not the most intuitive way to have an iterator that iterates over only one element.

@Niels_Dekker This is a great approach and seems more intuitive than using the iterator. Is there a reason why it is in the Experimental namespace?

Thank you both for your help. I was able to implement what I was aiming for.

2 Likes

GenerateRectangularImageNeighborhoodOffsets is part of a group of functions and classes that were introduced with ITK 5. At the initial release, they were still somewhat experimental, which is why we placed them in the Experimental namespace. But we have just moved them out of that namespace, in ITK’s git repository, June 23! With the next major release (ITK 5.2.0), they should be directly in itk namespace :smiley:

The group of functions and classes that were originally added to Experimental namespace offer C++11 “std style” iteration over the pixel values or the indices of an image. (Similar to how you would iterate over the elements of an std::vector.) Especially the ShapedImageNeighborhoodRange might be interesting for your use case! Example from the Detailed Description section of its documentation:

The following example creates a 3 x 5 neighborhood around pixel [10, 20] and adds 42 to each neighborhood pixel, using a range-based for loop:

const ImageType::IndexType location = {10, 20};
const itk::Size<ImageType::ImageDimension> radius = { { 1, 2 } };
const std::vector<OffsetType> offsets = itk::GenerateRectangularImageNeighborhoodOffsets(radius)
itk::ShapedImageNeighborhoodRange<ImageType> neighborhoodRange{ *image, location, offsets };
 
for (auto&& neighborhoodPixel : neighborhoodRange)
{
  neighborhoodPixel = neighborhoodPixel + 42;
}

Hmmm, I see now that the example is already without the Experimental namespace! Anyway, I hope you got the point! :smiley:

Kind regards, Niels

2 Likes

@Niels_Dekker Sorry the delayed reply! This last example you posted using the ShapedImageNeighborhoodRange in combination with GenerateRectangularImageNeighborhoodOffsets is perfect if you want to deal with the pixel values. Is there some way to iterate over the indices of the pixels in the range instead of their values using a ShapedImageNeighborhoodRange? Maybe a second iterator that returns the neighbor indices would be helpful.

Thank you a lot.