ITK  6.0.0
Insight Toolkit
Examples/Segmentation/VectorConfidenceConnected.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
*
* 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: {VisibleWomanEyeSlice.png}
// OUTPUTS: {VectorConfidenceConnectedOutput1.png}
// ARGUMENTS: 70 120 7 1
// Software Guide : EndCommandLineArgs
// Software Guide : BeginCommandLineArgs
// INPUTS: {VisibleWomanEyeSlice.png}
// OUTPUTS: {VectorConfidenceConnectedOutput2.png}
// ARGUMENTS: 23 93 7 1
// Software Guide : EndCommandLineArgs
// Software Guide : BeginCommandLineArgs
// INPUTS: {VisibleWomanEyeSlice.png}
// OUTPUTS: {VectorConfidenceConnectedOutput3.png}
// ARGUMENTS: 66 66 3 1
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
//
// This example illustrates the use of the confidence connected concept
// applied to images with vector pixel types. The confidence connected
// algorithm is implemented for vector images in the class
// \doxygen{VectorConfidenceConnected}. The basic difference between the
// scalar and vector version is that the vector version uses the covariance
// matrix instead of a variance, and a vector mean instead of a scalar mean.
// The membership of a vector pixel value to the region is measured using the
// Mahalanobis distance as implemented in the class
// \subdoxygen{Statistics}{MahalanobisDistanceThresholdImageFunction}.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// Software Guide : EndCodeSnippet
#include "itkImage.h"
#include "itkRGBPixel.h"
int
main(int argc, char * argv[])
{
if (argc < 7)
{
std::cerr << "Missing Parameters " << std::endl;
std::cerr << "Usage: " << argv[0] << " inputImage outputImage"
<< " seedX seedY"
<< " multiplier iterations" << std::endl;
return EXIT_FAILURE;
}
// Software Guide : BeginLatex
//
// We now define the image type using a particular pixel type and
// 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
constexpr unsigned int Dimension = 2;
using PixelComponentType = unsigned char;
using InputPixelType = itk::RGBPixel<PixelComponentType>;
using InputImageType = itk::Image<InputPixelType, Dimension>;
// Software Guide : EndCodeSnippet
using OutputPixelType = unsigned char;
using OutputImageType = itk::Image<OutputPixelType, Dimension>;
// We instantiate reader and writer types
//
auto reader = ReaderType::New();
auto writer = WriterType::New();
reader->SetFileName(argv[1]);
writer->SetFileName(argv[2]);
// Software Guide : BeginLatex
//
// We now declare the type of the region-growing filter. In this case it
// is the \doxygen{VectorConfidenceConnectedImageFilter}.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
using ConnectedFilterType =
OutputImageType>;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Then, we construct one filter of this class using the \code{New()}
// method.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
auto confidenceConnected = ConnectedFilterType::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Next we create a simple, linear data processing pipeline.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
confidenceConnected->SetInput(reader->GetOutput());
writer->SetInput(confidenceConnected->GetOutput());
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// \code{VectorConfidenceConnectedImageFilter} requires two
// parameters. First, the multiplier factor $f$ defines how large the
// range of intensities will be. Small values of the multiplier will
// restrict the inclusion of pixels to those having similar intensities to
// those already in the current region. Larger values of the multiplier
// relax the accepting condition and result in more generous growth of the
// region. Values that are too large will cause the region to grow into
// neighboring regions which may actually belong to separate anatomical
// structures.
//
// \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetMultiplier()}
//
// Software Guide : EndLatex
const double multiplier = std::stod(argv[5]);
// Software Guide : BeginCodeSnippet
confidenceConnected->SetMultiplier(multiplier);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The number of iterations is typically determined based on the
// homogeneity of the image intensity representing the anatomical
// structure to be segmented. Highly homogeneous regions may only require
// a couple of iterations. Regions with ramp effects, like MRI images with
// inhomogeneous fields, may require more iterations. In practice, it seems
// to be more relevant to carefully select the multiplier factor than the
// number of iterations. However, keep in mind that there is no reason to
// assume that this algorithm should converge to a stable region. It is
// possible that by letting the algorithm run for more iterations the
// region will end up engulfing the entire image.
//
// \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetNumberOfIterations()}
//
// Software Guide : EndLatex
const unsigned int iterations = std::stoi(argv[6]);
// Software Guide : BeginCodeSnippet
confidenceConnected->SetNumberOfIterations(iterations);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The output of this filter is a binary image with zero-value pixels
// everywhere except on the extracted region. The intensity value to be
// put inside the region is selected with the method
// \code{SetReplaceValue()}.
//
// \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetReplaceValue()}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
confidenceConnected->SetReplaceValue(255);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The initialization of the algorithm requires the user to provide a seed
// point. This point should be placed in a \emph{typical} region of the
// anatomical structure to be segmented. A small neighborhood around the
// seed point will be used to compute the initial mean and standard
// deviation for the inclusion criterion. The seed is passed in the form
// of an \doxygen{Index} to the \code{SetSeed()} method.
//
// \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetSeed()}
// \index{itk::Vector\-Confidence\-Connected\-Image\-Filter!SetInitialNeighborhoodRadius()}
//
// Software Guide : EndLatex
index[0] = std::stoi(argv[3]);
index[1] = std::stoi(argv[4]);
// Software Guide : BeginCodeSnippet
confidenceConnected->SetSeed(index);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The size of the initial neighborhood around the seed is defined with the
// method \code{SetInitialNeighborhoodRadius()}. The neighborhood will be
// defined as an $N$-Dimensional rectangular region with $2r+1$ pixels on
// the side, where $r$ is the value passed as initial neighborhood radius.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
confidenceConnected->SetInitialNeighborhoodRadius(3);
// 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 (const itk::ExceptionObject & excep)
{
std::cerr << "Exception caught !" << std::endl;
std::cerr << excep << std::endl;
}
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Now let's run this example using as input the image
// \code{VisibleWomanEyeSlice.png} provided in the directory
// \code{Examples/Data}. We can easily segment the major anatomical
// structures by providing seeds in the appropriate locations. For example,
//
// \begin{center}
// \begin{tabular}{|l|c|c|c|c|}
// \hline
// Structure & Seed Index & Multiplier & Iterations
// & Output Image \\ \hline
// Rectum & $(70,120)$ & 7 & 1 & Second from left in Figure
// \ref{fig:VectorConfidenceConnectedOutput} \\ \hline Rectum & $(23, 93)$
// & 7 & 1 & Third from left in Figure
// \ref{fig:VectorConfidenceConnectedOutput} \\ \hline Vitreo & $(66, 66)$
// & 3 & 1 & Fourth from left in Figure
// \ref{fig:VectorConfidenceConnectedOutput} \\ \hline \end{tabular}
// \end{center}
//
// \begin{figure} \center
// \includegraphics[width=0.24\textwidth]{VisibleWomanEyeSlice}
// \includegraphics[width=0.24\textwidth]{VectorConfidenceConnectedOutput1}
// \includegraphics[width=0.24\textwidth]{VectorConfidenceConnectedOutput2}
// \includegraphics[width=0.24\textwidth]{VectorConfidenceConnectedOutput3}
// \itkcaption[VectorConfidenceConnected segmentation results]{Segmentation
// results of the VectorConfidenceConnected filter for various seed
// points.} \label{fig:VectorConfidenceConnectedOutput} \end{figure}
//
// The coloration of muscular tissue makes it easy to distinguish them from
// the surrounding anatomical structures. The optic vitrea on the other
// hand has a coloration that is not very homogeneous inside the eyeball
// and does not facilitate a full segmentation based only on color.
//
// Software Guide : EndLatex
// Software Guide : BeginLatex
//
// The values of the final mean vector and covariance matrix used for the
// last iteration can be queried using the methods \code{GetMean()} and
// \code{GetCovariance()}.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
using MeanVectorType = ConnectedFilterType::MeanVectorType;
using CovarianceMatrixType = ConnectedFilterType::CovarianceMatrixType;
const MeanVectorType & mean = confidenceConnected->GetMean();
const CovarianceMatrixType & covariance =
confidenceConnected->GetCovariance();
std::cout << "Mean vector = " << mean << std::endl;
std::cout << "Covariance matrix = " << covariance << std::endl;
// Software Guide : EndCodeSnippet
return EXIT_SUCCESS;
}
itk::RGBPixel
Represent Red, Green and Blue components for color images.
Definition: itkRGBPixel.h:58
itkRGBPixel.h
itkImageFileReader.h
itkImage.h
itk::ImageFileReader
Data source that reads image data from a single file.
Definition: itkImageFileReader.h:75
itk::GTest::TypedefsAndConstructors::Dimension2::IndexType
ImageBaseType::IndexType IndexType
Definition: itkGTestTypedefsAndConstructors.h:50
itkVectorConfidenceConnectedImageFilter.h
itk::VectorConfidenceConnectedImageFilter
Segment pixels with similar statistics using connectivity.
Definition: itkVectorConfidenceConnectedImageFilter.h:60
itk::ImageFileWriter
Writes image data to a single file.
Definition: itkImageFileWriter.h:90
itkImageFileWriter.h
itk::Image
Templated n-dimensional image class.
Definition: itkImage.h:88
New
static Pointer New()
itk::GTest::TypedefsAndConstructors::Dimension2::Dimension
constexpr unsigned int Dimension
Definition: itkGTestTypedefsAndConstructors.h:44