/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: MathematicalMorphologyGrayscaleFilters.cxx,v $ Language: C++ Date: $Date: 2005-08-31 13:55:21 $ Version: $Revision: 1.26 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #if defined(_MSC_VER) #pragma warning ( disable : 4786 ) #endif #ifdef __BORLANDC__ #define ITK_LEAN_AND_MEAN #endif // Software Guide : BeginCommandLineArgs // INPUTS: {BrainProtonDensitySlice.png} // OUTPUTS: {MathematicalMorphologyGrayscaleErosionOutput.png} // OUTPUTS: {MathematicalMorphologyGrayscaleDilationOutput.png} // 150 180 // Software Guide : EndCommandLineArgs // Software Guide : BeginLatex // // The following section illustrates the use of filters for performing basic // mathematical morphology operations on grayscale images. The // \doxygen{GrayscaleErodeImageFilter} and // \doxygen{GrayscaleDilateImageFilter} are covered in this example. The // filter names clearly specify the type of image on which they operate. // The header files required for a simple example of the use of // grayscale mathematical morphology filters are presented below. // // \index{itk::GrayscaleDilateImageFilter!header} // \index{itk::GrayscaleErodeImageFilter!header} // // Software Guide : EndLatex #include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" // Software Guide : BeginCodeSnippet #include "itkGrayscaleErodeImageFilter.h" #include "itkGrayscaleDilateImageFilter.h" #include "itkBinaryBallStructuringElement.h" #include "itkRescaleIntensityImageFilter.h" // Software Guide : EndCodeSnippet int main( int argc, char * argv[] ) { if( argc < 4 ) { std::cerr << "Usage: " << std::endl; std::cerr << argv[0] << " inputImageFile "; std::cerr << " outputImageFileErosion outputImageFileDilation" << std::endl; return EXIT_FAILURE; } int t1, t2; t1 = GetTickCount(); // Software Guide : BeginLatex // // The following code defines the input and output pixel types and their // associated image types. // // Software Guide : EndLatex // Software Guide : BeginCodeSnippet const unsigned int Dimension = 2; typedef float InputPixelType; typedef float OutputPixelType; typedef unsigned int WritePixelType; typedef itk::Image< InputPixelType, Dimension > InputImageType; typedef itk::Image< OutputPixelType, Dimension > OutputImageType; typedef itk::Image< WritePixelType, Dimension > WriteImageType; // Software Guide : EndCodeSnippet typedef itk::ImageFileReader< InputImageType > ReaderType; typedef itk::RescaleIntensityImageFilter < OutputImageType, WriteImageType > RescalerType; typedef itk::ImageFileWriter< WriteImageType > WriterType; // Software Guide : BeginLatex // // Mathematical morphology operations are based on the application of an // operator over a neighborhood of each input pixel. The combination of // the rule and the neighborhood is known as \emph{structuring // element}. Although some rules have become the de facto standard in image // processing there is a good deal of freedom as to what kind of // algorithmic rule should be applied on the neighborhood. The // implementation in ITK follows the typical rule of minimum for // erosion and maximum for dilation. // // The structuring element is implemented as a // \doxygen{NeighborhoodOperator}. In particular, the default structuring // element is the \doxygen{BinaryBallStructuringElement} class. This class // is instantiated using the pixel type and dimension of the input image. // // Software Guide : EndLatex // Software Guide : BeginCodeSnippet typedef itk::BinaryBallStructuringElement< InputPixelType, Dimension > StructuringElementType; // Software Guide : EndCodeSnippet // Software Guide : BeginLatex // // The structuring element type is then used along with the input and output // image types for instantiating the type of the filters. // // Software Guide : EndLatex // Software Guide : BeginCodeSnippet typedef itk::GrayscaleErodeImageFilter< InputImageType, OutputImageType, StructuringElementType > ErodeFilterType; typedef itk::GrayscaleDilateImageFilter< InputImageType, OutputImageType, StructuringElementType > DilateFilterType; // Software Guide : EndCodeSnippet // Creation of Reader and Writer filters ReaderType::Pointer reader = ReaderType::New(); WriterType::Pointer writerDilation = WriterType::New(); WriterType::Pointer writerErosion = WriterType::New(); // Software Guide : BeginLatex // // The filters can now be created by invoking the \code{New()} method and // assigning the result to SmartPointers. // // \index{itk::GrayscaleDilateImageFilter!New()} // \index{itk::GrayscaleErodeImageFilter!New()} // \index{itk::GrayscaleDilateImageFilter!Pointer} // \index{itk::GrayscaleErodeImageFilter!Pointer} // // Software Guide : EndLatex // Software Guide : BeginCodeSnippet ErodeFilterType::Pointer grayscaleErode = ErodeFilterType::New(); DilateFilterType::Pointer grayscaleDilate = DilateFilterType::New(); // Software Guide : EndCodeSnippet // Software Guide : BeginLatex // // The structuring element is not a reference counted class. Thus it is // created as a C++ stack object instead of using \code{New()} and // SmartPointers. The radius of the neighborhood associated with the // structuring element is defined with the \code{SetRadius()} method and the // \code{CreateStructuringElement()} method is invoked in order to initialize the // operator. The resulting structuring element is passed to the // mathematical morphology filter through the \code{SetKernel()} method, as // illustrated below. // // \index{itk::BinaryBallStructuringElement!SetRadius()} // \index{itk::BinaryBallStructuringElement!CreateStructuringElement()} // \index{itk::GrayscaleDilateImageFilter!SetKernel()} // \index{itk::GrayscaleErodeImageFilter!SetKernel()} // \index{SetRadius()!itk::BinaryBallStructuringElement} // \index{SetKernel()!itk::GrayscaleDilateImageFilter} // \index{SetKernel()!itk::GrayscaleErodeImageFilter} // \index{SetRadius()!itk::BinaryBallStructuringElement} // \index{CreateStructuringElement()!itk::BinaryBallStructuringElement} // // Software Guide : EndLatex // Software Guide : BeginCodeSnippet StructuringElementType structuringElement; structuringElement.SetRadius( 1 ); // 3x3 structuring element structuringElement.CreateStructuringElement(); grayscaleErode->SetKernel( structuringElement ); grayscaleDilate->SetKernel( structuringElement ); // Software Guide : EndCodeSnippet reader->SetFileName( argv[1] ); writerErosion->SetFileName( argv[2] ); writerDilation->SetFileName( argv[3] ); // Software Guide : BeginLatex // // A grayscale image is provided as input to the filters. This image might be, // for example, the output of a reader. // // Software Guide : EndLatex // Software Guide : BeginCodeSnippet grayscaleErode->SetInput( reader->GetOutput() ); grayscaleDilate->SetInput( reader->GetOutput() ); // Software Guide : EndCodeSnippet // Software Guide : BeginLatex // // The filter is executed by invoking its \code{Update()} method, or by // updating any downstream filter, like, for example, an image writer. // // \index{itk::GrayscaleDilateImageFilter!Update()} // \index{itk::GrayscaleErodeImageFilter!Update()} // // Software Guide : EndLatex typedef itk::RescaleIntensityImageFilter RescaleFilterType; RescaleFilterType::Pointer rescalerDilatation = RescaleFilterType::New(); RescaleFilterType::Pointer rescalerErosion = RescaleFilterType::New(); rescalerDilatation->SetOutputMinimum(0); rescalerDilatation->SetOutputMaximum(255); rescalerErosion->SetOutputMinimum(0); rescalerErosion->SetOutputMaximum(255); // Software Guide : BeginCodeSnippet rescalerDilatation->SetInput( grayscaleDilate->GetOutput() ); writerDilation->SetInput( rescalerDilatation->GetOutput() ); try { writerDilation->Update(); } catch (itk::ExceptionObject &excp) { std::cerr<SetInput( grayscaleErode->GetOutput() ); writerErosion->SetInput( rescalerErosion->GetOutput() ); try { writerErosion->Update(); } catch (itk::ExceptionObject &excp) { std::cerr<