Skip to content

Commit 06cc158

Browse files
N-Dekkerdzenanz
authored andcommitted
ENH: Add example, "Generate the Offsets of a Shaped Image Neighborhood"
1 parent a9d3b22 commit 06cc158

File tree

5 files changed

+215
-0
lines changed

5 files changed

+215
-0
lines changed

src/Core/Common/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ add_example(DuplicateAnImage)
4646
add_example(ApplyAFilterOnlyToASpecifiedRegionOfAnImage)
4747
add_example(IterateOverARegionWithAShapedNeighborhoodIterator)
4848
add_example(IterateOverARegionWithAShapedNeighborhoodIteratorManual)
49+
add_example(GenerateOffsetsShapedImageNeighborhood)
4950
add_example(CreateABackwardDifferenceOperator)
5051
add_example(BuildAHelloWorldProgram)
5152
add_example(TraceMemoryBetweenPoints)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
cmake_minimum_required(VERSION 3.16.3)
2+
3+
project(Shapes)
4+
5+
find_package(ITK REQUIRED)
6+
include(${ITK_USE_FILE})
7+
8+
add_executable(${PROJECT_NAME} Code.cxx)
9+
target_link_libraries(${PROJECT_NAME} ${ITK_LIBRARIES})
10+
11+
install(TARGETS ${PROJECT_NAME}
12+
DESTINATION bin/ITKSphinxExamples/Core/Common
13+
COMPONENT Runtime
14+
)
15+
16+
install(FILES Code.cxx CMakeLists.txt
17+
DESTINATION share/ITKSphinxExamples/Code/Core/Common/${PROJECT_NAME}
18+
COMPONENT Code
19+
)
20+
21+
enable_testing()
22+
add_test(NAME ${PROJECT_NAME}Test
23+
COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME})
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*=========================================================================
2+
*
3+
* Copyright NumFOCUS
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0.txt
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*=========================================================================*/
18+
19+
#include "itkConnectedImageNeighborhoodShape.h"
20+
#include "itkImage.h"
21+
#include "itkImageBufferRange.h"
22+
#include "itkImageNeighborhoodOffsets.h"
23+
#include "itkRectangularImageNeighborhoodShape.h"
24+
#include "itkShapedImageNeighborhoodRange.h"
25+
26+
#include <array>
27+
#include <cassert>
28+
#include <numeric> // For iota
29+
#include <ios> // For hex
30+
31+
namespace
32+
{
33+
constexpr unsigned int Dimension{ 2 };
34+
using OffsetType = itk::Offset<Dimension>;
35+
36+
// Print the specified offsets of a neighborhood shape. Also prints the pixel values of a small image for which such a
37+
// shaped neigborhood located at the image center is filled with consecutive values, 1, 2, 3, ..., N.
38+
template <typename TOffsets>
39+
void
40+
PrintImageNeighborhoodShape(const TOffsets & offsets)
41+
{
42+
std::cout << " ";
43+
44+
for (const OffsetType & offset : offsets)
45+
{
46+
std::cout << offset << ' ';
47+
}
48+
49+
using ImageType = itk::Image<int>;
50+
const auto image = ImageType::New();
51+
constexpr unsigned int imageSize{ 7 };
52+
image->SetRegions(ImageType::SizeType::Filled(imageSize));
53+
image->Allocate(true);
54+
55+
const auto centerIndex = ImageType::IndexType::Filled(imageSize / 2);
56+
const itk::ShapedImageNeighborhoodRange<ImageType> shapedImageNeighborhoodRange(*image, centerIndex, offsets);
57+
58+
// Set the values of the pixels in the "shaped neighborhood" of the image center to 1, 2, 3, ..., N, consecutively.
59+
std::iota(shapedImageNeighborhoodRange.begin(), shapedImageNeighborhoodRange.end(), 1);
60+
61+
std::cout << "\n\n";
62+
const std::ios_base::fmtflags flags(std::cout.flags());
63+
std::cout << std::hex << std::uppercase;
64+
65+
const itk::ImageBufferRange<const ImageType> imageBufferRange(*image);
66+
auto imageBufferIterator = imageBufferRange.cbegin();
67+
68+
for (int y{ 0 }; y < imageSize; ++y)
69+
{
70+
std::cout << " ";
71+
72+
for (int x{ 0 }; x < imageSize; ++x)
73+
{
74+
std::cout << *imageBufferIterator << ' ';
75+
++imageBufferIterator;
76+
}
77+
std::cout << '\n';
78+
}
79+
std::cout.flags(flags);
80+
std::cout << '\n';
81+
}
82+
83+
} // namespace
84+
85+
86+
int
87+
main()
88+
{
89+
const std::array<OffsetType, 3> offsets = { { { { 0, -1 } }, { { 0, 1 } }, { { 1, 1 } } } };
90+
std::cout << "Shape of some arbitrary offsets:\n\n";
91+
PrintImageNeighborhoodShape(offsets);
92+
93+
const bool includeCenterPixel = false;
94+
const size_t maximumCityblockDistance = 1;
95+
std::cout << "4-connected neighborhood shape (excluding the center pixel) with maximumCityblockDistance = "
96+
<< maximumCityblockDistance << ":\n\n";
97+
98+
// GenerateConnectedImageNeighborhoodShapeOffsets returns an std::array of offsets.
99+
const auto connectedImageNeighborhoodShapeOffsets =
100+
itk::GenerateConnectedImageNeighborhoodShapeOffsets<Dimension, maximumCityblockDistance, includeCenterPixel>();
101+
PrintImageNeighborhoodShape(connectedImageNeighborhoodShapeOffsets);
102+
103+
const itk::Size<Dimension> radius = { { 1, 2 } };
104+
std::cout << "Rectangular shape of radius " << radius << ":\n\n";
105+
106+
// GenerateRectangularImageNeighborhoodOffsets returns an std::vector of offsets.
107+
const auto rectangularImageNeighborhoodOffsets = itk::GenerateRectangularImageNeighborhoodOffsets(radius);
108+
PrintImageNeighborhoodShape(rectangularImageNeighborhoodOffsets);
109+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
:name: GenerateOffsetsShapedImageNeighborhood
2+
3+
Generate the Offsets of a Shaped Image Neighborhood
4+
===================================================
5+
6+
.. index::
7+
single: ConnectedImageNeighborhoodShape
8+
single: RectangularImageNeighborhoodShape
9+
single: ShapedImageNeighborhoodRange
10+
11+
12+
Synopsis
13+
--------
14+
15+
16+
This example demonstrates various ways to create a container of offsets, to
17+
specify the shape of a neighborhood of pixels:
18+
19+
- An arbitrary shape
20+
- A 4-connected neighborhood shape
21+
- A rectangular neighborhood shape
22+
23+
These offsets may be used to specify the shape of a ShapedImageNeighborhoodRange
24+
(as included with this code example), or a ShapedNeighborhoodIterator.
25+
26+
Results
27+
-------
28+
29+
Output::
30+
31+
Shape of some arbitrary offsets:
32+
33+
[0, -1] [0, 1] [1, 1]
34+
35+
0 0 0 0 0 0 0
36+
0 0 0 0 0 0 0
37+
0 0 0 1 0 0 0
38+
0 0 0 0 0 0 0
39+
0 0 0 2 3 0 0
40+
0 0 0 0 0 0 0
41+
0 0 0 0 0 0 0
42+
43+
4-connected neighborhood shape (excluding the center pixel) with maximumCityblockDistance = 1:
44+
45+
[0, -1] [-1, 0] [1, 0] [0, 1]
46+
47+
0 0 0 0 0 0 0
48+
0 0 0 0 0 0 0
49+
0 0 0 1 0 0 0
50+
0 0 2 0 3 0 0
51+
0 0 0 4 0 0 0
52+
0 0 0 0 0 0 0
53+
0 0 0 0 0 0 0
54+
55+
Rectangular shape of radius [1, 2]:
56+
57+
[-1, -2] [0, -2] [1, -2] [-1, -1] [0, -1] [1, -1] [-1, 0] [0, 0] [1, 0] [-1, 1] [0, 1] [1, 1] [-1, 2] [0, 2] [1, 2]
58+
59+
0 0 0 0 0 0 0
60+
0 0 1 2 3 0 0
61+
0 0 4 5 6 0 0
62+
0 0 7 8 9 0 0
63+
0 0 A B C 0 0
64+
0 0 D E F 0 0
65+
0 0 0 0 0 0 0
66+
67+
68+
Code
69+
----
70+
71+
C++
72+
...
73+
74+
.. literalinclude:: Code.cxx
75+
:lines: 18-
76+
77+
78+
Classes demonstrated
79+
--------------------
80+
81+
.. breathelink:: itk::ConnectedImageNeighborhoodShape itk::RectangularImageNeighborhoodShape

src/Core/Common/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ Common
5555
FilterImageUsingMultipleThreads/Documentation.rst
5656
FilterImageWithoutCopying/Documentation.rst
5757
FindMaxAndMinInImage/Documentation.rst
58+
GenerateOffsetsShapedImageNeighborhood/Documentation.rst
5859
GetImageSize/Documentation.rst
5960
GetNameOfClass/Documentation.rst
6061
GetOrSetMemberVariableOfITKClass/Documentation.rst

0 commit comments

Comments
 (0)