Skip to content

Commit

Permalink
ENH: Add example derivativeImage (#380)
Browse files Browse the repository at this point in the history
* ENH: Add example derivativeImage

* ENH: Add baseline check to verify against previous data
  • Loading branch information
labdala authored Jul 5, 2022
1 parent 5d3a1ab commit ff92cc6
Show file tree
Hide file tree
Showing 10 changed files with 282 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/Filtering/ImageFeature/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ add_example(FindZeroCrossingsInSignedImage)
#===================================

add_example(AdditiveGaussianNoiseImageFilter)

add_example(DerivativeImage)
compare_to_baseline(EXAMPLE_NAME DerivativeImage BASELINE_PREFIX Output)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
86cbe2a809e90d72fb464868449477fe6d83809ddd0493cfca92033d7d3dd4bc3e0b831b17735926ed990735234a4eb8034aeaca70a3f5ba18fffe8f3c8e7eaa
34 changes: 34 additions & 0 deletions src/Filtering/ImageFeature/DerivativeImage/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
cmake_minimum_required(VERSION 3.16.3)

project( DerivativeImage )

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

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

install( TARGETS DerivativeImage
DESTINATION bin/ITKSphinxExamples/Filtering/ImageFeature
COMPONENT Runtime
)

install( FILES Code.cxx CMakeLists.txt
DESTINATION share/ITKSphinxExamples/Code/Filtering/ImageFeature/DerivativeImage
COMPONENT Code
)

enable_testing()
add_test( NAME DerivativeImageTest
COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DerivativeImage
${CMAKE_CURRENT_BINARY_DIR}/BrainProtonDensitySlice.png
Output.mha Output_normalized.mha 1 1
)

#if( ITK_WRAP_PYTHON )
# add_test( NAME DerivativeImageTestPython
# COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Code.py
# ${CMAKE_CURRENT_BINARY_DIR}/BrainProtonDensitySlice.png
# OutputPython.png
# )
#endif()
190 changes: 190 additions & 0 deletions src/Filtering/ImageFeature/DerivativeImage/Code.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/*=========================================================================
*
* 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
*
* https://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.
*
*=========================================================================*/

// Software Guide : BeginCommandLineArgs
// INPUTS: {BrainProtonDensitySlice.png}
// ARGUMENTS: {DerivativeImageFilterFloatOutput.mhd}
// OUTPUTS: {DerivativeImageFilterOutput.png}
// ARGUMENTS: 1 0
// Software Guide : EndCommandLineArgs

// Software Guide : BeginLatex
//
// The \doxygen{DerivativeImageFilter} is used for computing the partial
// derivative of an image, the derivative of an image along a particular
// axial direction.
//
// \index{itk::DerivativeImageFilter}
//
// Software Guide : EndLatex


#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"

// Software Guide : BeginLatex
//
// The header file corresponding to this filter should be included first.
//
// \index{itk::DerivativeImageFilter!header}
//
// Software Guide : EndLatex


// Software Guide : BeginCodeSnippet
#include "itkDerivativeImageFilter.h"
// Software Guide : EndCodeSnippet


int
main(int argc, char * argv[])
{
if (argc < 6)
{
std::cerr << "Usage: " << std::endl;
std::cerr << argv[0] << " inputImageFile outputImageFile normalizedOutputImageFile ";
std::cerr << " derivativeOrder direction" << std::endl;
return EXIT_FAILURE;
}


// Software Guide : BeginLatex
//
// Next, the pixel types for the input and output images must be defined
// and, with them, the image types can be instantiated. Note that it is
// important to select a signed type for the image, since the values of the
// derivatives will be positive as well as negative.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
using InputPixelType = float;
using OutputPixelType = float;

constexpr unsigned int Dimension = 2;

using InputImageType = itk::Image<InputPixelType, Dimension>;
using OutputImageType = itk::Image<OutputPixelType, Dimension>;
// Software Guide : EndCodeSnippet


using ReaderType = itk::ImageFileReader<InputImageType>;
using WriterType = itk::ImageFileWriter<OutputImageType>;

auto reader = ReaderType::New();
auto writer = WriterType::New();

reader->SetFileName(argv[1]);
writer->SetFileName(argv[2]);

// Software Guide : BeginLatex
//
// Using the image types, it is now possible to define the filter type
// and create the filter object.
//
// \index{itk::DerivativeImageFilter!instantiation}
// \index{itk::DerivativeImageFilter!New()}
// \index{itk::DerivativeImageFilter!Pointer}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
using FilterType = itk::DerivativeImageFilter<InputImageType, OutputImageType>;

auto filter = FilterType::New();
// Software Guide : EndCodeSnippet


// Software Guide : BeginLatex
//
// The order of the derivative is selected with the \code{SetOrder()}
// method. The direction along which the derivative will be computed is
// selected with the \code{SetDirection()} method.
//
// \index{itk::DerivativeImageFilter!SetOrder()}
// \index{itk::DerivativeImageFilter!SetDirection()}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
filter->SetOrder(std::stoi(argv[4]));
filter->SetDirection(std::stoi(argv[5]));
// Software Guide : EndCodeSnippet


// Software Guide : BeginLatex
//
// The input to the filter can be taken from any other filter, for example
// a reader. The output can be passed down the pipeline to other filters,
// for example, a writer. An \code{Update()} call on any downstream filter
// will trigger the execution of the derivative filter.
//
// \index{itk::DerivativeImageFilter!SetInput()}
// \index{itk::DerivativeImageFilter!GetOutput()}
//
// Software Guide : EndLatex


// Software Guide : BeginCodeSnippet
filter->SetInput(reader->GetOutput());
writer->SetInput(filter->GetOutput());
writer->Update();
// Software Guide : EndCodeSnippet


// Software Guide : BeginLatex
//
// \begin{figure}
// \center
// \includegraphics[width=0.44\textwidth]{BrainProtonDensitySlice}
// \includegraphics[width=0.44\textwidth]{DerivativeImageFilterOutput}
// \itkcaption[Effect of the Derivative filter.]{Effect of the Derivative
// filter on a slice from a MRI proton density brain image.}
// \label{fig:DerivativeImageFilterOutput}
// \end{figure}
//
// Figure \ref{fig:DerivativeImageFilterOutput} illustrates the effect of
// the DerivativeImageFilter on a slice of MRI brain image. The derivative
// is taken along the $x$ direction. The sensitivity to noise in the image
// is evident from this result.
//
// Software Guide : EndLatex


using WriteImageType = itk::Image<unsigned char, Dimension>;

using NormalizeFilterType = itk::RescaleIntensityImageFilter<OutputImageType, WriteImageType>;

using NormalizedWriterType = itk::ImageFileWriter<WriteImageType>;

auto normalizer = NormalizeFilterType::New();
auto normalizedWriter = NormalizedWriterType::New();

normalizer->SetInput(filter->GetOutput());
normalizedWriter->SetInput(normalizer->GetOutput());

normalizer->SetOutputMinimum(0);
normalizer->SetOutputMaximum(255);

normalizedWriter->SetFileName(argv[3]);
normalizedWriter->Update();

return EXIT_SUCCESS;
}
49 changes: 49 additions & 0 deletions src/Filtering/ImageFeature/DerivativeImage/Documentation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
:name: DerivativeImage

Compute Derivative
===================

.. index::
single: DerivativeImageFilter

Synopsis
--------

This filter computes a n-th Derivative of a scalar-valued image in a specified direction.


Results
-------

.. figure:: BrainProtonDensitySlice.png
:scale: 50%
:alt: Input image

Input image

.. figure:: Output.png
:scale: 50%
:alt: Output image

Output image


.. figure:: Output_normalized.png
:scale: 50%
:alt: Output normalized image

Output normalized image

Code
----

C++
...

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

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

.. breathelink:: itk::DerivativeImageFilter
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1bba1d72a84bf2d171c85834a9e9e7e485b26ef60a05fb0fe93c1103ff920071fc5ccc14b7c27348abf5dcd537825838bdefd7a8b27336c8115677ceb80af227
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
29e67a22a4218b780ca75af045544178e193aefce7ceff7923fcd858068918efab6d41c37ea3020fe3747abb35172a67be33ff85c9595ff3a19fffdc37d6a2d1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
346c92583d339826d3ebf9cede566d1d215e50b3cd431fe63e693e97f03f0b9f48c2f461a4dd73218f0e5852f5a12e9d90e8360c522fb8e5752aadc86e6d3362
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1cf70adf30331a9c1a084e64f13dc7c263d212ebcad0880048413af3490ee81f5e1f77caf5cd98b52a0181a66ad2ced1c02392dd8c8e2d46f615e93d205df6c4
1 change: 1 addition & 0 deletions src/Filtering/ImageFeature/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ ImageFeature
BilateralFilterAnImage/Documentation.rst
ComputeLaplacian/Documentation.rst
DetectEdgesWithCannyEdgeDetectionFilter/Documentation.rst
DerivativeImage/Documentation.rst
ExtractContoursFromImage/Documentation.rst
FindZeroCrossingsInSignedImage/Documentation.rst
LaplacianRecursiveGaussianImageFilter/Documentation.rst
Expand Down

1 comment on commit ff92cc6

@github-actions
Copy link

Choose a reason for hiding this comment

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

Please sign in to comment.