KullbackLeiblerProfileChDet.cxxΒΆ
Example usage:
./KullbackLeiblerProfileChDet Input/GomaAvant.png Input/GomaApres.png Output/KLProfileChDet.png 5 51 1 12 24
Example source code (KullbackLeiblerProfileChDet.cxx):
// This example illustrates the class
// \doxygen{otb}{KullbackLeiblerProfileImageFilter} for detecting changes
// between pairs of images, according to a range of window size.
// This example is very similar, in its principle, to all of the change
// detection examples, especially the distance between distributions one
// (section~\ref{sec:KullbackLeiblerDistance}) which uses a fixed window size.
//
// The main differences are:
// \begin{enumerate}
// \item a set of window range instead of a fixed size of window;
// \item an output of type \doxygen{otb}{VectorImage}.
// \end{enumerate}
// Then, the program begins with the \doxygen{otb}{VectorImage} and the
// \doxygen{otb}{KullbackLeiblerProfileImageFilter} header files in addition
// to those already details in the \doxygen{otb}{MeanRatioImageFilter} example.
#include "otbImage.h"
#include "otbMultiChannelExtractROI.h"
#include "otbVectorRescaleIntensityImageFilter.h"
#include "otbKullbackLeiblerProfileImageFilter.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
int main(int argc, char* argv[])
{
try
{
if (argc != 9)
{
std::cerr << "Change detection based on Kullback-Leibler distance betweenlocal pdf through an Edgeworth approximation\n";
std::cerr << argv[0] << " imgAv imgAp imgResu winSizeMin winSizeMax outRedIndex outGreenIndex outBlueIndex\n";
return 1;
}
char* fileName1 = argv[1];
char* fileName2 = argv[2];
char* fileNameOut = argv[3];
int winSizeMin = atoi(argv[4]);
int winSizeMax = atoi(argv[5]);
unsigned int ri = atoi(argv[6]);
unsigned int gi = atoi(argv[7]);
unsigned int bi = atoi(argv[8]);
const unsigned int Dimension = 2;
typedef double PixelType;
typedef unsigned char OutPixelType;
// The \doxygen{otb}{KullbackLeiblerProfileImageFilter} is templated over
// the types of the two input images and the type of the generated change
// image (which is now of multi-components), in a similar way as the
// \doxygen{otb}{KullbackLeiblerDistanceImageFilter}.
typedef otb::Image<PixelType, Dimension> ImageType;
typedef otb::VectorImage<PixelType, Dimension> VectorImageType;
typedef otb::KullbackLeiblerProfileImageFilter<ImageType, ImageType, VectorImageType> FilterType;
typedef otb::VectorImage<OutPixelType, Dimension> OutVectorImageType;
typedef otb::ImageFileReader<ImageType> ReaderType;
typedef otb::ImageFileWriter<OutVectorImageType> WriterType;
typedef otb::MultiChannelExtractROI<PixelType, PixelType> ChannelSelecterType;
typedef otb::VectorRescaleIntensityImageFilter<VectorImageType, OutVectorImageType> RescalerType;
ReaderType::Pointer reader1 = ReaderType::New();
reader1->SetFileName(fileName1);
ReaderType::Pointer reader2 = ReaderType::New();
reader2->SetFileName(fileName2);
// The different elements of the pipeline can now be instantiated in the
// same way as the ratio of means change detector example.
//
// Two parameters are now required to give the minimum and the maximum size
// of the analysis window. The program will begin by performing change
// detection through the smaller window size and then applying moments update
// of eq.~\eqref{eqMomentN} by incrementing the radius of the analysis window
// (i.e. add a ring of width 1 pixel around the current neightborhood shape).
// The process is applied until the larger window size is reached.
//
FilterType::Pointer filter = FilterType::New();
filter->SetRadius((winSizeMin - 1) / 2, (winSizeMax - 1) / 2);
filter->SetInput1(reader1->GetOutput());
filter->SetInput2(reader2->GetOutput());
ChannelSelecterType::Pointer channelSelecter = ChannelSelecterType::New();
channelSelecter->SetInput(filter->GetOutput());
channelSelecter->SetChannel(ri);
channelSelecter->SetChannel(gi);
channelSelecter->SetChannel(bi);
RescalerType::Pointer rescaler = RescalerType::New();
rescaler->SetInput(channelSelecter->GetOutput());
OutVectorImageType::PixelType min, max;
min.SetSize(3);
max.SetSize(3);
min.Fill(0);
max.Fill(255);
rescaler->SetOutputMinimum(min);
rescaler->SetOutputMaximum(max);
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(fileNameOut);
writer->SetInput(rescaler->GetOutput());
writer->Update();
// Figure \ref{fig:RESKLPCHDET} shows the result of the change
// detection by computing the Kullback-Leibler distance between
// local pdf through an Edgeworth approximation.
// \begin{figure}
// \center
// \includegraphics[width=0.35\textwidth]{KLProfileChDet.eps}
// \itkcaption[Kullback-Leibler profile Change Detection Results]{Result of the
// Kullback-Leibler profile change detector, colored composition including the first, 12th and 24th
// channel of the generated output.}
// \label{fig:RESKLPCHDET}
// \end{figure}
}
catch (itk::ExceptionObject& err)
{
std::cout << "Exception itk::ExceptionObject thrown !" << std::endl;
std::cout << err << std::endl;
return EXIT_FAILURE;
}
catch (...)
{
std::cout << "Unknown exception thrown !" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}