Hereby I would like to share my ideas behind the proposed patch ENH: Added class to create offsets for a hyperrectangular neighborhood shape
Both the new ShapedImageNeighborhoodRange (from namespace itk::Experimental
) and the original itk::ShapedNeighborhoodIterator allow specifying the shape of a neighborhood by means of offsets (objects of type itk::Offset<N>
). Unfortunately, it can be somewhat cumbersome for users to specify the values of such offsets, depending on the preferred shape. I think it would be nice if ITK could have some classes for commonly used neighborhood shapes. Each class would allow generating the offsets for that particular shape. If possible, they might all have a similar interface, like this:
template <unsigned int VImageDimension>
class ExampleImageNeighborhoodShape
{
public:
static constexpr unsigned int ImageDimension = VImageDimension;
constexpr explicit ExampleImageNeighborhoodShape(...) noexcept;
constexpr std::size_t GetNumberOfOffsets() const noexcept;
void FillOffsets(itk::Offset<ImageDimension>*) const noexcept;
};
Not surprisingly, that’s also basically the interface of the HyperrectangularImageNeighborhoodShape<ImageDimension>
class, which is part of the proposed patch. This class specifically supports generating the offsets for box-shaped neighborhoods. It can be constructed as follows, for example:
constexpr itk::Size<ImageDimension> radius = {{ 1, 2 }}; // For example.
constexpr HyperrectangularImageNeighborhoodShape<ImageDimension> shape{radius};
The offsets can then be generated as follows:
std::array<OffsetType, shape.GetNumberOfOffsets()> offsets;
shape.FillOffsets(offsets.data());
Or by using the proposed convenience function GenerateImageNeighborhoodOffsets
(also added to namespace itk::Experimental
):
std::vector<OffsetType> offsets = GenerateImageNeighborhoodOffsets(shape);
The offsets can then be used to specify the shape for the original itk::ShapedNeighborhoodIterator
:
ShapedNeighborhoodIterator<ImageType> neighborhoodIterator{radius, image, region};
for (const auto offset: offsets)
{
neighborhoodIterator.ActivateOffset(offset);
}
As well as to specify the shape for the new itk::Experimental::ShapedImageNeighborhoodRange
:
ShapedImageNeighborhoodRange<ImageType> neighborhoodRange{*image, location, offsets};
Please have a look: http://review.source.kitware.com/#/c/23389
P.S. The patch does not yet present any other shapes, but @phcerdan already suggested another one, that we are still discussing at itk::NeighborhoodRange: a new class for efficient modern C++ style iteration