Skip to content
Snippets Groups Projects
Commit f042d91f authored by Cyrille Valladeau's avatar Cyrille Valladeau
Browse files

Example Markov.

parent 000ab8ec
Branches
Tags
No related merge requests found
...@@ -3,11 +3,11 @@ INCLUDE_REGULAR_EXPRESSION("^.*$") ...@@ -3,11 +3,11 @@ INCLUDE_REGULAR_EXPRESSION("^.*$")
SET(Markov_EXAMPLES ${CXX_TEST_PATH}/otbMarkovExamplesTests) SET(Markov_EXAMPLES ${CXX_TEST_PATH}/otbMarkovExamplesTests)
ADD_EXECUTABLE(MarkovClassification1Example MarkovClassification1Example.cxx ) ADD_EXECUTABLE(MarkovRandomField1Example MarkovRandomField1Example.cxx )
TARGET_LINK_LIBRARIES(MarkovClassification1Example OTBMarkov OTBCommon OTBIO ITKNumerics ITKIO) TARGET_LINK_LIBRARIES(MarkovRandomField1Example OTBMarkov OTBCommon OTBIO ITKNumerics ITKIO)
ADD_EXECUTABLE(MarkovClassification2Example MarkovClassification2Example.cxx ) ADD_EXECUTABLE(MarkovRandomField2Example MarkovRandomField2Example.cxx )
TARGET_LINK_LIBRARIES(MarkovClassification2Example OTBMarkov OTBCommon OTBIO ITKNumerics ITKIO) TARGET_LINK_LIBRARIES(MarkovRandomField2Example OTBMarkov OTBCommon OTBIO ITKNumerics ITKIO)
ADD_EXECUTABLE(MarkovRestaurationExample MarkovRestaurationExample.cxx ) ADD_EXECUTABLE(MarkovRestaurationExample MarkovRestaurationExample.cxx )
TARGET_LINK_LIBRARIES(MarkovRestaurationExample OTBMarkov OTBCommon OTBIO ITKNumerics ITKIO) TARGET_LINK_LIBRARIES(MarkovRestaurationExample OTBMarkov OTBCommon OTBIO ITKNumerics ITKIO)
...@@ -27,25 +27,25 @@ SET(EXE_TESTS ${CXX_TEST_PATH}/otbMarkovExamplesTests) ...@@ -27,25 +27,25 @@ SET(EXE_TESTS ${CXX_TEST_PATH}/otbMarkovExamplesTests)
SET(TOL 0.0) SET(TOL 0.0)
SET(EPSILON 0.00000001) SET(EPSILON 0.00000001)
ADD_TEST(MarkovClassification1ExampleTest ${EXE_TESTS} ADD_TEST(MarkovRandomField1ExampleTest ${EXE_TESTS}
--compare-image ${EPSILON} --compare-image ${EPSILON}
${BASELINE}/MarkovClassification1.png ${BASELINE}/MarkovRandomField1.png
${TEMP}/MarkovClassification1.png ${TEMP}/MarkovRandomField1.png
MarkovClassification1ExampleTest MarkovRandomField1ExampleTest
${INPUTDATA}/QB_Suburb.png ${INPUTDATA}/QB_Suburb.png
${TEMP}/MarkovClassification1.png ${TEMP}/MarkovRandomField1.png
1.0 1.0
20 20
1.0 1.0
) )
ADD_TEST(MarkovClassification2ExampleTest ${EXE_TESTS} ADD_TEST(MarkovRandomField2ExampleTest ${EXE_TESTS}
--compare-image ${EPSILON} --compare-image ${EPSILON}
${BASELINE}/MarkovClassification2.png ${BASELINE}/MarkovRandomField2.png
${TEMP}/MarkovClassification2.png ${TEMP}/MarkovRandomField2.png
MarkovClassification2ExampleTest MarkovRandomField2ExampleTest
${INPUTDATA}/QB_Suburb.png ${INPUTDATA}/QB_Suburb.png
${TEMP}/MarkovClassification2.png ${TEMP}/MarkovRandomField2.png
1.0 1.0
5 5
) )
......
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt 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: {QB_Suburb.png}
// OUTPUTS: {MarkovClassification1.png}
// 1.0 20 1.0
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
//
// This example illustrates the details of the \doxygen{otb}{MarkovRandomFieldFilter}.
// This filter is an application of the Markov Random Fields for classification,
// segmentation or restauration.
//
// This example applies the \doxygen{otb}{MarkovRandomFieldFilter} to
// classify an image into four classes defined by their mean and variance. The
// optimization is done using an Metropolis algorithm with a random sampler. The
// regularization energy is defined by a Potts model and the fidelity by a
// Gaussian model.
//
//
// Software Guide : EndLatex
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbImage.h"
#include "otbMarkovRandomFieldFilter.h"
#include "itkRescaleIntensityImageFilter.h"
// Software Guide : BeginLatex
//
// The first step toward the use of this filter is the inclusion of the proper
// header files.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
#include "otbMRFEnergyPotts.h"
#include "otbMRFEnergyGaussianClassification.h"
#include "otbMRFOptimizerMetropolis.h"
#include "otbMRFSamplerRandom.h"
// Software Guide : EndCodeSnippet
int main(int argc, char* argv[] )
{
if( argc != 6 )
{
std::cerr << "Missing Parameters "<< argc << std::endl;
std::cerr << "Missing Parameters " << std::endl;
std::cerr << "Usage: " << argv[0];
std::cerr << " inputImage output lambda iterations optimizerTemperature" << std::endl;
return 1;
}
// Software Guide : BeginLatex
//
// Then we must decide what pixel type to use for the image. We
// choose to make all computations with double precision.
// The labelled image is of type unsigned char which allows up to 256 different
// classes.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
const unsigned int Dimension = 2;
typedef double InternalPixelType;
typedef unsigned char LabelledPixelType;
typedef otb::Image<InternalPixelType, Dimension> InputImageType;
typedef otb::Image<LabelledPixelType, Dimension> LabelledImageType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We define a reader for the image to be classified, an initialisation for the
// classification (which could be random) and a writer for the final
// classification.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::ImageFileReader< InputImageType > ReaderType;
typedef otb::ImageFileWriter< LabelledImageType > WriterType;
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer = WriterType::New();
const char * inputFilename = argv[1];
const char * outputFilename = argv[2];
reader->SetFileName( inputFilename );
writer->SetFileName( outputFilename );
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Finally, we define the different classes necessary for the Markov classification.
// A \doxygen{otb}{MarkovRandomFieldFilter} is instanciated, this is the
// main class which connect the other to do the Markov classification.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::MarkovRandomFieldFilter
<InputImageType,LabelledImageType> MarkovRandomFieldFilterType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// An \doxygen{otb}{MRFSamplerRandomMAP}, which derives from the
// \doxygen{otb}{MRFSampler}, is instanciated. The sampler is in charge of
// proposing a modification for a given site. The
// \doxygen{otb}{MRFSamplerRandomMAP}, randomly pick one possible value
// according to the MAP probability.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::MRFSamplerRandom< InputImageType, LabelledImageType> SamplerType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// An \doxygen{otb}{MRFOptimizerMetropoli}, which derives from the
// \doxygen{otb}{MRFOptimizer}, is instanciated. The optimizer is in charge
// of accepting or rejecting the value proposed by the sampler. The
// \doxygen{otb}{MRFSamplerRandomMAP}, accept the proposal according to the
// variation of energy it causes and a temperature parameter.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::MRFOptimizerMetropolis OptimizerType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Two energy, deriving from the \doxygen{otb}{MRFEnergy} class need to be instanciated. One energy
// is required for the regularization, taking into account the relashionship between neighborhing pixels
// in the classified image. Here it is done with the \doxygen{otb}{MRFEnergyPotts} which implement
// a Potts model.
//
// The second energy is for the fidelity to the original data. Here it is done with an
// \doxygen{otb}{MRFEnergyGaussianClassification} class, which defines a gaussian model for the data.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::MRFEnergyPotts
<LabelledImageType, LabelledImageType> EnergyRegularizationType;
typedef otb::MRFEnergyGaussianClassification
<InputImageType, LabelledImageType> EnergyFidelityType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The different filters composing our pipeline are created by invoking their
// \code{New()} methods, assigning the results to smart pointers.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
MarkovRandomFieldFilterType::Pointer markovFilter = MarkovRandomFieldFilterType::New();
EnergyRegularizationType::Pointer energyRegularization = EnergyRegularizationType::New();
EnergyFidelityType::Pointer energyFidelity = EnergyFidelityType::New();
OptimizerType::Pointer optimizer = OptimizerType::New();
SamplerType::Pointer sampler = SamplerType::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Parameter for the \doxygen{otb}{MRFEnergyGaussianClassification} class, meand
// and standard deviation are created.
//
// Software Guide : EndLatex
// Overpass random calculation(for test only):
sampler->InitializeSeed(0);
optimizer->InitializeSeed(0);
markovFilter->InitializeSeed(0);
// Software Guide : BeginCodeSnippet
unsigned int nClass = 4;
energyFidelity->SetNumberOfParameters(2*nClass);
EnergyFidelityType::ParametersType parameters;
parameters.SetSize(energyFidelity->GetNumberOfParameters());
parameters[0]=10.0; //Class 0 mean
parameters[1]=10.0; //Class 0 stdev
parameters[2]=80.0;//Class 1 mean
parameters[3]=10.0; //Class 1 stdev
parameters[4]=150.0; //Class 2 mean
parameters[5]=10.0; //Class 2 stdev
parameters[6]=220.0;//Class 3 mean
parameters[7]=10.0; //Class 3 stde
energyFidelity->SetParameters(parameters);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Parameters are given to the different class an the sampler, optimizer and
// energies are connected with the Markov filter.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
OptimizerType::ParametersType param(1);
param.Fill(atof(argv[5]));
optimizer->SetParameters(param);
markovFilter->SetNumberOfClasses(nClass);
markovFilter->SetMaximumNumberOfIterations(atoi(argv[4]));
markovFilter->SetErrorTolerance(0.0);
markovFilter->SetLambda(atof(argv[3]));
markovFilter->SetNeighborhoodRadius(1);
markovFilter->SetEnergyRegularization(energyRegularization);
markovFilter->SetEnergyFidelity(energyFidelity);
markovFilter->SetOptimizer(optimizer);
markovFilter->SetSampler(sampler);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The pipeline is connected. An \doxygen{itk}{RescaleIntensityImageFilter}
// rescale the classified image before saving it.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
markovFilter->SetInput(reader->GetOutput());
typedef itk::RescaleIntensityImageFilter
< LabelledImageType, LabelledImageType > RescaleType;
RescaleType::Pointer rescaleFilter = RescaleType::New();
rescaleFilter->SetOutputMinimum(0);
rescaleFilter->SetOutputMaximum(255);
rescaleFilter->SetInput( markovFilter->GetOutput() );
writer->SetInput( rescaleFilter->GetOutput() );
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Finally, the pipeline execution is trigerred.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
writer->Update();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Figure~\ref{fig:MRF_CLASSIFICATION1} shows the output of the Markov Random
// Field classification after 20 iterations with a
// random sampler and a Metropolis optimizer.
//
// \begin{figure}
// \center
// \includegraphics[width=0.44\textwidth]{QB_Suburb.eps}
// \includegraphics[width=0.44\textwidth]{MarkovClassification1.eps}
// \itkcaption[MRF restauration]{Result of applying
// the \doxygen{otb}{MarkovRandomFieldFilter} to an extract from a PAN Quickbird
// image for classification. The result is obtained after 20 iterations with a
// random sampler and a Metropolis optimizer. From left to right : original image,
// classification.}
// \label{fig:MRF_CLASSIFICATION1}
// \end{figure}
//
// Software Guide : EndLatex
return EXIT_SUCCESS;
}
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt 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: {QB_Suburb.png}
// OUTPUTS: {MarkovClassification1.png}
// 1.0 5
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
//
// Using a similar structure as the previous program and the same energy
// function, we are now going to slightly alter the program to use a
// different sampler and optimizer. The proposed sample is proposed
// randomly according to the MAP probability and the optimizer is the
// ICM which accept the proposed sample if it enable a reduction of
// the energy.
//
// Software Guide : EndLatex
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbImage.h"
#include "otbMarkovRandomFieldFilter.h"
#include "itkRescaleIntensityImageFilter.h"
// Software Guide : BeginLatex
//
// First, we need to include header specific to these class:
//
// Software Guide : EndLatex
#include "otbMRFEnergyPotts.h"
#include "otbMRFEnergyGaussianClassification.h"
// Software Guide : BeginCodeSnippet
#include "otbMRFSamplerRandomMAP.h"
#include "otbMRFOptimizerICM.h"
// Software Guide : EndCodeSnippet
//#include "otbMRFSamplerRandom.h"
int main(int argc, char* argv[] )
{
if( argc != 5 )
{
std::cerr << "Missing Parameters " << std::endl;
std::cerr << "Usage: " << argv[0];
std::cerr << " inputImage output lambda iterations" << std::endl;
return 1;
}
const unsigned int Dimension = 2;
typedef double InternalPixelType;
typedef unsigned char LabelledPixelType;
typedef otb::Image<InternalPixelType, Dimension> InputImageType;
typedef otb::Image<LabelledPixelType, Dimension> LabelledImageType;
typedef otb::ImageFileReader< InputImageType > ReaderType;
typedef otb::ImageFileWriter< LabelledImageType > WriterType;
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer = WriterType::New();
const char * inputFilename = argv[1];
const char * outputFilename = argv[2];
reader->SetFileName( inputFilename );
writer->SetFileName( outputFilename );
typedef otb::MarkovRandomFieldFilter
<InputImageType,LabelledImageType> MarkovRandomFieldFilterType;
// Software Guide : BeginLatex
//
// And to declare these new type:
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::MRFSamplerRandomMAP< InputImageType, LabelledImageType> SamplerType;
// typedef otb::MRFSamplerRandom< InputImageType, LabelledImageType> SamplerType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginCodeSnippet
typedef otb::MRFOptimizerICM OptimizerType;
// Software Guide : EndCodeSnippet
typedef otb::MRFEnergyPotts
<LabelledImageType, LabelledImageType> EnergyRegularizationType;
typedef otb::MRFEnergyGaussianClassification
<InputImageType, LabelledImageType> EnergyFidelityType;
MarkovRandomFieldFilterType::Pointer markovFilter = MarkovRandomFieldFilterType::New();
EnergyRegularizationType::Pointer energyRegularization = EnergyRegularizationType::New();
EnergyFidelityType::Pointer energyFidelity = EnergyFidelityType::New();
OptimizerType::Pointer optimizer = OptimizerType::New();
SamplerType::Pointer sampler = SamplerType::New();
// Overpass random calculation(for test only):
sampler->InitializeSeed(0);
markovFilter->InitializeSeed(0);
unsigned int nClass = 4;
energyFidelity->SetNumberOfParameters(2*nClass);
EnergyFidelityType::ParametersType parameters;
parameters.SetSize(energyFidelity->GetNumberOfParameters());
parameters[0]=10.0; //Class 0 mean
parameters[1]=10.0; //Class 0 stdev
parameters[2]=80.0;//Class 1 mean
parameters[3]=10.0; //Class 1 stdev
parameters[4]=150.0; //Class 2 mean
parameters[5]=10.0; //Class 2 stdev
parameters[6]=220.0;//Class 3 mean
parameters[7]=10.0; //Class 3 stde
energyFidelity->SetParameters(parameters);
// Software Guide : BeginLatex
//
// As the \doxygen{otb}{MRFOptimizerICM} does not have any parameters,
// the call to \code{optimizer->SetParameters()} must be removed
//
// Software Guide : EndLatex
markovFilter->SetNumberOfClasses(nClass);
markovFilter->SetMaximumNumberOfIterations(atoi(argv[4]));
markovFilter->SetErrorTolerance(0.0);
markovFilter->SetLambda(atof(argv[3]));
markovFilter->SetNeighborhoodRadius(1);
markovFilter->SetEnergyRegularization(energyRegularization);
markovFilter->SetEnergyFidelity(energyFidelity);
markovFilter->SetOptimizer(optimizer);
markovFilter->SetSampler(sampler);
markovFilter->SetInput(reader->GetOutput());
typedef itk::RescaleIntensityImageFilter
< LabelledImageType, LabelledImageType > RescaleType;
RescaleType::Pointer rescaleFilter = RescaleType::New();
rescaleFilter->SetOutputMinimum(0);
rescaleFilter->SetOutputMaximum(255);
rescaleFilter->SetInput( markovFilter->GetOutput() );
writer->SetInput( rescaleFilter->GetOutput() );
writer->Update();
// Software Guide : BeginLatex
//
// Apart from these, no further modification is required.
//
// Software Guide : EndLatex
// Software Guide : BeginLatex
//
// Figure~\ref{fig:MRF_CLASSIFICATION2} shows the output of the Markov Random
// Field classification after 5 iterations with a
// MAP random sampler and an ICM optimizer.
//
// \begin{figure}
// \center
// \includegraphics[width=0.44\textwidth]{QB_Suburb.eps}
// \includegraphics[width=0.44\textwidth]{MarkovClassification2.eps}
// \itkcaption[MRF restauration]{Result of applying
// the \doxygen{otb}{MarkovRandomFieldFilter} to an extract from a PAN Quickbird
// image for classification. The result is obtained after 5 iterations with a
// MAP random sampler and an ICM optimizer. From left to right : original image,
// classification.}
// \label{fig:MRF_CLASSIFICATION2}
// \end{figure}
//
// Software Guide : EndLatex
return EXIT_SUCCESS;
}
/*========================================================================= /*=========================================================================
Program: ORFEO Toolbox Program: ORFEO Toolbox
......
...@@ -25,19 +25,19 @@ ...@@ -25,19 +25,19 @@
void RegisterTests() void RegisterTests()
{ {
REGISTER_TEST(MarkovClassification1ExampleTest); REGISTER_TEST(MarkovRandomField1ExampleTest);
REGISTER_TEST(MarkovClassification2ExampleTest); REGISTER_TEST(MarkovRandomField2ExampleTest);
REGISTER_TEST(MarkovRestaurationExampleTest); REGISTER_TEST(MarkovRestaurationExampleTest);
REGISTER_TEST(MarkovRegularizationExampleTest); REGISTER_TEST(MarkovRegularizationExampleTest);
} }
#undef main #undef main
#define main MarkovClassification1ExampleTest #define main MarkovRandomField1ExampleTest
#include "MarkovClassification1Example.cxx" #include "MarkovRandomField1Example.cxx"
#undef main #undef main
#define main MarkovClassification2ExampleTest #define main MarkovRandomField2ExampleTest
#include "MarkovClassification2Example.cxx" #include "MarkovRandomField2Example.cxx"
#undef main #undef main
#define main MarkovRestaurationExampleTest #define main MarkovRestaurationExampleTest
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment