Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Add ImageBufferAndIndexRange example #368

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool!


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