Skip to content

Commit

Permalink
ENH: Add ImageBufferAndIndexRange example
Browse files Browse the repository at this point in the history
Using `ImageBufferRange` and `IndexRange`, which were introduced with ITK 5.0.
  • Loading branch information
N-Dekker committed May 21, 2022
1 parent 6f0e16b commit 0ba2890
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/Core/Common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ add_example(AddOffsetToIndex)
add_example(GetNameOfClass)
add_example(CreateAnImageRegion)
add_example(IsPixelInsideRegion)
add_example(ImageBufferAndIndexRange)
add_example(ImageRegionIntersection)

add_example(ImageRegionOverlap)
Expand Down
23 changes: 23 additions & 0 deletions src/Core/Common/ImageBufferAndIndexRange/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.16.3)

project(ImageBufferAndIndexRange)

find_package(ITK REQUIRED)
include(${ITK_USE_FILE})

add_executable(${PROJECT_NAME} Code.cxx)
target_link_libraries(${PROJECT_NAME} ${ITK_LIBRARIES})

install(TARGETS ${PROJECT_NAME}
DESTINATION bin/ITKSphinxExamples/Core/Common
COMPONENT Runtime
)

install(FILES Code.cxx CMakeLists.txt
DESTINATION share/ITKSphinxExamples/Code/Core/Common/${PROJECT_NAME}
COMPONENT Code
)

enable_testing()
add_test(NAME ${PROJECT_NAME}Test
COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME})
87 changes: 87 additions & 0 deletions src/Core/Common/ImageBufferAndIndexRange/Code.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*=========================================================================
*
* Copyright NumFOCUS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/

#include "itkImage.h"
#include "itkImageBufferRange.h"
#include "itkIndexRange.h"
#include "itkNumericTraits.h"

#include <cassert>
#include <numeric> // For iota

namespace
{
// Creates an image with sequentially increasing pixel values (0, 1, 2, ...).
template <typename TImage>
typename TImage::Pointer
CreateImageWithSequentiallyIncreasingPixelValues(const typename TImage::RegionType & region)
{
using PixelType = typename TImage::PixelType;

const auto image = TImage::New();
image->SetRegions(region);
image->Allocate();

const itk::ImageBufferRange<TImage> imageBufferRange(*image);
std::iota(imageBufferRange.begin(), imageBufferRange.end(), PixelType{ 0 });

return image;
}


// Prints all pixel values with their N-dimensional indices.
template <typename TImage>
void
PrintPixelValues(const TImage & image)
{
constexpr unsigned int Dimension{ TImage::ImageDimension };
const itk::ImageRegion<Dimension> region = image.GetBufferedRegion();
const itk::ImageRegionIndexRange<Dimension> indexRange(region);
const itk::ImageBufferRange<const TImage> imageBufferRange(image);

using PixelType = typename TImage::PixelType;
using PrintType = typename itk::NumericTraits<PixelType>::PrintType;

std::cout << "Region index: " << region.GetIndex() << "; Region size: " << region.GetSize() << "\n\n";

auto indexIterator = indexRange.cbegin();

for (const PixelType pixel : imageBufferRange)
{
const itk::Index<Dimension> index = *indexIterator;
std::cout << "Pixel index: " << index << "; Pixel value: " << PrintType{ pixel } << '\n';
++indexIterator;
}

assert(indexIterator == indexRange.cend());
}

} // namespace


int
main()
{
using PixelType = unsigned char;
using ImageType = itk::Image<PixelType>;
using RegionType = ImageType::RegionType;

const RegionType region(itk::MakeIndex(100, 200), itk::MakeSize(4, 5));
const ImageType::ConstPointer image = CreateImageWithSequentiallyIncreasingPixelValues<ImageType>(region);
PrintPixelValues(*image);
}
59 changes: 59 additions & 0 deletions src/Core/Common/ImageBufferAndIndexRange/Documentation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
:name: ImageBufferAndIndexRange

Image Buffer and Index Range
============================

.. index::
single: ImageBufferRange

Synopsis
--------


This example demonstrates how to iterate over all pixels of the buffered region
of an image, using either an iterator-based algorithm from the C++ Standard
Library, or a range-based for loop.


Results
-------

Output::

Region index: [100, 200]; Region size: [4, 5]

Pixel index: [100, 200]; Pixel value: 0
Pixel index: [101, 200]; Pixel value: 1
Pixel index: [102, 200]; Pixel value: 2
Pixel index: [103, 200]; Pixel value: 3
Pixel index: [100, 201]; Pixel value: 4
Pixel index: [101, 201]; Pixel value: 5
Pixel index: [102, 201]; Pixel value: 6
Pixel index: [103, 201]; Pixel value: 7
Pixel index: [100, 202]; Pixel value: 8
Pixel index: [101, 202]; Pixel value: 9
Pixel index: [102, 202]; Pixel value: 10
Pixel index: [103, 202]; Pixel value: 11
Pixel index: [100, 203]; Pixel value: 12
Pixel index: [101, 203]; Pixel value: 13
Pixel index: [102, 203]; Pixel value: 14
Pixel index: [103, 203]; Pixel value: 15
Pixel index: [100, 204]; Pixel value: 16
Pixel index: [101, 204]; Pixel value: 17
Pixel index: [102, 204]; Pixel value: 18
Pixel index: [103, 204]; Pixel value: 19

Code
----

C++
...

.. literalinclude:: Code.cxx
:lines: 18-


Classes demonstrated
--------------------

.. breathelink:: itk::ImageBufferRange itk::IndexRange
1 change: 1 addition & 0 deletions src/Core/Common/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Common
GetNameOfClass/Documentation.rst
GetOrSetMemberVariableOfITKClass/Documentation.rst
GetTypeBasicInformation/Documentation.rst
ImageBufferAndIndexRange/Documentation.rst
ImageRegionIntersection/Documentation.rst
ImageRegionOverlap/Documentation.rst
ImportPixelBufferIntoAnImage/Documentation.rst
Expand Down

0 comments on commit 0ba2890

Please sign in to comment.