ITK  5.2.0
Insight Toolkit
Examples/Filtering/CannyEdgeDetectionImageFilter.cxx
/*=========================================================================
*
* 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.
*
*=========================================================================*/
// Software Guide : BeginLatex
//
// This example introduces the use of the
// \doxygen{CannyEdgeDetectionImageFilter}. Canny edge detection is widely
// used for edge detection since it is the optimal solution satisfying the
// constraints of good sensitivity, localization and noise robustness. To
// achieve this end, Canny edge detection is implemented internally as a
// multi-stage algorithm, which involves Gaussian smoothing to remove noise,
// calculation of gradient magnitudes to localize edge features, non-maximum
// suppression to remove suprious features, and finally thresholding to yield
// a binary image. Though the specifics of this internal pipeline are largely
// abstracted from the user of the class, it is nonetheless beneficial to
// have a general understanding of these components so that parameters can be
// appropriately adjusted.
//
// \index{itk::CannyEdgeDetectionImageFilter|textbf}
//
// The first step required for using this filter is to include its header
// file.
//
// \index{itk::CannyEdgeDetectionImageFilter!header}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// Software Guide : EndCodeSnippet
int
main(int argc, char * argv[])
{
if (argc < 3)
{
std::cerr << "Usage: " << std::endl;
std::cerr << argv[0] << " inputImage outputImage"
<< " [variance upperThreshold lowerThreshold]" << std::endl;
return EXIT_FAILURE;
}
const char * inputFilename = argv[1];
const char * outputFilename = argv[2];
float variance = 2.0;
float upperThreshold = 0.0;
float lowerThreshold = 0.0;
if (argc > 3)
{
variance = std::stod(argv[3]);
}
if (argc > 4)
{
upperThreshold = std::stod(argv[4]);
}
if (argc > 5)
{
lowerThreshold = std::stod(argv[5]);
}
std::cout << "Variance = " << variance << std::endl;
std::cout << "UpperThreshold = " << upperThreshold << std::endl;
std::cout << "LowerThreshold = " << lowerThreshold << std::endl;
// Software Guide : BeginLatex
//
// In this example, images are read and written with \code{unsigned char}
// pixel type. However, Canny edge detection requires floating point
// pixel types in order to avoid numerical errors. For this reason,
// a separate internal image type with pixel type \code{double} is defined
// for edge detection.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
constexpr unsigned int Dimension = 2;
using CharPixelType = unsigned char; // IO
using RealPixelType = double; // Operations
using CharImageType = itk::Image<CharPixelType, Dimension>;
using RealImageType = itk::Image<RealPixelType, Dimension>;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The \code{CharImageType} image is cast to and from \code{RealImageType}
// using \doxygen{CastImageFilter} and \code{RescaleIntensityImageFilter},
// respectively; both the input and output of
// \code{CannyEdgeDetectionImageFilter} are \code{RealImageType}.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
using CastToRealFilterType =
using CannyFilterType =
using RescaleFilterType =
// Software Guide : EndCodeSnippet
// Setting the IO
ReaderType::Pointer reader = ReaderType::New();
CastToRealFilterType::Pointer toReal = CastToRealFilterType::New();
CannyFilterType::Pointer cannyFilter = CannyFilterType::New();
RescaleFilterType::Pointer rescale = RescaleFilterType::New();
WriterType::Pointer writer = WriterType::New();
reader->SetFileName(inputFilename);
writer->SetFileName(outputFilename);
toReal->SetInput(reader->GetOutput());
cannyFilter->SetInput(toReal->GetOutput());
rescale->SetInput(cannyFilter->GetOutput());
writer->SetInput(rescale->GetOutput());
// Software Guide : BeginLatex
//
// In this example, three parameters of the Canny edge detection
// filter may be set via the \code{SetVariance()},
// \code{SetUpperThreshold()}, and \code{SetLowerThreshold()} methods.
// Based on the previous discussion of the steps in the internal pipeline,
// we understand that \code{variance} adjusts the amount of Gaussian
// smoothing and \code{upperThreshold} and \code{lowerThreshold} control
// which edges are selected in the final step.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
cannyFilter->SetVariance(variance);
cannyFilter->SetUpperThreshold(upperThreshold);
cannyFilter->SetLowerThreshold(lowerThreshold);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Finally, \code{Update()} is called on \code{writer} to trigger
// excecution of the pipeline. As usual, the call is wrapped in a
// \code{try/catch} block.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
try
{
writer->Update();
}
catch (const itk::ExceptionObject & err)
{
std::cout << "ExceptionObject caught !" << std::endl;
std::cout << err << std::endl;
return EXIT_FAILURE;
}
// Software Guide : EndCodeSnippet
return EXIT_SUCCESS;
}
itkCannyEdgeDetectionImageFilter.h
itk::CastImageFilter
Casts input pixels to output pixel type.
Definition: itkCastImageFilter.h:104
itkImageFileReader.h
itkCastImageFilter.h
itk::ImageFileReader
Data source that reads image data from a single file.
Definition: itkImageFileReader.h:75
itk::ImageFileWriter
Writes image data to a single file.
Definition: itkImageFileWriter.h:88
itk::CannyEdgeDetectionImageFilter
This filter is an implementation of a Canny edge detector for scalar-valued images.
Definition: itkCannyEdgeDetectionImageFilter.h:88
itkRescaleIntensityImageFilter.h
itkImageFileWriter.h
itk::RescaleIntensityImageFilter
Applies a linear transformation to the intensity levels of the input Image.
Definition: itkRescaleIntensityImageFilter.h:154
itk::Image
Templated n-dimensional image class.
Definition: itkImage.h:86
itk::GTest::TypedefsAndConstructors::Dimension2::Dimension
constexpr unsigned int Dimension
Definition: itkGTestTypedefsAndConstructors.h:44