itk::NeighborhoodRange: a new class for efficient modern C++ style iteration

NeighborhoodOffsets.h sounds good to me!.

The name GenerateOffsetsForRectangularNeighborhood, might be misleading, because the offsets could be Cubic if Size is 3D. Or lines if Size<1>.
I would recommend the more formal GenerateHyperRectangleOffsets, or GenerateNRectangleOffsets?

GenerateNCrossOffsets(radius), for one pixel wide Greek cross (+), with the lengths of the cross taken from radius?

I would put there:

Generate3D26TopologyOffsets,
 equivalent to GenerateOffsetsForRectangularNeighborhood<Size<3>>({1,1,1}) 
with the index {0} removed.

Generate3D18TopologyOffsets
removing {0} and all indices with
 std::inner_product(indice.begin(), indice.end(), indice.begin(), 0) == 3, 
or putting other way, all indices in the corners of the cube removed.

Generate3D6TopologyOffsets,
 equivalent to GenerateNCrossOffsets<Size<3>>)({1,1,1}) with index {0} removed. 

Generate2D8Topology
 GenerateOffsetsForRectangularNeighborhood<Size<2>>({1,1}) with the index {0} removed.

Generate2D4Topology
equivalent to GenerateNCrossOffsets<Size<2>>)({1,1}) with index {0} removed. 

Or maybe easier to just hard-code the relative indices, but I am concerned about the order of the indices:

For example, in the case of the Gaussian that you use.

    for (const TOutput kernelValue : operatorNeighborhood.GetBufferReference())
    {
      result += kernelValue * (*neighborhoodRangeIterator);
      ++neighborhoodRangeIterator;
    }

There, the indices of neighborhoodRangeIterator has the same order than the Buffer of the operatorNeighborhood, because you coded GenerateOffsetsForRectangularNeighborhood generating the offsets in the same order than the buffer. What about when a user puts indices at random order? Shouldn’t we provide a helper function to order them in the same way than Buffer is ordered if that is the standard?

Good stuff!

1 Like