Skip to content

Commit c505bf2

Browse files
committed
ENH: Migrate example itkGrayscaleFunctionDilateImageFilter
* Migrate the itkGrayscaleFunctionDilateImageFilter.cxx example from `ITK/Examples/Filtering` to `ITKSphinxExamples/src/Filtering/MathematicalMorphology/DilateAGrayscaleImage`. * Add new baseline output image as `OutputBaseline.png`. * Add an equivalent python implementation of the example.
1 parent 3bca12f commit c505bf2

File tree

7 files changed

+231
-0
lines changed

7 files changed

+231
-0
lines changed

src/Filtering/MathematicalMorphology/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,8 @@ add_example(ErodeBinaryImageUsingFlatStruct)
3232
compare_to_baseline(EXAMPLE_NAME ErodeBinaryImageUsingFlatStruct
3333
BASELINE_PREFIX ErodeBinaryImageUsingFlatStruct
3434
)
35+
36+
add_example(DilateUsingFunctionalGrayscale)
37+
compare_to_baseline(EXAMPLE_NAME DilateUsingFunctionalGrayscale
38+
BASELINE_PREFIX OutputBaseline
39+
)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
cmake_minimum_required(VERSION 3.16.3)
2+
3+
project( DilateUsingFunctionalGrayscale )
4+
5+
find_package( ITK REQUIRED
6+
COMPONENTS
7+
ITKCommon
8+
ITKIOImageBase
9+
ITKMathematicalMorphology
10+
ITKIOPNG
11+
)
12+
include( ${ITK_USE_FILE} )
13+
14+
add_executable( DilateUsingFunctionalGrayscale Code.cxx )
15+
target_link_libraries( DilateUsingFunctionalGrayscale ${ITK_LIBRARIES} )
16+
17+
install( TARGETS DilateUsingFunctionalGrayscale
18+
DESTINATION bin/ITKSphinxExamples/Filtering/MathematicalMorphology
19+
COMPONENT Runtime
20+
)
21+
22+
install( FILES Code.cxx CMakeLists.txt
23+
DESTINATION share/ITKSphinxExamples/Code/Filtering/MathematicalMorphology/DilateUsingFunctionalGrayscale
24+
COMPONENT Code
25+
)
26+
27+
enable_testing()
28+
add_test( NAME DilateUsingFunctionalGrayscaleTest
29+
COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DilateUsingFunctionalGrayscale
30+
${CMAKE_CURRENT_BINARY_DIR}/cthead1.png
31+
Output.png
32+
5
33+
)
34+
35+
if( ITK_WRAP_PYTHON )
36+
add_test( NAME DilateUsingFunctionalGrayscaleTestPython
37+
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Code.py
38+
${CMAKE_CURRENT_BINARY_DIR}/cthead1.png
39+
OutputPython.png
40+
5
41+
)
42+
endif()
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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+
* https://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 "itkFlatStructuringElement.h"
20+
#include "itkGrayscaleFunctionDilateImageFilter.h"
21+
#include "itkImage.h"
22+
#include "itkImageFileReader.h"
23+
#include "itkImageFileWriter.h"
24+
25+
int
26+
main(int argc, char * argv[])
27+
{
28+
if (argc < 4)
29+
{
30+
std::cerr << "Usage: " << std::endl;
31+
std::cerr << argv[0] << " <inputImage> <outputImage> <radius>";
32+
std::cerr << std::endl;
33+
return EXIT_FAILURE;
34+
}
35+
36+
constexpr unsigned int Dimension = 2;
37+
using PixelType = unsigned char;
38+
39+
using ImageType = itk::Image<PixelType, Dimension>;
40+
41+
using ReaderType = itk::ImageFileReader<ImageType>;
42+
using WriterType = itk::ImageFileWriter<ImageType>;
43+
44+
auto reader = ReaderType::New();
45+
auto writer = WriterType::New();
46+
47+
const char * inputImage = argv[1];
48+
const char * outputImage = argv[2];
49+
const unsigned int radiusValue = std::stoi(argv[3]);
50+
51+
reader->SetFileName(inputImage);
52+
writer->SetFileName(outputImage);
53+
54+
using StructuringElementType = itk::FlatStructuringElement<Dimension>;
55+
StructuringElementType::RadiusType radius;
56+
radius.Fill(radiusValue);
57+
StructuringElementType structuringElement = StructuringElementType::Ball(radius);
58+
59+
using FilterType = itk::GrayscaleFunctionDilateImageFilter<ImageType, ImageType, StructuringElementType>;
60+
61+
auto filter = FilterType::New();
62+
63+
filter->SetKernel(structuringElement);
64+
65+
filter->SetInput(reader->GetOutput());
66+
writer->SetInput(filter->GetOutput());
67+
68+
try
69+
{
70+
writer->Update();
71+
}
72+
catch (const itk::ExceptionObject & excp)
73+
{
74+
std::cerr << excp << std::endl;
75+
return EXIT_FAILURE;
76+
}
77+
78+
return EXIT_SUCCESS;
79+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env python
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+
import itk
18+
import argparse
19+
20+
itk.auto_progress(2)
21+
22+
parser = argparse.ArgumentParser(
23+
description="Dilate an image using functional grayscale morphology."
24+
)
25+
parser.add_argument("input_image")
26+
parser.add_argument("output_image")
27+
parser.add_argument("radius", type=int)
28+
args = parser.parse_args()
29+
30+
PixelType = itk.UC
31+
Dimension = 2
32+
33+
ImageType = itk.Image[PixelType, Dimension]
34+
35+
reader = itk.ImageFileReader[ImageType].New()
36+
reader.SetFileName(args.input_image)
37+
38+
StructuringElementType = itk.FlatStructuringElement[Dimension]
39+
structuringElement = StructuringElementType.Ball(args.radius)
40+
41+
grayscaleFilter = itk.GrayscaleFunctionDilateImageFilter[
42+
ImageType, ImageType, structuringElement
43+
].New()
44+
grayscaleFilter.SetInput(reader.GetOutput())
45+
grayscaleFilter.SetKernel(structuringElement)
46+
47+
writer = itk.ImageFileWriter[ImageType].New()
48+
writer.SetFileName(args.output_image)
49+
writer.SetInput(grayscaleFilter.GetOutput())
50+
51+
writer.Update()
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
:name: DilateUsingFunctionalGrayscale
2+
3+
Dilate a grayscale image using a functional kernel
4+
========================
5+
6+
.. index::
7+
single: BinaryBallStructuringElement
8+
single: GrayscaleFunctionDilateImageFilter
9+
pair: mathematical morphology; dilation
10+
11+
.. seealso:: dilation; erosion
12+
13+
14+
Synopsis
15+
--------
16+
17+
Dilate an image using functional grayscale morphology.
18+
Function dilation takes the maximum of all the pixels identified by the structuring element plus the structuring element value.
19+
In this example, the white regions are enlarged.
20+
21+
22+
23+
Results
24+
-------
25+
26+
.. figure:: cthead1.png
27+
:scale: 50%
28+
:alt: Input ct head image.
29+
30+
Input grayscale image.
31+
32+
.. figure:: OutputBaseline.png
33+
:scale: 50%
34+
:alt: Dilated output.
35+
36+
Dilated output.
37+
38+
39+
Code
40+
----
41+
42+
C++
43+
...
44+
45+
.. literalinclude:: Code.cxx
46+
:lines: 18-
47+
48+
49+
Classes demonstrated
50+
--------------------
51+
52+
.. breathelink:: itk::GrayscaleFunctionDilateImageFilter itk::BinaryBallStructuringElement
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
92adb2cb8bc2437cf1451037aa14305e7302d31503059b2aa4bc53e4bc8cd8ad00cb43bcbb31097e058f2486d806037b9ac192227368368392efd8a5dbc5c77c
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
32d5c12cd02f537c901ee48ad2f438fcf5399f7292bf9c0abfb8da91b74fc2e0c4983e9650283db3462d22f05f05a8637a6c3b8188159e4bbd6dc68804a84870

0 commit comments

Comments
 (0)