diff --git a/Code/FeatureExtraction/otbComplexMomentImageFunction.txx b/Code/FeatureExtraction/otbComplexMomentImageFunction.txx index 1f67679df3dae5393d364c7d248b9cfc216da7d8..a9ef0f2bc716303906fe1c92eac7586cb43bbe79 100644 --- a/Code/FeatureExtraction/otbComplexMomentImageFunction.txx +++ b/Code/FeatureExtraction/otbComplexMomentImageFunction.txx @@ -111,7 +111,9 @@ ComplexMomentImageFunction<TInput,TOutput,TCoordRep> --q; } - Sum += ( ValP * ValQ * std::complex<float>(static_cast<float>(it.GetPixel(i)),0.0) ); + Sum += ( ValP * ValQ * std::complex<float>(static_cast<float>(it.GetPixel(i)),0.0) ); + + //std::cout << Sum << std::endl; } return (static_cast<ComplexType>(Sum) ); diff --git a/Code/FeatureExtraction/otbHuImageFunction.txx b/Code/FeatureExtraction/otbHuImageFunction.txx index 62b24cc4ab89488091e7241b54dc170aa7979653..d6e2feed252c556a8be64ec8a35fed8d61779d85 100644 --- a/Code/FeatureExtraction/otbHuImageFunction.txx +++ b/Code/FeatureExtraction/otbHuImageFunction.txx @@ -62,18 +62,23 @@ HuImageFunction<TInput,TOutput,TCoordRep> { return ( itk::NumericTraits<RealType>::max() ); } + + +/* std::cout << "Start" << this->GetStartIndex() << std::endl; + std::cout << "End" << this->GetEndIndex() << std::endl; */ if ( !this->IsInsideBuffer( index ) ) { + std::cout << index << std::endl; return ( itk::NumericTraits<RealType>::max() ); } assert(m_MomentNumber > 0); assert(m_MomentNumber < 8); - + function->SetInputImage( this->GetInputImage() ); //OTB-FA-00025-CS - std::cout << "Neighbor " <<this->GetNeighborhoodRadius()<<std::endl; +// std::cout << "Neighbor " <<this->GetNeighborhoodRadius()<<std::endl; function->SetNeighborhoodRadius(this->GetNeighborhoodRadius() ); //OTB-FA-00024-CS diff --git a/Examples/Segmentation/CMakeLists.txt b/Examples/Segmentation/CMakeLists.txt index 087e2e1ec4f4cc34853c0e2a57a114369cc3783b..535beedcbcbfc04972e596de56c3ae54d276ac3b 100644 --- a/Examples/Segmentation/CMakeLists.txt +++ b/Examples/Segmentation/CMakeLists.txt @@ -8,11 +8,19 @@ INCLUDE_REGULAR_EXPRESSION("^.*$") ADD_EXECUTABLE(ConnectedThresholdImageFilter ConnectedThresholdImageFilter.cxx ) TARGET_LINK_LIBRARIES(ConnectedThresholdImageFilter OTBCommon OTBIO ITKNumerics ITKIO) +ADD_EXECUTABLE(OtsuThresholdImageFilter OtsuThresholdImageFilter.cxx ) +TARGET_LINK_LIBRARIES(OtsuThresholdImageFilter OTBCommon OTBIO ITKCommon ITKIO) + +ADD_EXECUTABLE(OtsuMultipleThresholdImageFilter OtsuMultipleThresholdImageFilter.cxx ) +TARGET_LINK_LIBRARIES(OtsuMultipleThresholdImageFilter + OTBCommon OTBIO ITKCommon ITKIO ITKStatistics) + #ADD_EXECUTABLE(ConfidenceConnected ConfidenceConnected.cxx ) #TARGET_LINK_LIBRARIES(ConfidenceConnected ITKNumerics ITKIO) -#ADD_EXECUTABLE(NeighborhoodConnectedImageFilter NeighborhoodConnectedImageFilter.cxx ) -#TARGET_LINK_LIBRARIES(NeighborhoodConnectedImageFilter ITKNumerics ITKIO) +ADD_EXECUTABLE(NeighborhoodConnectedImageFilter NeighborhoodConnectedImageFilter.cxx ) +TARGET_LINK_LIBRARIES(NeighborhoodConnectedImageFilter OTBCommon OTBIO +ITKNumerics ITKIO) #ADD_EXECUTABLE(IsolatedConnectedImageFilter IsolatedConnectedImageFilter.cxx ) #TARGET_LINK_LIBRARIES(IsolatedConnectedImageFilter ITKNumerics ITKIO) diff --git a/Examples/Segmentation/NeighborhoodConnectedImageFilter.cxx b/Examples/Segmentation/NeighborhoodConnectedImageFilter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..781a2b6c8e39f1d399474e9d7c84abb6a56dd247 --- /dev/null +++ b/Examples/Segmentation/NeighborhoodConnectedImageFilter.cxx @@ -0,0 +1,342 @@ + +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#ifdef __BORLANDC__ +#define ITK_LEAN_AND_MEAN +#endif + +// Software Guide : BeginCommandLineArgs +// INPUTS: {QB_Suburb.png} +// OUTPUTS: {NeighborhoodConnectedThresholdOutput1.png} +// 110 38 50 100 +// Software Guide : EndCommandLineArgs +// Software Guide : BeginCommandLineArgs +// INPUTS: {QB_Suburb.png} +// OUTPUTS: {NeighborhoodConnectedThresholdOutput2.png} +// 118 100 0 10 +// Software Guide : EndCommandLineArgs +// Software Guide : BeginCommandLineArgs +// INPUTS: {QB_Suburb.png} +// OUTPUTS: {NeighborhoodConnectedThresholdOutput3.png} +// 169 146 220 255 +// Software Guide : EndCommandLineArgs + +// Software Guide : BeginLatex +// +// The following example illustrates the use of the +// \doxygen{itk::NeighborhoodConnectedImageFilter}. This filter is a close variant +// of the \doxygen{itk::ConnectedThresholdImageFilter}. On one hand, the +// ConnectedThresholdImageFilter accepts a pixel in the region if its intensity +// is in the interval defined by two user-provided threshold values. The +// NeighborhoodConnectedImageFilter, on the other hand, will only accept a +// pixel if \textbf{all} its neighbors have intensities that fit in the +// interval. The size of the neighborhood to be considered around each pixel is +// defined by a user-provided integer radius. +// +// The reason for considering the neighborhood intensities instead of only the +// current pixel intensity is that small structures are less likely to be +// accepted in the region. The operation of this filter is equivalent to +// applying the ConnectedThresholdImageFilter followed by mathematical +// morphology erosion using a structuring element of the same shape as +// the neighborhood provided to the NeighborhoodConnectedImageFilter. +// +// Software Guide : EndLatex + + +// Software Guide : BeginCodeSnippet +#include "itkNeighborhoodConnectedImageFilter.h" +// Software Guide : EndCodeSnippet + + +#include "otbImage.h" +#include "itkCastImageFilter.h" + + +// Software Guide : BeginLatex +// +// The \doxygen{itk::CurvatureFlowImageFilter} is used here to smooth the image +// while preserving edges. +// +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet +#include "itkCurvatureFlowImageFilter.h" +// Software Guide : EndCodeSnippet + + +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" + + +int main( int argc, char *argv[] ) +{ + if( argc < 7 ) + { + std::cerr << "Missing Parameters " << std::endl; + std::cerr << "Usage: " << argv[0]; + std::cerr << " inputImage outputImage seedX seedY lowerThreshold upperThreshold" << std::endl; + return 1; + } + + + // Software Guide : BeginLatex + // + // We now define the image type using a particular pixel type and image + // dimension. In this case the \code{float} type is used for the pixels due + // to the requirements of the smoothing filter. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + typedef float InternalPixelType; + const unsigned int Dimension = 2; + typedef itk::Image< InternalPixelType, Dimension > InternalImageType; + // Software Guide : EndCodeSnippet + + //FIXME : OTBIMAGE + typedef unsigned char OutputPixelType; + typedef itk::Image< OutputPixelType, Dimension > OutputImageType; + + typedef itk::CastImageFilter< InternalImageType, OutputImageType > + CastingFilterType; + CastingFilterType::Pointer caster = CastingFilterType::New(); + + + // We instantiate reader and writer types + // + typedef otb::ImageFileReader< InternalImageType > ReaderType; + typedef otb::ImageFileWriter< OutputImageType > WriterType; + + ReaderType::Pointer reader = ReaderType::New(); + WriterType::Pointer writer = WriterType::New(); + + reader->SetFileName( argv[1] ); + writer->SetFileName( argv[2] ); + + + // Software Guide : BeginLatex + // + // The smoothing filter type is instantiated using the image type as + // a template parameter. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + typedef itk::CurvatureFlowImageFilter<InternalImageType, InternalImageType> + CurvatureFlowImageFilterType; + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // Then, the filter is created by invoking the \code{New()} method and + // assigning the result to a \doxygen{itk::SmartPointer}. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + CurvatureFlowImageFilterType::Pointer smoothing = + CurvatureFlowImageFilterType::New(); + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // We now declare the type of the region growing filter. In this case it is + // the NeighborhoodConnectedImageFilter. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + typedef itk::NeighborhoodConnectedImageFilter<InternalImageType, + InternalImageType > ConnectedFilterType; + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // One filter of this class is constructed using the \code{New()} method. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + ConnectedFilterType::Pointer neighborhoodConnected = ConnectedFilterType::New(); + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // Now it is time to create a simple, linear data processing pipeline. A + // file reader is added at the beginning of the pipeline and a cast + // filter and writer are added at the end. The cast filter is required + // to convert \code{float} pixel types to integer types since only a + // few image file formats support \code{float} types. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + smoothing->SetInput( reader->GetOutput() ); + neighborhoodConnected->SetInput( smoothing->GetOutput() ); + caster->SetInput( neighborhoodConnected->GetOutput() ); + writer->SetInput( caster->GetOutput() ); + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // The CurvatureFlowImageFilter requires a couple of parameters to + // be defined. The following are typical values for $2D$ images. However + // they may have to be adjusted depending on the amount of noise present in + // the input image. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + smoothing->SetNumberOfIterations( 5 ); + smoothing->SetTimeStep( 0.125 ); + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // The NeighborhoodConnectedImageFilter requires that two main parameters + // are specified. They are the lower and upper thresholds of the interval + // in which intensity values must fall to be included in the + // region. Setting these two values too close will not allow enough + // flexibility for the region to grow. Setting them too far apart will + // result in a region that engulfs the image. + // + // \index{itk::NeighborhoodConnectedImageFilter!SetLower()} + // \index{itk::NeighborhoodConnectedImageFilter!SetUppder()} + // + // Software Guide : EndLatex + + const InternalPixelType lowerThreshold = atof( argv[5] ); + const InternalPixelType upperThreshold = atof( argv[6] ); + + // Software Guide : BeginCodeSnippet + neighborhoodConnected->SetLower( lowerThreshold ); + neighborhoodConnected->SetUpper( upperThreshold ); + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // Here, we add the crucial parameter that defines the neighborhood size + // used to determine whether a pixel lies in the region. The larger the + // neighborhood, the more stable this filter will be against noise in the + // input image, but also the longer the computing time will be. Here we + // select a filter of radius $2$ along each dimension. This results in a + // neighborhood of $5 \times 5$ pixels. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + InternalImageType::SizeType radius; + + radius[0] = 2; // two pixels along X + radius[1] = 2; // two pixels along Y + + neighborhoodConnected->SetRadius( radius ); + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // As in the ConnectedThresholdImageFilter we must now provide the + // intensity value to be used for the output pixels accepted in the region + // and at least one seed point to define the initial region. + // + // \index{itk::NeighborhoodConnectedImageFilter!SetSeed()} + // \index{itk::NeighborhoodConnectedImageFilter!SetReplaceValue()} + // + // Software Guide : EndLatex + + InternalImageType::IndexType index; + + index[0] = atoi( argv[3] ); + index[1] = atoi( argv[4] ); + + + // Software Guide : BeginCodeSnippet + neighborhoodConnected->SetSeed( index ); + neighborhoodConnected->SetReplaceValue( 255 ); + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // The invocation of the \code{Update()} method on the writer triggers the + // execution of the pipeline. It is usually wise to put update calls in a + // \code{try/catch} block in case errors occur and exceptions are thrown. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + try + { + writer->Update(); + } + catch( itk::ExceptionObject & excep ) + { + std::cerr << "Exception caught !" << std::endl; + std::cerr << excep << std::endl; + } + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // Let's run this example using as input the image + // \code{QB\_Suburb.png} provided in the directory + // \code{Examples/Data}. We can easily segment the major + // structures by providing seeds in the appropriate locations and defining + // values for the lower and upper thresholds. + // Figure~\ref{fig:NeighborhoodConnectedThresholdOutput} illustrates several examples of + // segmentation. The parameters used are presented in + // Table~\ref{tab:NeighborhoodConnectedThresholdOutput}. + // + // \begin{table} + // \begin{center} + // \begin{tabular}{|l|c|c|c|c|} + // \hline + // Structure & Seed Index & Lower & Upper & Output Image \\ \hline + // Road & $(110,38)$ & 50 & 100 & Second from left in Figure \ref{fig:NeighborhoodConnectedThresholdOutput} \\ \hline + // Shadow & $(118,100)$ & 0 & 10 & Third from left in Figure \ref{fig:NeighborhoodConnectedThresholdOutput} \\ \hline + // Building & $(169,146)$ & 220 & 255 & Fourth from left in Figure \ref{fig:NeighborhoodConnectedThresholdOutput} \\ \hline + // \end{tabular} + // \end{center} + // \itkcaption[NeighborhoodConnectedThreshold example parameters]{Parameters used for + // segmenting some structures shown in + // Figure~\ref{fig:NeighborhoodConnectedThresholdOutput} with the filter + // \doxygen{itk::NeighborhoodConnectedThresholdImageFilter}.\label{tab:NeighborhoodConnectedThresholdOutput}} + // \end{table} + // + // \begin{figure} \center + // \includegraphics[width=0.24\textwidth]{QB_Suburb.eps} + // \includegraphics[width=0.24\textwidth]{NeighborhoodConnectedThresholdOutput1.eps} + // \includegraphics[width=0.24\textwidth]{NeighborhoodConnectedThresholdOutput2.eps} + // \includegraphics[width=0.24\textwidth]{NeighborhoodConnectedThresholdOutput3.eps} + // \itkcaption[NeighborhoodConnectedThreshold segmentation results]{Segmentation results + // for the NeighborhoodConnectedThreshold filter for various seed points.} + // \label{fig:NeighborhoodConnectedThresholdOutput} + // \end{figure} + // + // As with the ConnectedThresholdImageFilter, several seeds could + // be provided to the filter by using the \code{AddSeed()} method. + // Compare the output of Figure + // \ref{fig:NeighborhoodConnectedImageFilterOutput} with those of Figure + // \ref{fig:ConnectedThresholdOutput} produced by the + // ConnectedThresholdImageFilter. You may want to play with the + // value of the neighborhood radius and see how it affect the smoothness of + // the segmented object borders, the size of the segmented region and how + // much that costs in computing time. + // + // Software Guide : EndLatex + + return 0; +} + + + + diff --git a/Examples/Segmentation/OtsuMultipleThresholdImageFilter.cxx b/Examples/Segmentation/OtsuMultipleThresholdImageFilter.cxx new file mode 100755 index 0000000000000000000000000000000000000000..c347ea383c506b90f2c3609e9f6386fa7ccd4abe --- /dev/null +++ b/Examples/Segmentation/OtsuMultipleThresholdImageFilter.cxx @@ -0,0 +1,195 @@ + +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#ifdef __BORLANDC__ +#define ITK_LEAN_AND_MEAN +#endif + +// Software Guide : BeginCommandLineArgs +// INPUTS: {QB_Suburb.png} +// OUTPUTS: {OtsuMultipleThresholdsOutput000.png},{OtsuMultipleThresholdsOutput001.png}, {OtsuMultipleThresholdsOutput002.png} +// Software Guide : EndCommandLineArgs + +// Software Guide : BeginLatex +// This example illustrates how to use the \doxygen{itk::OtsuMultipleThresholdsCalculator}. +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet +#include "itkOtsuMultipleThresholdsCalculator.h" +// Software Guide : EndCodeSnippet + +#include "otbImage.h" +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" +#include "itkScalarImageToHistogramGenerator.h" +#include "itkBinaryThresholdImageFilter.h" +#include "itkNumericTraits.h" + +#include <stdio.h> +int main( int argc, char * argv[] ) +{ + if( argc < 2 ) + { + std::cerr << "Usage: " << argv[0]; + std::cerr << " inputImageFile outputImageFileName1 [OutputImageFilename2 ...] "; + return EXIT_FAILURE; + } + + //Convenience typedefs + typedef unsigned char InputPixelType; + typedef unsigned char OutputPixelType; + + typedef otb::Image< InputPixelType, 2 > InputImageType; + typedef otb::Image< OutputPixelType, 2 > OutputImageType; + + // Software Guide : BeginLatex + // OtsuMultipleThresholdsCalculator calculates thresholds for a give histogram + // so as to maximize the between-class variance. We use + // ScalarImageToHistogramGenerator to generate histograms + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + typedef itk::Statistics::ScalarImageToHistogramGenerator< InputImageType > + ScalarImageToHistogramGeneratorType; + typedef itk::OtsuMultipleThresholdsCalculator< + ScalarImageToHistogramGeneratorType::HistogramType > CalculatorType; + // Software Guide : EndCodeSnippet + + typedef otb::ImageFileReader< InputImageType > ReaderType; + typedef otb::ImageFileWriter< InputImageType > WriterType; + + // Software Guide : BeginLatex + // Once thresholds are computed we will use BinaryThresholdImageFilter to + // segment the input image into segments. + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + typedef itk::BinaryThresholdImageFilter< InputImageType, OutputImageType > + FilterType; + // Software Guide : EndCodeSnippet + + //Create using static New() method + + // Software Guide : BeginCodeSnippet + ScalarImageToHistogramGeneratorType::Pointer scalarImageToHistogramGenerator = + ScalarImageToHistogramGeneratorType::New(); + CalculatorType::Pointer calculator = CalculatorType::New(); + FilterType::Pointer filter = FilterType::New(); + // Software Guide : EndCodeSnippet + + ReaderType::Pointer reader = ReaderType::New(); + WriterType::Pointer writer = WriterType::New(); + + //Set Properties + + // Software Guide : BeginCodeSnippet + scalarImageToHistogramGenerator->SetNumberOfBins(128); + int nbThresholds = argc-2; + calculator->SetNumberOfThresholds( nbThresholds ); + // Software Guide : EndCodeSnippet + + const OutputPixelType outsideValue = 0; + const OutputPixelType insideValue = 255; + filter->SetOutsideValue( outsideValue ); + filter->SetInsideValue( insideValue ); + + //Connect Pipeline + reader->SetFileName( argv[1] ); + + // Software Guide : BeginLatex + // The pipeline will look as follows: + // Software Guide : EndLatex + // Software Guide : BeginCodeSnippet + scalarImageToHistogramGenerator->SetInput(reader->GetOutput()); + calculator->SetInputHistogram(scalarImageToHistogramGenerator->GetOutput()); + filter->SetInput( reader->GetOutput() ); + writer->SetInput(filter->GetOutput()); + // Software Guide : EndCodeSnippet + + + //Invoke pipeline + try + { reader->Update(); } + catch( itk::ExceptionObject & excp ) + { + std::cerr << "Exception thrown while reading image" << excp << std::endl; + } + scalarImageToHistogramGenerator->Compute(); + + try + { calculator->Update(); } + catch( itk::ExceptionObject & excp ) + { + std::cerr << "Exception thrown " << excp << std::endl; + } + + // Software Guide : BeginLatex + // Thresholds are obtained using the \code{GetOutput} method + // \index{itk::OtsuMultipleThresholdsCalculator!GetOutput()} + // Software Guide : EndLatex + //Get Thresholds + // Software Guide : BeginCodeSnippet + const CalculatorType::OutputType &thresholdVector = calculator->GetOutput(); + CalculatorType::OutputType::const_iterator itNum = thresholdVector.begin(); + // Software Guide : EndCodeSnippet + + //Threshold into seperate segments and write out as binary images + double lowerThreshold = 0; + double upperThreshold; + + unsigned int counter = 0; + // Software Guide : BeginCodeSnippet + for(; itNum < thresholdVector.end(); itNum++) + { + std::cout << "OtsuThreshold[" + << (int)(itNum - thresholdVector.begin()) + << "] = " << + static_cast<itk::NumericTraits<CalculatorType::MeasurementType>::PrintType> + (*itNum) << std::endl; + // Software Guide : EndCodeSnippet + + upperThreshold = (*itNum); + filter->SetLowerThreshold( static_cast<OutputPixelType> (lowerThreshold) ); + filter->SetUpperThreshold( static_cast<OutputPixelType> (upperThreshold) ); + lowerThreshold = upperThreshold; + + + writer->SetFileName( argv[2+counter] ); + ++counter; + try + { writer->Update(); } + catch( itk::ExceptionObject & excp ) + { + std::cerr << "Exception thrown " << excp << std::endl; + } + // Software Guide : BeginCodeSnippet + } + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // \begin{figure} + // \center + // \includegraphics[width=0.44\textwidth]{QB_Suburb.eps} + // \includegraphics[width=0.44\textwidth]{OtsuMultipleThresholdsOutput000.eps} + // \includegraphics[width=0.44\textwidth]{OtsuMultipleThresholdsOutput001.eps} + // \includegraphics[width=0.44\textwidth]{OtsuMultipleThresholdsOutput002.eps} + // \itkcaption[OtsuThresholdImageFilter output]{Effect of the OtsuMultipleThresholdImageFilter.} + // \label{fig:OtsuMultipleThresholdImageFilterInputOutput} + // \end{figure} + // + // Figure \ref{fig:OtsuMultipleThresholdImageFilterInputOutput} illustrates the + // effect of this filter. + // + // \relatedClasses + // \begin{itemize} + // \item \doxygen{itk::ThresholdImageFilter} + // \end{itemize} + // + // Software Guide : EndLatex + + return EXIT_SUCCESS; +} + diff --git a/Examples/Segmentation/OtsuThresholdImageFilter.cxx b/Examples/Segmentation/OtsuThresholdImageFilter.cxx new file mode 100755 index 0000000000000000000000000000000000000000..70819639315caad4cf75f1ae2ce69fe838e52b72 --- /dev/null +++ b/Examples/Segmentation/OtsuThresholdImageFilter.cxx @@ -0,0 +1,231 @@ +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#ifdef __BORLANDC__ +#define ITK_LEAN_AND_MEAN +#endif + +// Software Guide : BeginCommandLineArgs +// INPUTS: {QB_Suburb.png} +// OUTPUTS: {OtsuThresholdImageFilterOutput.png} +// 255 0 +// Software Guide : EndCommandLineArgs + +// Software Guide : BeginLatex +// +// This example illustrates how to use the \doxygen{itk::OtsuThresholdImageFilter}. +// +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet +#include "itkOtsuThresholdImageFilter.h" +// Software Guide : EndCodeSnippet + +#include "otbImage.h" +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" + +int main( int argc, char * argv[] ) +{ + if( argc < 5 ) + { + std::cerr << "Usage: " << argv[0]; + std::cerr << " inputImageFile outputImageFile "; + std::cerr << " insideValue outsideValue " << std::endl; + return EXIT_FAILURE; + } + + // Software Guide : BeginLatex + // + // The next step is to decide which pixel types to use for the input and output + // images. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + typedef unsigned char InputPixelType; + typedef unsigned char OutputPixelType; + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // The input and output image types are now defined using their respective + // pixel types and dimensions. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + typedef itk::Image< InputPixelType, 2 > InputImageType; + typedef itk::Image< OutputPixelType, 2 > OutputImageType; + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // The filter type can be instantiated using the input and output image + // types defined above. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + typedef itk::OtsuThresholdImageFilter< + InputImageType, OutputImageType > FilterType; + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // An \doxygen{otb::ImageFileReader} class is also instantiated in order to read + // image data from a file. (See Section \ref{sec:IO} on page + // \pageref{sec:IO} for more information about reading + // and writing data.) + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + typedef otb::ImageFileReader< InputImageType > ReaderType; + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // An \doxygen{otb::ImageFileWriter} is instantiated in order to write the output + // image to a file. + // + // Software Guide : EndLatex + + + // Software Guide : BeginCodeSnippet + typedef otb::ImageFileWriter< InputImageType > WriterType; + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // Both the filter and the reader are created by invoking their \code{New()} + // methods and assigning the result to \doxygen{SmartPointer}s. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + ReaderType::Pointer reader = ReaderType::New(); + FilterType::Pointer filter = FilterType::New(); + // Software Guide : EndCodeSnippet + + WriterType::Pointer writer = WriterType::New(); + writer->SetInput( filter->GetOutput() ); + reader->SetFileName( argv[1] ); + + + // Software Guide : BeginLatex + // + // The image obtained with the reader is passed as input to the + // OtsuThresholdImageFilter. + // + // \index{itk::Otsu\-Threshold\-Image\-Filter!SetInput()} + // \index{otb::FileImageReader!GetOutput()} + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + filter->SetInput( reader->GetOutput() ); + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // The method \code{SetOutsideValue()} defines the intensity value to be + // assigned to those pixels whose intensities are outside the range defined + // by the lower and upper thresholds. The method \code{SetInsideValue()} + // defines the intensity value to be assigned to pixels with intensities + // falling inside the threshold range. + // + // \index{itk::Otsu\-Threshold\-Image\-Filter!SetOutsideValue()} + // \index{itk::Otsu\-Threshold\-Image\-Filter!SetInsideValue()} + // \index{SetOutsideValue()!itk::Otsu\-Threshold\-Image\-Filter} + // \index{SetInsideValue()!itk::Otsu\-Threshold\-Image\-Filter} + // + // Software Guide : EndLatex + + const OutputPixelType outsideValue = atoi( argv[3] ); + const OutputPixelType insideValue = atoi( argv[4] ); + + // Software Guide : BeginCodeSnippet + filter->SetOutsideValue( outsideValue ); + filter->SetInsideValue( insideValue ); + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // The method \code{SetNumberOfHistogramBins()} defines the number of bins + // to be used for computing the histogram. This histogram will be used + // internally in order to compute the Otsu threshold. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + filter->SetNumberOfHistogramBins( 128 ); + // Software Guide : EndCodeSnippet + + + // Software Guide : BeginLatex + // + // The execution of the filter is triggered by invoking the \code{Update()} + // method. If the filter's output has been passed as input to subsequent + // filters, the \code{Update()} call on any posterior filters in the + // pipeline will indirectly trigger the update of this filter. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + filter->Update(); + // Software Guide : EndCodeSnippet + + + + // Software Guide : BeginLatex + // + // We print out here the Threshold value that was computed internally by the + // filter. For this we invoke the \code{GetThreshold} method. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + int threshold = filter->GetThreshold(); + std::cout << "Threshold = " << threshold << std::endl; + // Software Guide : EndCodeSnippet + + + + // Software Guide : BeginLatex + // + // \begin{figure} + // \center + // \includegraphics[width=0.44\textwidth]{QB_Suburb.eps} + // \includegraphics[width=0.44\textwidth]{OtsuThresholdImageFilterOutput.eps} + // \itkcaption[OtsuThresholdImageFilter output]{Effect of the OtsuThresholdImageFilter.} + // \label{fig:OtsuThresholdImageFilterInputOutput} + // \end{figure} + // + // Figure \ref{fig:OtsuThresholdImageFilterInputOutput} illustrates the + // effect of this filter. This + // figure shows the limitations of this filter for performing segmentation + // by itself. These limitations are particularly noticeable in noisy images + // and in images lacking spatial uniformity. + // + // \relatedClasses + // \begin{itemize} + // \item \doxygen{itk::ThresholdImageFilter} + // \end{itemize} + // + // Software Guide : EndLatex + + writer->SetFileName( argv[2] ); + writer->Update(); + + return EXIT_SUCCESS; +} +