From 2d06c461494619113b8cb20ec24278376dcac244 Mon Sep 17 00:00:00 2001 From: Emmanuel Christophe <emmanuel.christophe@orfeo-toolbox.org> Date: Fri, 17 Sep 2010 17:21:57 +0800 Subject: [PATCH] STYLE: end of line --- Code/IO/otbImageMetadataInterfaceFactory.cxx | 4 +- .../otbMRFEnergyGaussianClassification.h | 184 ++-- Code/Markov/otbMRFSamplerRandomMAP.h | 356 ++++---- .../KullbackLeiblerDistanceChDet.cxx | 422 ++++----- .../KullbackLeiblerProfileChDet.cxx | 384 ++++---- .../FeatureExtraction/ExtractRoadExample.cxx | 862 +++++++++--------- Examples/IO/ImageSeriesIOExample.cxx | 404 ++++---- .../SpatialReasoning/otbRCC8VertexBase.cxx | 208 ++--- 8 files changed, 1412 insertions(+), 1412 deletions(-) diff --git a/Code/IO/otbImageMetadataInterfaceFactory.cxx b/Code/IO/otbImageMetadataInterfaceFactory.cxx index 04d29f08e5..42c1178125 100644 --- a/Code/IO/otbImageMetadataInterfaceFactory.cxx +++ b/Code/IO/otbImageMetadataInterfaceFactory.cxx @@ -38,8 +38,8 @@ #include "itkMutexLock.h" #include "itkMutexLockHolder.h" -#include <iostream> -#include <iterator> +#include <iostream> +#include <iterator> #include <vector> namespace otb diff --git a/Code/Markov/otbMRFEnergyGaussianClassification.h b/Code/Markov/otbMRFEnergyGaussianClassification.h index 2cddf6cfc7..27407fc2ea 100644 --- a/Code/Markov/otbMRFEnergyGaussianClassification.h +++ b/Code/Markov/otbMRFEnergyGaussianClassification.h @@ -1,92 +1,92 @@ -/*========================================================================= - - 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. - -=========================================================================*/ -#ifndef __otbMRFEnergyGaussianClassification_h -#define __otbMRFEnergyGaussianClassification_h - -#include "otbMRFEnergy.h" -#include "otbMath.h" - -namespace otb -{ -/** - * \class MRFEnergyGaussianClassification - * \brief This is the implementation of the Gaussian model for Markov classification. - * - * This is the implementation of the Gaussian Energy model for Markov classification, to be used for - * the fidelity term for classification. Energy is: - * \f[ U(x_s / y_s) = \frac{(y_s+\mu_{x_s})^2}{2\sigma^2_{x_s}}+\log{\sqrt{2\pi}\sigma_{x_s}} \f] - * with - * - \f$ x_s \f$ the label on site s - * - \f$ y_s \f$ the value on the reference image - * - \f$ \mu_{x_s} \f$ and \f$ \sigma^2_{x_s} \f$ the mean and variance of label \f$ x_s \f$ - * - * This class is meant to be used in the MRF framework with the otb::MarkovRandomFieldFilter - * - * \ingroup Markov - */ - -template<class TInput1, class TInput2> -class ITK_EXPORT MRFEnergyGaussianClassification : public MRFEnergy<TInput1, TInput2> -{ -public: - typedef MRFEnergyGaussianClassification Self; - typedef MRFEnergy<TInput1, TInput2> Superclass; - typedef itk::SmartPointer<Self> Pointer; - typedef itk::SmartPointer<const Self> ConstPointer; - - typedef TInput1 InputImageType; - typedef TInput2 LabelledImageType; - typedef typename InputImageType::PixelType InputImagePixelType; - typedef typename LabelledImageType::PixelType LabelledImagePixelType; - typedef itk::Array <double> ParametersType; - - itkNewMacro(Self); - - itkTypeMacro(MRFEnergyGaussianClassification, MRFEnergy); - - void SetNumberOfParameters(const unsigned int nParameters) - { - Superclass::SetNumberOfParameters(nParameters); - this->m_Parameters.SetSize(nParameters); - this->Modified(); - } - - double GetSingleValue(const InputImagePixelType& value1, const LabelledImagePixelType& value2) - { - if ((unsigned int) value2 >= this->GetNumberOfParameters() / 2) - { - itkExceptionMacro(<< "Number of parameters does not correspond to number of classes"); - } - double val1 = static_cast<double>(value1); - - double result = vnl_math_sqr(val1 - this->m_Parameters[2 * static_cast<int>(value2)]) - / (2 * vnl_math_sqr(this->m_Parameters[2 * static_cast<int>(value2) + 1])) - + vcl_log(vcl_sqrt(CONST_2PI) * this->m_Parameters[2 * static_cast<int>(value2) + 1]); - - return static_cast<double>(result); - } - -protected: - // The constructor and destructor. - MRFEnergyGaussianClassification() {}; - virtual ~MRFEnergyGaussianClassification() {} - -}; -} - -#endif +/*========================================================================= + + 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. + +=========================================================================*/ +#ifndef __otbMRFEnergyGaussianClassification_h +#define __otbMRFEnergyGaussianClassification_h + +#include "otbMRFEnergy.h" +#include "otbMath.h" + +namespace otb +{ +/** + * \class MRFEnergyGaussianClassification + * \brief This is the implementation of the Gaussian model for Markov classification. + * + * This is the implementation of the Gaussian Energy model for Markov classification, to be used for + * the fidelity term for classification. Energy is: + * \f[ U(x_s / y_s) = \frac{(y_s+\mu_{x_s})^2}{2\sigma^2_{x_s}}+\log{\sqrt{2\pi}\sigma_{x_s}} \f] + * with + * - \f$ x_s \f$ the label on site s + * - \f$ y_s \f$ the value on the reference image + * - \f$ \mu_{x_s} \f$ and \f$ \sigma^2_{x_s} \f$ the mean and variance of label \f$ x_s \f$ + * + * This class is meant to be used in the MRF framework with the otb::MarkovRandomFieldFilter + * + * \ingroup Markov + */ + +template<class TInput1, class TInput2> +class ITK_EXPORT MRFEnergyGaussianClassification : public MRFEnergy<TInput1, TInput2> +{ +public: + typedef MRFEnergyGaussianClassification Self; + typedef MRFEnergy<TInput1, TInput2> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + typedef TInput1 InputImageType; + typedef TInput2 LabelledImageType; + typedef typename InputImageType::PixelType InputImagePixelType; + typedef typename LabelledImageType::PixelType LabelledImagePixelType; + typedef itk::Array <double> ParametersType; + + itkNewMacro(Self); + + itkTypeMacro(MRFEnergyGaussianClassification, MRFEnergy); + + void SetNumberOfParameters(const unsigned int nParameters) + { + Superclass::SetNumberOfParameters(nParameters); + this->m_Parameters.SetSize(nParameters); + this->Modified(); + } + + double GetSingleValue(const InputImagePixelType& value1, const LabelledImagePixelType& value2) + { + if ((unsigned int) value2 >= this->GetNumberOfParameters() / 2) + { + itkExceptionMacro(<< "Number of parameters does not correspond to number of classes"); + } + double val1 = static_cast<double>(value1); + + double result = vnl_math_sqr(val1 - this->m_Parameters[2 * static_cast<int>(value2)]) + / (2 * vnl_math_sqr(this->m_Parameters[2 * static_cast<int>(value2) + 1])) + + vcl_log(vcl_sqrt(CONST_2PI) * this->m_Parameters[2 * static_cast<int>(value2) + 1]); + + return static_cast<double>(result); + } + +protected: + // The constructor and destructor. + MRFEnergyGaussianClassification() {}; + virtual ~MRFEnergyGaussianClassification() {} + +}; +} + +#endif diff --git a/Code/Markov/otbMRFSamplerRandomMAP.h b/Code/Markov/otbMRFSamplerRandomMAP.h index 61ca7fa4f9..e001b7e76e 100644 --- a/Code/Markov/otbMRFSamplerRandomMAP.h +++ b/Code/Markov/otbMRFSamplerRandomMAP.h @@ -1,178 +1,178 @@ -/*========================================================================= - - 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. - -=========================================================================*/ - -#ifndef __otbMRFSamplerRandomMAP_h -#define __otbMRFSamplerRandomMAP_h - -#include "itkMersenneTwisterRandomVariateGenerator.h" -#include "otbMRFSampler.h" - -namespace otb -{ -/** - * \class MRFSamplerRandomMAP - * \brief This is the base class for sampler methods used in the MRF framework. - * - * This is one sampler to be used int he MRF framework. This sampler select the - * value randomly according to the apriori probability. - * - * The probability is defined from the energy as: - * - * \f[ P(X=x)= \frac{1}{Z} \exp^{-U(x)} \f] - * - * where \f$ Z = \sum_x \exp^{-U(x)}\f$ - * - * - * This class is meant to be used in the MRF framework with the otb::MarkovRandomFieldFilter - * - * \ingroup Markov - */ - -template<class TInput1, class TInput2> -class ITK_EXPORT MRFSamplerRandomMAP : public MRFSampler<TInput1, TInput2> -{ -public: - - typedef MRFSamplerRandomMAP Self; - typedef otb::MRFSampler<TInput1, TInput2> Superclass; - typedef itk::SmartPointer<Self> Pointer; - typedef itk::SmartPointer<const Self> ConstPointer; - - typedef typename Superclass::InputImageNeighborhoodIterator InputImageNeighborhoodIterator; - typedef typename Superclass::LabelledImageNeighborhoodIterator LabelledImageNeighborhoodIterator; - typedef typename Superclass::LabelledImagePixelType LabelledImagePixelType; - typedef typename Superclass::InputImagePixelType InputImagePixelType; - typedef typename Superclass::EnergyFidelityType EnergyFidelityType; - typedef typename Superclass::EnergyRegularizationType EnergyRegularizationType; - typedef typename Superclass::EnergyFidelityPointer EnergyFidelityPointer; - typedef typename Superclass::EnergyRegularizationPointer EnergyRegularizationPointer; - typedef itk::Statistics::MersenneTwisterRandomVariateGenerator RandomGeneratorType; - - itkNewMacro(Self); - - itkTypeMacro(MRFSamplerRandomMAP, MRFSampler); - - void SetNumberOfClasses(const unsigned int nClasses) - { - if ((nClasses != this->m_NumberOfClasses) || (m_EnergiesInvalid == true)) - { - this->m_NumberOfClasses = nClasses; - if (m_Energy != NULL) free(m_Energy); - if (m_RepartitionFunction != NULL) free(m_RepartitionFunction); - m_Energy = (double *) calloc(this->m_NumberOfClasses, sizeof(double)); - m_RepartitionFunction = (double *) calloc(this->m_NumberOfClasses, sizeof(double)); - this->Modified(); - } - } - - inline int Compute(const InputImageNeighborhoodIterator& itData, const LabelledImageNeighborhoodIterator& itRegul) - { - if (this->m_NumberOfClasses == 0) - { - itkExceptionMacro(<< "NumberOfClasse has to be greater than 0."); - } - - this->m_EnergyBefore = this->m_EnergyFidelity->GetValue(itData, itRegul.GetCenterPixel()); - this->m_EnergyBefore += this->m_Lambda - * this->m_EnergyRegularization->GetValue(itRegul, itRegul.GetCenterPixel()); - - //Try all possible value (how to be generic ?) - this->m_EnergyAfter = this->m_EnergyBefore; //default values to current one - this->m_Value = itRegul.GetCenterPixel(); - - //Compute probability for each possibility - double totalProba = 0.0; - unsigned int valueCurrent = 0; - for (valueCurrent = 0; valueCurrent < this->m_NumberOfClasses; ++valueCurrent) - { - this->m_EnergyCurrent = this->m_EnergyFidelity->GetValue(itData, static_cast<LabelledImagePixelType>(valueCurrent)); - this->m_EnergyCurrent += this->m_Lambda - * this->m_EnergyRegularization->GetValue(itRegul, - static_cast<LabelledImagePixelType>( - valueCurrent)); - - m_Energy[valueCurrent] = this->m_EnergyCurrent; - m_RepartitionFunction[valueCurrent] = vcl_exp(-this->m_EnergyCurrent) + totalProba; - totalProba = m_RepartitionFunction[valueCurrent]; - - } - - //Pick a value according to probability - - //double select = (m_Generator->GetIntegerVariate()/(double(RAND_MAX)+1) * totalProba); - double select = - (m_Generator->GetIntegerVariate() / - (double(itk::NumericTraits<RandomGeneratorType::IntegerType>::max()) + 1) * totalProba); - valueCurrent = 0; - while ((valueCurrent < this->GetNumberOfClasses()) - && (m_RepartitionFunction[valueCurrent] <= select)) - { - valueCurrent++; - } - - if (valueCurrent == this->GetNumberOfClasses()) - { - valueCurrent = this->GetNumberOfClasses() - 1; - } - - if (this->m_Value != static_cast<LabelledImagePixelType>(valueCurrent)) - { - this->m_Value = static_cast<LabelledImagePixelType>(valueCurrent); - this->m_EnergyAfter = m_Energy[static_cast<unsigned int>(valueCurrent)]; - } - - this->m_DeltaEnergy = this->m_EnergyAfter - this->m_EnergyBefore; - - return 0; - } - - /** Methods to cancel random effects.*/ - void InitializeSeed(int seed) - { - m_Generator->SetSeed(seed); - } - void InitializeSeed() - { - m_Generator->SetSeed(); - } - -protected: - // The constructor and destructor. - MRFSamplerRandomMAP() : - m_RepartitionFunction(NULL), - m_Energy(NULL), - m_EnergiesInvalid(true) - { - m_Generator = RandomGeneratorType::New(); - m_Generator->SetSeed(); - } - virtual ~MRFSamplerRandomMAP() - { - if (m_Energy != NULL) free(m_Energy); - if (m_RepartitionFunction != NULL) free(m_RepartitionFunction); - } - -private: - double * m_RepartitionFunction; - double * m_Energy; - bool m_EnergiesInvalid; - RandomGeneratorType::Pointer m_Generator; -}; -} - -#endif +/*========================================================================= + + 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. + +=========================================================================*/ + +#ifndef __otbMRFSamplerRandomMAP_h +#define __otbMRFSamplerRandomMAP_h + +#include "itkMersenneTwisterRandomVariateGenerator.h" +#include "otbMRFSampler.h" + +namespace otb +{ +/** + * \class MRFSamplerRandomMAP + * \brief This is the base class for sampler methods used in the MRF framework. + * + * This is one sampler to be used int he MRF framework. This sampler select the + * value randomly according to the apriori probability. + * + * The probability is defined from the energy as: + * + * \f[ P(X=x)= \frac{1}{Z} \exp^{-U(x)} \f] + * + * where \f$ Z = \sum_x \exp^{-U(x)}\f$ + * + * + * This class is meant to be used in the MRF framework with the otb::MarkovRandomFieldFilter + * + * \ingroup Markov + */ + +template<class TInput1, class TInput2> +class ITK_EXPORT MRFSamplerRandomMAP : public MRFSampler<TInput1, TInput2> +{ +public: + + typedef MRFSamplerRandomMAP Self; + typedef otb::MRFSampler<TInput1, TInput2> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + typedef typename Superclass::InputImageNeighborhoodIterator InputImageNeighborhoodIterator; + typedef typename Superclass::LabelledImageNeighborhoodIterator LabelledImageNeighborhoodIterator; + typedef typename Superclass::LabelledImagePixelType LabelledImagePixelType; + typedef typename Superclass::InputImagePixelType InputImagePixelType; + typedef typename Superclass::EnergyFidelityType EnergyFidelityType; + typedef typename Superclass::EnergyRegularizationType EnergyRegularizationType; + typedef typename Superclass::EnergyFidelityPointer EnergyFidelityPointer; + typedef typename Superclass::EnergyRegularizationPointer EnergyRegularizationPointer; + typedef itk::Statistics::MersenneTwisterRandomVariateGenerator RandomGeneratorType; + + itkNewMacro(Self); + + itkTypeMacro(MRFSamplerRandomMAP, MRFSampler); + + void SetNumberOfClasses(const unsigned int nClasses) + { + if ((nClasses != this->m_NumberOfClasses) || (m_EnergiesInvalid == true)) + { + this->m_NumberOfClasses = nClasses; + if (m_Energy != NULL) free(m_Energy); + if (m_RepartitionFunction != NULL) free(m_RepartitionFunction); + m_Energy = (double *) calloc(this->m_NumberOfClasses, sizeof(double)); + m_RepartitionFunction = (double *) calloc(this->m_NumberOfClasses, sizeof(double)); + this->Modified(); + } + } + + inline int Compute(const InputImageNeighborhoodIterator& itData, const LabelledImageNeighborhoodIterator& itRegul) + { + if (this->m_NumberOfClasses == 0) + { + itkExceptionMacro(<< "NumberOfClasse has to be greater than 0."); + } + + this->m_EnergyBefore = this->m_EnergyFidelity->GetValue(itData, itRegul.GetCenterPixel()); + this->m_EnergyBefore += this->m_Lambda + * this->m_EnergyRegularization->GetValue(itRegul, itRegul.GetCenterPixel()); + + //Try all possible value (how to be generic ?) + this->m_EnergyAfter = this->m_EnergyBefore; //default values to current one + this->m_Value = itRegul.GetCenterPixel(); + + //Compute probability for each possibility + double totalProba = 0.0; + unsigned int valueCurrent = 0; + for (valueCurrent = 0; valueCurrent < this->m_NumberOfClasses; ++valueCurrent) + { + this->m_EnergyCurrent = this->m_EnergyFidelity->GetValue(itData, static_cast<LabelledImagePixelType>(valueCurrent)); + this->m_EnergyCurrent += this->m_Lambda + * this->m_EnergyRegularization->GetValue(itRegul, + static_cast<LabelledImagePixelType>( + valueCurrent)); + + m_Energy[valueCurrent] = this->m_EnergyCurrent; + m_RepartitionFunction[valueCurrent] = vcl_exp(-this->m_EnergyCurrent) + totalProba; + totalProba = m_RepartitionFunction[valueCurrent]; + + } + + //Pick a value according to probability + + //double select = (m_Generator->GetIntegerVariate()/(double(RAND_MAX)+1) * totalProba); + double select = + (m_Generator->GetIntegerVariate() / + (double(itk::NumericTraits<RandomGeneratorType::IntegerType>::max()) + 1) * totalProba); + valueCurrent = 0; + while ((valueCurrent < this->GetNumberOfClasses()) + && (m_RepartitionFunction[valueCurrent] <= select)) + { + valueCurrent++; + } + + if (valueCurrent == this->GetNumberOfClasses()) + { + valueCurrent = this->GetNumberOfClasses() - 1; + } + + if (this->m_Value != static_cast<LabelledImagePixelType>(valueCurrent)) + { + this->m_Value = static_cast<LabelledImagePixelType>(valueCurrent); + this->m_EnergyAfter = m_Energy[static_cast<unsigned int>(valueCurrent)]; + } + + this->m_DeltaEnergy = this->m_EnergyAfter - this->m_EnergyBefore; + + return 0; + } + + /** Methods to cancel random effects.*/ + void InitializeSeed(int seed) + { + m_Generator->SetSeed(seed); + } + void InitializeSeed() + { + m_Generator->SetSeed(); + } + +protected: + // The constructor and destructor. + MRFSamplerRandomMAP() : + m_RepartitionFunction(NULL), + m_Energy(NULL), + m_EnergiesInvalid(true) + { + m_Generator = RandomGeneratorType::New(); + m_Generator->SetSeed(); + } + virtual ~MRFSamplerRandomMAP() + { + if (m_Energy != NULL) free(m_Energy); + if (m_RepartitionFunction != NULL) free(m_RepartitionFunction); + } + +private: + double * m_RepartitionFunction; + double * m_Energy; + bool m_EnergiesInvalid; + RandomGeneratorType::Pointer m_Generator; +}; +} + +#endif diff --git a/Examples/ChangeDetection/KullbackLeiblerDistanceChDet.cxx b/Examples/ChangeDetection/KullbackLeiblerDistanceChDet.cxx index 91e325cb30..6da141ae1f 100644 --- a/Examples/ChangeDetection/KullbackLeiblerDistanceChDet.cxx +++ b/Examples/ChangeDetection/KullbackLeiblerDistanceChDet.cxx @@ -1,211 +1,211 @@ -/*========================================================================= - - 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. - -=========================================================================*/ - -// Software Guide : BeginCommandLineArgs -// INPUTS: {GomaAvant.png}, {GomaApres.png} -// OUTPUTS: {KLdistanceChDet.png} -// 35 -// Software Guide : EndCommandLineArgs - -// Software Guide : BeginLatex -// This example illustrates the class -// \doxygen{otb}{KullbackLeiblerDistanceImageFilter} for detecting changes -// between pairs of images. This filter computes the Kullback-Leibler -// distance between probability density functions (pdfs). -// In fact, the Kullback-Leibler distance is itself approximated through -// a cumulant-based expansion, since the pdfs are approximated through an -// Edgeworth series. -// The Kullback-Leibler distance is evaluated by: -// \begin{multline}\label{eqKLapprox1D} -// K_{\text{Edgeworth}}(X_1 | X_2) = \frac{1}{12} \frac{\kappa_{X_1;3}^2}{\kappa_{X_1;2}^2} -// + \frac{1}{2} \left( \log \frac{\kappa_{X_2;2}}{\kappa_{X_1;2}} -// -1+\frac{1}{\kappa_{X_2;2}} -// \left( \kappa_{X_1;1} - \kappa_{X_2;1} + \kappa_{X_1;2}^{1/2} \right)^2 -// \right) \\ -// - \left( \kappa_{X_2;3} \frac{a_1}{6} + \kappa_{X_2;4} \frac{a_2}{24} -// + \kappa_{X_2;3}^2 \frac{a_3}{72} \right) -// - \frac{1}{2} \frac{ \kappa_{X_2;3}^2}{36} -// \left( -// c_6 - 6 \frac{c_4}{\kappa_{X_1;2}} + 9 \frac{c_2}{\kappa_{X_2;2}^2} -// \right) \\ -// - 10 \frac{\kappa_{X_1;3} \kappa_{X_2;3} -// \left( \kappa_{X_1;1} - \kappa_{X_2;1} \right) -// \left( \kappa_{X_1;2} - \kappa_{X_2;2} \right)}{\kappa_{X_2;2}^6} \qquad -// \end{multline} -// where -// \begin{align*} -// a_1 &= c_3 - 3 \frac{\alpha}{\kappa_{X_2;2}} \\ -// a_2 &= c_4 - 6 \frac{c_2}{\kappa_{X_2;2}} + \frac{3}{\kappa_{X_2;2}^2} \\ -// a_3 &= c_6 - 15\frac{c_4}{\kappa_{X_2;2}} + 45\frac{c_2}{\kappa_{X_2;2}^2} - -// \frac{15}{\kappa_{X_2;2}^3} \\ -// c_2 &= \alpha^2 + \beta^2 \\ -// c_3 &= \alpha^3 + 3 \alpha \beta^2 \\ -// c_4 &= \alpha^4 + 6 \alpha^2 \beta^2 + 3 \beta^4 \\ -// c_6 &= \alpha^6 + 15\alpha^4 \beta^2 + 45 \alpha^2 \beta^4 + 15 \beta^6 \\ -// \alpha &= \frac{\kappa_{X_1;1} - \kappa_{X_2;1}}{\kappa_{X_2;2}} \\ -// \beta &= \frac{ \kappa_{X_1;2}^{1/2} }{\kappa_{X_2;2}}. -// \end{align*} -// $\kappa_{X_i;1}$, $\kappa_{X_i;2}$, $\kappa_{X_i;3}$ and $\kappa_{X_i;4}$ -// are the cumulants up to order 4 of the random variable $X_i$ ($i=1,2$). -// This example will use the images shown in -// figure~\ref{fig:RATCHDETINIM}. These correspond to 2 Radarsat fine -// mode acquisitions before and after a lava flow resulting from a -// volcanic eruption. -// -// The program itself is very similar to the ratio of means detector, -// implemented in \doxygen{otb}{MeanRatioImageFilter}, -// in section~\ref{sec:RatioOfMeans}. Nevertheless -// the corresponding header file has to be used instead. -// -// Software Guide : EndLatex - -#include "itkExceptionObject.h" -#include "otbImage.h" -#include "otbImageFileReader.h" -#include "otbImageFileWriter.h" -#include "itkRescaleIntensityImageFilter.h" - -// Software Guide : BeginCodeSnippet -#include "otbKullbackLeiblerDistanceImageFilter.h" -// Software Guide : EndCodeSnippet - -int main(int argc, char * argv[]) -{ - try - { - if (argc != 5) - { - std::cerr << - "Change detection through a Kullback-Leibler measure (which is a distance between local distributions)\n"; - std::cerr << - "Kullback-Leibler measure is optimized by a Edgeworth series expansion\n"; - std::cerr << argv[0] << " imgAv imgAp imgResu winSize\n"; - return 1; - } - - char * fileName1 = argv[1]; - char * fileName2 = argv[2]; - char * fileNameOut = argv[3]; - int winSize = atoi(argv[4]); - - const unsigned int Dimension = 2; - typedef double PixelType; - typedef unsigned char OutputPixelType; - - typedef otb::Image<PixelType, Dimension> ImageType; - typedef otb::Image<OutputPixelType, Dimension> OutputImageType; - - // Software Guide : BeginLatex - // - // The \doxygen{otb}{KullbackLeiblerDistanceImageFilter} is templated over - // the types of the two input images and the type of the generated change - // image, in a similar way as the \doxygen{otb}{MeanRatioImageFilter}. It is - // the only line to be changed from the ratio of means change detection - // example to perform a change detection through a distance between - // distributions... - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - typedef otb::KullbackLeiblerDistanceImageFilter<ImageType, - ImageType, - ImageType> FilterType; - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The different elements of the pipeline can now be instantiated. Follow the - // ratio of means change detector example. - // - // Software Guide : EndLatex - - typedef otb::ImageFileReader<ImageType> ReaderType; - typedef otb::ImageFileWriter<OutputImageType> WriterType; - - ReaderType::Pointer reader1 = ReaderType::New(); - reader1->SetFileName(fileName1); - - ReaderType::Pointer reader2 = ReaderType::New(); - reader2->SetFileName(fileName2); - - // Software Guide : BeginLatex - // - // The only parameter for this change detector is the radius of - // the window used for computing the cumulants. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - FilterType::Pointer filter = FilterType::New(); - filter->SetRadius((winSize - 1) / 2); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The pipeline is built by plugging all the elements together. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - filter->SetInput1(reader1->GetOutput()); - filter->SetInput2(reader2->GetOutput()); - // Software Guide : EndCodeSnippet - - typedef itk::RescaleIntensityImageFilter<ImageType, - OutputImageType> RescaleFilterType; - RescaleFilterType::Pointer rescaler = RescaleFilterType::New(); - - rescaler->SetInput(filter->GetOutput()); - rescaler->SetOutputMinimum(0); - rescaler->SetOutputMaximum(255); - - WriterType::Pointer writer = WriterType::New(); - writer->SetFileName(fileNameOut); - writer->SetInput(rescaler->GetOutput()); - writer->Update(); - - } - - 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; - } - - // Software Guide : BeginLatex - // Figure \ref{fig:RESKLDCHDET} 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]{KLdistanceChDet.eps} - // \itkcaption[Kullback-Leibler Change Detection Results]{Result of the - // Kullback-Leibler change detector} - // \label{fig:RESKLDCHDET} - // \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. + +=========================================================================*/ + +// Software Guide : BeginCommandLineArgs +// INPUTS: {GomaAvant.png}, {GomaApres.png} +// OUTPUTS: {KLdistanceChDet.png} +// 35 +// Software Guide : EndCommandLineArgs + +// Software Guide : BeginLatex +// This example illustrates the class +// \doxygen{otb}{KullbackLeiblerDistanceImageFilter} for detecting changes +// between pairs of images. This filter computes the Kullback-Leibler +// distance between probability density functions (pdfs). +// In fact, the Kullback-Leibler distance is itself approximated through +// a cumulant-based expansion, since the pdfs are approximated through an +// Edgeworth series. +// The Kullback-Leibler distance is evaluated by: +// \begin{multline}\label{eqKLapprox1D} +// K_{\text{Edgeworth}}(X_1 | X_2) = \frac{1}{12} \frac{\kappa_{X_1;3}^2}{\kappa_{X_1;2}^2} +// + \frac{1}{2} \left( \log \frac{\kappa_{X_2;2}}{\kappa_{X_1;2}} +// -1+\frac{1}{\kappa_{X_2;2}} +// \left( \kappa_{X_1;1} - \kappa_{X_2;1} + \kappa_{X_1;2}^{1/2} \right)^2 +// \right) \\ +// - \left( \kappa_{X_2;3} \frac{a_1}{6} + \kappa_{X_2;4} \frac{a_2}{24} +// + \kappa_{X_2;3}^2 \frac{a_3}{72} \right) +// - \frac{1}{2} \frac{ \kappa_{X_2;3}^2}{36} +// \left( +// c_6 - 6 \frac{c_4}{\kappa_{X_1;2}} + 9 \frac{c_2}{\kappa_{X_2;2}^2} +// \right) \\ +// - 10 \frac{\kappa_{X_1;3} \kappa_{X_2;3} +// \left( \kappa_{X_1;1} - \kappa_{X_2;1} \right) +// \left( \kappa_{X_1;2} - \kappa_{X_2;2} \right)}{\kappa_{X_2;2}^6} \qquad +// \end{multline} +// where +// \begin{align*} +// a_1 &= c_3 - 3 \frac{\alpha}{\kappa_{X_2;2}} \\ +// a_2 &= c_4 - 6 \frac{c_2}{\kappa_{X_2;2}} + \frac{3}{\kappa_{X_2;2}^2} \\ +// a_3 &= c_6 - 15\frac{c_4}{\kappa_{X_2;2}} + 45\frac{c_2}{\kappa_{X_2;2}^2} - +// \frac{15}{\kappa_{X_2;2}^3} \\ +// c_2 &= \alpha^2 + \beta^2 \\ +// c_3 &= \alpha^3 + 3 \alpha \beta^2 \\ +// c_4 &= \alpha^4 + 6 \alpha^2 \beta^2 + 3 \beta^4 \\ +// c_6 &= \alpha^6 + 15\alpha^4 \beta^2 + 45 \alpha^2 \beta^4 + 15 \beta^6 \\ +// \alpha &= \frac{\kappa_{X_1;1} - \kappa_{X_2;1}}{\kappa_{X_2;2}} \\ +// \beta &= \frac{ \kappa_{X_1;2}^{1/2} }{\kappa_{X_2;2}}. +// \end{align*} +// $\kappa_{X_i;1}$, $\kappa_{X_i;2}$, $\kappa_{X_i;3}$ and $\kappa_{X_i;4}$ +// are the cumulants up to order 4 of the random variable $X_i$ ($i=1,2$). +// This example will use the images shown in +// figure~\ref{fig:RATCHDETINIM}. These correspond to 2 Radarsat fine +// mode acquisitions before and after a lava flow resulting from a +// volcanic eruption. +// +// The program itself is very similar to the ratio of means detector, +// implemented in \doxygen{otb}{MeanRatioImageFilter}, +// in section~\ref{sec:RatioOfMeans}. Nevertheless +// the corresponding header file has to be used instead. +// +// Software Guide : EndLatex + +#include "itkExceptionObject.h" +#include "otbImage.h" +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" +#include "itkRescaleIntensityImageFilter.h" + +// Software Guide : BeginCodeSnippet +#include "otbKullbackLeiblerDistanceImageFilter.h" +// Software Guide : EndCodeSnippet + +int main(int argc, char * argv[]) +{ + try + { + if (argc != 5) + { + std::cerr << + "Change detection through a Kullback-Leibler measure (which is a distance between local distributions)\n"; + std::cerr << + "Kullback-Leibler measure is optimized by a Edgeworth series expansion\n"; + std::cerr << argv[0] << " imgAv imgAp imgResu winSize\n"; + return 1; + } + + char * fileName1 = argv[1]; + char * fileName2 = argv[2]; + char * fileNameOut = argv[3]; + int winSize = atoi(argv[4]); + + const unsigned int Dimension = 2; + typedef double PixelType; + typedef unsigned char OutputPixelType; + + typedef otb::Image<PixelType, Dimension> ImageType; + typedef otb::Image<OutputPixelType, Dimension> OutputImageType; + + // Software Guide : BeginLatex + // + // The \doxygen{otb}{KullbackLeiblerDistanceImageFilter} is templated over + // the types of the two input images and the type of the generated change + // image, in a similar way as the \doxygen{otb}{MeanRatioImageFilter}. It is + // the only line to be changed from the ratio of means change detection + // example to perform a change detection through a distance between + // distributions... + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + typedef otb::KullbackLeiblerDistanceImageFilter<ImageType, + ImageType, + ImageType> FilterType; + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // The different elements of the pipeline can now be instantiated. Follow the + // ratio of means change detector example. + // + // Software Guide : EndLatex + + typedef otb::ImageFileReader<ImageType> ReaderType; + typedef otb::ImageFileWriter<OutputImageType> WriterType; + + ReaderType::Pointer reader1 = ReaderType::New(); + reader1->SetFileName(fileName1); + + ReaderType::Pointer reader2 = ReaderType::New(); + reader2->SetFileName(fileName2); + + // Software Guide : BeginLatex + // + // The only parameter for this change detector is the radius of + // the window used for computing the cumulants. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + FilterType::Pointer filter = FilterType::New(); + filter->SetRadius((winSize - 1) / 2); + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // The pipeline is built by plugging all the elements together. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + filter->SetInput1(reader1->GetOutput()); + filter->SetInput2(reader2->GetOutput()); + // Software Guide : EndCodeSnippet + + typedef itk::RescaleIntensityImageFilter<ImageType, + OutputImageType> RescaleFilterType; + RescaleFilterType::Pointer rescaler = RescaleFilterType::New(); + + rescaler->SetInput(filter->GetOutput()); + rescaler->SetOutputMinimum(0); + rescaler->SetOutputMaximum(255); + + WriterType::Pointer writer = WriterType::New(); + writer->SetFileName(fileNameOut); + writer->SetInput(rescaler->GetOutput()); + writer->Update(); + + } + + 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; + } + + // Software Guide : BeginLatex + // Figure \ref{fig:RESKLDCHDET} 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]{KLdistanceChDet.eps} + // \itkcaption[Kullback-Leibler Change Detection Results]{Result of the + // Kullback-Leibler change detector} + // \label{fig:RESKLDCHDET} + // \end{figure} + // Software Guide : EndLatex + + return EXIT_SUCCESS; +} diff --git a/Examples/ChangeDetection/KullbackLeiblerProfileChDet.cxx b/Examples/ChangeDetection/KullbackLeiblerProfileChDet.cxx index e6668746ab..2fb9f417ba 100644 --- a/Examples/ChangeDetection/KullbackLeiblerProfileChDet.cxx +++ b/Examples/ChangeDetection/KullbackLeiblerProfileChDet.cxx @@ -1,192 +1,192 @@ -/*========================================================================= - - 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. - -=========================================================================*/ - -// Software Guide : BeginCommandLineArgs -// INPUTS: {GomaAvant.png}, {GomaApres.png} -// OUTPUTS: {KLProfileChDet.png} -// 5 51 1 12 24 -// Software Guide : EndCommandLineArgs - -// Software Guide : BeginLatex -// -// 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. -// -// Software Guide : EndLatex - -#include "itkExceptionObject.h" -#include "otbImage.h" -#include "otbMultiChannelExtractROI.h" -#include "otbVectorRescaleIntensityImageFilter.h" - -// Software Guide : BeginCodeSnippet -#include "otbVectorImage.h" -#include "otbKullbackLeiblerProfileImageFilter.h" -// Software Guide : EndCodeSnippet -#include "otbImageFileReader.h" -#include "otbImageFileWriter.h" - -int main(int argc, char * argv[]) -{ - try - { - if (argc != 9) - { - std::cerr << - "Detection de changements par mesure de Kullback-Leibler, optimisee par un developpement de Edgeworth\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; - - // Software Guide : BeginLatex - // - // 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}. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - typedef otb::Image<PixelType, Dimension> ImageType; - typedef otb::VectorImage<PixelType, Dimension> VectorImageType; - typedef otb::KullbackLeiblerProfileImageFilter<ImageType, - ImageType, - VectorImageType> FilterType; - // Software Guide : EndCodeSnippet - - 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); - - // Software Guide : BeginLatex - // - // 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. - // - // Software Guide : EndLatex - // - // Software Guide : BeginCodeSnippet - FilterType::Pointer filter = FilterType::New(); - filter->SetRadius((winSizeMin - 1) / 2, (winSizeMax - 1) / 2); - filter->SetInput1(reader1->GetOutput()); - filter->SetInput2(reader2->GetOutput()); - // Software Guide : EndCodeSnippet - - 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(); - - // Software Guide : BeginLatex - // - // 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} - // - // Software Guide : EndLatex - } - - 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; -} +/*========================================================================= + + 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. + +=========================================================================*/ + +// Software Guide : BeginCommandLineArgs +// INPUTS: {GomaAvant.png}, {GomaApres.png} +// OUTPUTS: {KLProfileChDet.png} +// 5 51 1 12 24 +// Software Guide : EndCommandLineArgs + +// Software Guide : BeginLatex +// +// 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. +// +// Software Guide : EndLatex + +#include "itkExceptionObject.h" +#include "otbImage.h" +#include "otbMultiChannelExtractROI.h" +#include "otbVectorRescaleIntensityImageFilter.h" + +// Software Guide : BeginCodeSnippet +#include "otbVectorImage.h" +#include "otbKullbackLeiblerProfileImageFilter.h" +// Software Guide : EndCodeSnippet +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" + +int main(int argc, char * argv[]) +{ + try + { + if (argc != 9) + { + std::cerr << + "Detection de changements par mesure de Kullback-Leibler, optimisee par un developpement de Edgeworth\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; + + // Software Guide : BeginLatex + // + // 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}. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + typedef otb::Image<PixelType, Dimension> ImageType; + typedef otb::VectorImage<PixelType, Dimension> VectorImageType; + typedef otb::KullbackLeiblerProfileImageFilter<ImageType, + ImageType, + VectorImageType> FilterType; + // Software Guide : EndCodeSnippet + + 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); + + // Software Guide : BeginLatex + // + // 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. + // + // Software Guide : EndLatex + // + // Software Guide : BeginCodeSnippet + FilterType::Pointer filter = FilterType::New(); + filter->SetRadius((winSizeMin - 1) / 2, (winSizeMax - 1) / 2); + filter->SetInput1(reader1->GetOutput()); + filter->SetInput2(reader2->GetOutput()); + // Software Guide : EndCodeSnippet + + 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(); + + // Software Guide : BeginLatex + // + // 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} + // + // Software Guide : EndLatex + } + + 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; +} diff --git a/Examples/FeatureExtraction/ExtractRoadExample.cxx b/Examples/FeatureExtraction/ExtractRoadExample.cxx index a461eaccf6..aaa5ac9d11 100644 --- a/Examples/FeatureExtraction/ExtractRoadExample.cxx +++ b/Examples/FeatureExtraction/ExtractRoadExample.cxx @@ -1,431 +1,431 @@ -/*========================================================================= - - 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 - -// Software Guide : BeginCommandLineArgs -// INPUTS: {qb_RoadExtract.tif} -// OUTPUTS: {ExtractRoadOutput.png} -// 337 557 432 859 1.0 0.00005 1.0 0.39269 1.0 10.0 25. -// Software Guide : EndCommandLineArgs - -// Software Guide : BeginLatex -// -// The easiest way to use the road extraction filter provided by OTB is to use the composite -// filter. If a modification in the pipeline is required to adapt to a particular situation, -// the step by step example, described in the next section can be adapted. -// -// This example demonstrates the use of the \doxygen{otb}{RoadExtractionFilter}. -// This filter is a composite filter achieving road extraction according to the algorithm -// adapted by E. Christophe and J. Inglada \cite{Christophe2007} from an original method -// proposed in \cite{Lacroix1998}. -// -// The first step toward the use of this filter is the inclusion of the proper header files. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - -#include "otbPolyLineParametricPathWithValue.h" -#include "otbRoadExtractionFilter.h" -#include "otbDrawPathListFilter.h" - -// Software Guide : EndCodeSnippet - -#include "otbImage.h" -#include "otbVectorImage.h" -#include "otbImageFileReader.h" -#include "otbImageFileWriter.h" -#include "itkRescaleIntensityImageFilter.h" -#include "otbMath.h" - -#include "itkInvertIntensityImageFilter.h" -#include "itkGrayscaleDilateImageFilter.h" -#include "itkBinaryBallStructuringElement.h" - -int main(int argc, char * argv[]) -{ - - if (argc != 14) - { - std::cerr << "Usage: " << argv[0]; - std::cerr << - " inputFileName outputFileName firstPixelComponent secondPixelComponent "; - std::cerr << - "thirdPixelComponent fourthPixelComponent amplitudeThrehsold tolerance "; - std::cerr << - "angularThreshold firstMeanDistanceThreshold secondMeanDistanceThreshold "; - std::cerr << "distanceThreshold" << std::endl; - return EXIT_FAILURE; - } - - const unsigned int Dimension = 2; - // Software Guide : BeginLatex - // - // Then we must decide what pixel type to use for the image. We choose to do - // all the computation in floating point precision and rescale the results - // between 0 and 255 in order to export PNG images. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - typedef double InputPixelType; - typedef unsigned char OutputPixelType; - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The images are defined using the pixel type and the dimension. Please note that - // the \doxygen{otb}{RoadExtractionFilter} needs an \doxygen{otb}{VectorImage} as input - // to handle multispectral images. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - typedef otb::VectorImage<InputPixelType, Dimension> InputVectorImageType; - typedef otb::Image<InputPixelType, Dimension> InputImageType; - typedef otb::Image<OutputPixelType, Dimension> OutputImageType; - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // We define the type of the polyline that the filter produces. We use the - // \doxygen{otb}{PolyLineParametricPathWithValue}, which allows the filter to produce - // a likehood value along with each polyline. The filter is able to produce - // \doxygen{itk}{PolyLineParametricPath} as well. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - typedef otb::PolyLineParametricPathWithValue<InputPixelType, - Dimension> PathType; - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // Now we can define the \doxygen{otb}{RoadExtractionFilter} that takes a multi-spectral - // image as input and produces a list of polylines. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - typedef otb::RoadExtractionFilter<InputVectorImageType, - PathType> RoadExtractionFilterType; - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // We also define an \doxygen{otb}{DrawPathListFilter} to draw the output - // polylines on an image, taking their likehood values into account. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - typedef otb::DrawPathListFilter<InputImageType, PathType, - InputImageType> DrawPathFilterType; - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The intensity rescaling of the results will be carried out by the - // \doxygen{itk}{RescaleIntensityImageFilter} which is templated by the - // input and output image types. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - typedef itk::RescaleIntensityImageFilter<InputImageType, - OutputImageType> RescalerType; - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // An \doxygen{otb}{ImageFileReader} class is also instantiated in order to read - // image data from a file. Then, an \doxygen{otb}{ImageFileWriter} - // is instantiated in order to write the output image to a file. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - typedef otb::ImageFileReader<InputVectorImageType> ReaderType; - typedef otb::ImageFileWriter<OutputImageType> WriterType; - - // 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 - - ReaderType::Pointer reader = ReaderType::New(); - RoadExtractionFilterType::Pointer roadExtractionFilter - = RoadExtractionFilterType::New(); - DrawPathFilterType::Pointer drawingFilter = DrawPathFilterType::New(); - RescalerType::Pointer rescaleFilter = RescalerType::New(); - WriterType::Pointer writer = WriterType::New(); - - // Software Guide : EndCodeSnippet - - reader->SetFileName(argv[1]); - - // Software Guide : BeginLatex - // - // The \doxygen{otb}{RoadExtractionFilter} needs to have a reference pixel - // corresponding to the spectral content likely to represent a road. This is done - // by passing a pixel to the filter. Here we suppose that the input image - // has four spectral bands. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - InputVectorImageType::PixelType ReferencePixel; - ReferencePixel.SetSize(4); - ReferencePixel.SetElement(0, ::atof(argv[3])); - ReferencePixel.SetElement(1, ::atof(argv[4])); - ReferencePixel.SetElement(2, ::atof(argv[5])); - ReferencePixel.SetElement(3, ::atof(argv[6])); - roadExtractionFilter->SetReferencePixel(ReferencePixel); - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // We must also set the alpha parameter of the filter which allows us to tune the width of the roads - // we want to extract. Typical value is $1.0$ and should be working in most situations. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - roadExtractionFilter->SetAlpha(atof(argv[7])); - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // All other parameter should not influence the results too much in most situation and can - // be kept at the default value. - // - // The amplitude threshold parameter tunes the sensitivity of the vectorization step. A typical - // value is $5 \cdot 10^{-5}$. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - roadExtractionFilter->SetAmplitudeThreshold(atof(argv[8])); - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The tolerance threshold tunes the sensitivity of the path simplification step. - // Typical value is $1.0$. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - roadExtractionFilter->SetTolerance(atof(argv[9])); - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // Roads are not likely to have sharp turns. Therefore we set the max angle parameter, - // as well as the link angular threshold. The value is typicaly $\frac{\pi}{8}$. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - roadExtractionFilter->SetMaxAngle(atof(argv[10])); - roadExtractionFilter->SetAngularThreshold(atof(argv[10])); - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The \doxygen{otb}{RoadExtractionFilter} performs two odd path removing operations at different stage of - // its execution. The first mean distance threshold and the second mean distance threshold set their criterion - // for removal. Path are removed if their mean distance between nodes is to small, since such path coming - // from previous filters are likely to be tortuous. The first removal operation as a typical mean distance - // threshold parameter of $1.0$, and the second of $10.0$. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - roadExtractionFilter->SetFirstMeanDistanceThreshold(atof(argv[11])); - roadExtractionFilter->SetSecondMeanDistanceThreshold(atof(argv[12])); - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The \doxygen{otb}{RoadExtractionFilter} is able to link path whose ends are near - // according to an euclidean distance criterion. The threshold for this distance - // to link a path is the distance threshold parameter. A typical value is $25$. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - roadExtractionFilter->SetDistanceThreshold(atof(argv[13])); - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // We will now create a black background image to draw the resulting polyline on. - // To achieve this we need to know the size of our input image. Therefore we trigger the - // \code{GenerateOutputInformation()} of the reader. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - reader->GenerateOutputInformation(); - InputImageType::Pointer blackBackground = InputImageType::New(); - blackBackground->SetRegions(reader->GetOutput()->GetLargestPossibleRegion()); - blackBackground->Allocate(); - blackBackground->FillBuffer(0); - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // We tell the \doxygen{otb}{DrawPathListFilter} to try to use the likehood value - // embedded within the polyline as a value for drawing this polyline if possible. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - drawingFilter->UseInternalPathValueOn(); - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The \code{itk::RescaleIntensityImageFilter} needs to know which - // is the minimum and maximum values of the output generated - // image. Those can be chosen in a generic way by using the - // \code{NumericTraits} functions, since they are templated over - // the pixel type. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - rescaleFilter->SetOutputMinimum(itk::NumericTraits<OutputPixelType>::min()); - rescaleFilter->SetOutputMaximum(itk::NumericTraits<OutputPixelType>::max()); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // Now it is time for some pipeline wiring. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - roadExtractionFilter->SetInput(reader->GetOutput()); - drawingFilter->SetInput(blackBackground); - drawingFilter->SetInputPath(roadExtractionFilter->GetOutput()); - rescaleFilter->SetInput(drawingFilter->GetOutput()); - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The update of the pipeline is triggered by the \code{Update()} method - // of the rescale intensity filter. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - - rescaleFilter->Update(); - - // Software Guide : EndCodeSnippet - - // output image enhancement - typedef itk::BinaryBallStructuringElement<OutputPixelType, - Dimension> - StructuringElementType; - typedef itk::GrayscaleDilateImageFilter<OutputImageType, OutputImageType, - StructuringElementType> - DilateFilterType; - typedef itk::InvertIntensityImageFilter<OutputImageType, - OutputImageType> - InvertFilterType; - - StructuringElementType se; - se.SetRadius(1); - se.CreateStructuringElement(); - - DilateFilterType::Pointer dilater = DilateFilterType::New(); - - dilater->SetInput(rescaleFilter->GetOutput()); - dilater->SetKernel(se); - - InvertFilterType::Pointer invertFilter = InvertFilterType::New(); - invertFilter->SetInput(dilater->GetOutput()); - - writer->SetFileName(argv[2]); - writer->SetInput(invertFilter->GetOutput()); - writer->Update(); - - // Software Guide : BeginLatex - // - // Figure~\ref{fig:ROADEXTRACTION_FILTER} shows the result of applying - // the road extraction filter to a fusionned Quickbird image. - // \begin{figure} - // \center - // \includegraphics[width=0.44\textwidth]{qb_ExtractRoad_pretty.eps} - // \includegraphics[width=0.44\textwidth]{ExtractRoadOutput.eps} - // \itkcaption[Road extraction filter application]{Result of applying - // the \doxygen{otb}{RoadExtractionFilter} to a fusionned Quickbird - // image. From left to right : original image, extracted road with their - // likehood values (color are inverted for display).} - // \label{fig:ROADEXTRACTION_FILTER} - // \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 + +// Software Guide : BeginCommandLineArgs +// INPUTS: {qb_RoadExtract.tif} +// OUTPUTS: {ExtractRoadOutput.png} +// 337 557 432 859 1.0 0.00005 1.0 0.39269 1.0 10.0 25. +// Software Guide : EndCommandLineArgs + +// Software Guide : BeginLatex +// +// The easiest way to use the road extraction filter provided by OTB is to use the composite +// filter. If a modification in the pipeline is required to adapt to a particular situation, +// the step by step example, described in the next section can be adapted. +// +// This example demonstrates the use of the \doxygen{otb}{RoadExtractionFilter}. +// This filter is a composite filter achieving road extraction according to the algorithm +// adapted by E. Christophe and J. Inglada \cite{Christophe2007} from an original method +// proposed in \cite{Lacroix1998}. +// +// The first step toward the use of this filter is the inclusion of the proper header files. +// +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet + +#include "otbPolyLineParametricPathWithValue.h" +#include "otbRoadExtractionFilter.h" +#include "otbDrawPathListFilter.h" + +// Software Guide : EndCodeSnippet + +#include "otbImage.h" +#include "otbVectorImage.h" +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" +#include "itkRescaleIntensityImageFilter.h" +#include "otbMath.h" + +#include "itkInvertIntensityImageFilter.h" +#include "itkGrayscaleDilateImageFilter.h" +#include "itkBinaryBallStructuringElement.h" + +int main(int argc, char * argv[]) +{ + + if (argc != 14) + { + std::cerr << "Usage: " << argv[0]; + std::cerr << + " inputFileName outputFileName firstPixelComponent secondPixelComponent "; + std::cerr << + "thirdPixelComponent fourthPixelComponent amplitudeThrehsold tolerance "; + std::cerr << + "angularThreshold firstMeanDistanceThreshold secondMeanDistanceThreshold "; + std::cerr << "distanceThreshold" << std::endl; + return EXIT_FAILURE; + } + + const unsigned int Dimension = 2; + // Software Guide : BeginLatex + // + // Then we must decide what pixel type to use for the image. We choose to do + // all the computation in floating point precision and rescale the results + // between 0 and 255 in order to export PNG images. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + typedef double InputPixelType; + typedef unsigned char OutputPixelType; + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // The images are defined using the pixel type and the dimension. Please note that + // the \doxygen{otb}{RoadExtractionFilter} needs an \doxygen{otb}{VectorImage} as input + // to handle multispectral images. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + typedef otb::VectorImage<InputPixelType, Dimension> InputVectorImageType; + typedef otb::Image<InputPixelType, Dimension> InputImageType; + typedef otb::Image<OutputPixelType, Dimension> OutputImageType; + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // We define the type of the polyline that the filter produces. We use the + // \doxygen{otb}{PolyLineParametricPathWithValue}, which allows the filter to produce + // a likehood value along with each polyline. The filter is able to produce + // \doxygen{itk}{PolyLineParametricPath} as well. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + typedef otb::PolyLineParametricPathWithValue<InputPixelType, + Dimension> PathType; + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // Now we can define the \doxygen{otb}{RoadExtractionFilter} that takes a multi-spectral + // image as input and produces a list of polylines. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + typedef otb::RoadExtractionFilter<InputVectorImageType, + PathType> RoadExtractionFilterType; + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // We also define an \doxygen{otb}{DrawPathListFilter} to draw the output + // polylines on an image, taking their likehood values into account. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + typedef otb::DrawPathListFilter<InputImageType, PathType, + InputImageType> DrawPathFilterType; + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // The intensity rescaling of the results will be carried out by the + // \doxygen{itk}{RescaleIntensityImageFilter} which is templated by the + // input and output image types. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + typedef itk::RescaleIntensityImageFilter<InputImageType, + OutputImageType> RescalerType; + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // An \doxygen{otb}{ImageFileReader} class is also instantiated in order to read + // image data from a file. Then, an \doxygen{otb}{ImageFileWriter} + // is instantiated in order to write the output image to a file. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + typedef otb::ImageFileReader<InputVectorImageType> ReaderType; + typedef otb::ImageFileWriter<OutputImageType> WriterType; + + // 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 + + ReaderType::Pointer reader = ReaderType::New(); + RoadExtractionFilterType::Pointer roadExtractionFilter + = RoadExtractionFilterType::New(); + DrawPathFilterType::Pointer drawingFilter = DrawPathFilterType::New(); + RescalerType::Pointer rescaleFilter = RescalerType::New(); + WriterType::Pointer writer = WriterType::New(); + + // Software Guide : EndCodeSnippet + + reader->SetFileName(argv[1]); + + // Software Guide : BeginLatex + // + // The \doxygen{otb}{RoadExtractionFilter} needs to have a reference pixel + // corresponding to the spectral content likely to represent a road. This is done + // by passing a pixel to the filter. Here we suppose that the input image + // has four spectral bands. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + InputVectorImageType::PixelType ReferencePixel; + ReferencePixel.SetSize(4); + ReferencePixel.SetElement(0, ::atof(argv[3])); + ReferencePixel.SetElement(1, ::atof(argv[4])); + ReferencePixel.SetElement(2, ::atof(argv[5])); + ReferencePixel.SetElement(3, ::atof(argv[6])); + roadExtractionFilter->SetReferencePixel(ReferencePixel); + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // We must also set the alpha parameter of the filter which allows us to tune the width of the roads + // we want to extract. Typical value is $1.0$ and should be working in most situations. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + roadExtractionFilter->SetAlpha(atof(argv[7])); + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // All other parameter should not influence the results too much in most situation and can + // be kept at the default value. + // + // The amplitude threshold parameter tunes the sensitivity of the vectorization step. A typical + // value is $5 \cdot 10^{-5}$. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + roadExtractionFilter->SetAmplitudeThreshold(atof(argv[8])); + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // The tolerance threshold tunes the sensitivity of the path simplification step. + // Typical value is $1.0$. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + roadExtractionFilter->SetTolerance(atof(argv[9])); + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // Roads are not likely to have sharp turns. Therefore we set the max angle parameter, + // as well as the link angular threshold. The value is typicaly $\frac{\pi}{8}$. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + roadExtractionFilter->SetMaxAngle(atof(argv[10])); + roadExtractionFilter->SetAngularThreshold(atof(argv[10])); + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // The \doxygen{otb}{RoadExtractionFilter} performs two odd path removing operations at different stage of + // its execution. The first mean distance threshold and the second mean distance threshold set their criterion + // for removal. Path are removed if their mean distance between nodes is to small, since such path coming + // from previous filters are likely to be tortuous. The first removal operation as a typical mean distance + // threshold parameter of $1.0$, and the second of $10.0$. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + roadExtractionFilter->SetFirstMeanDistanceThreshold(atof(argv[11])); + roadExtractionFilter->SetSecondMeanDistanceThreshold(atof(argv[12])); + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // The \doxygen{otb}{RoadExtractionFilter} is able to link path whose ends are near + // according to an euclidean distance criterion. The threshold for this distance + // to link a path is the distance threshold parameter. A typical value is $25$. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + roadExtractionFilter->SetDistanceThreshold(atof(argv[13])); + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // We will now create a black background image to draw the resulting polyline on. + // To achieve this we need to know the size of our input image. Therefore we trigger the + // \code{GenerateOutputInformation()} of the reader. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + reader->GenerateOutputInformation(); + InputImageType::Pointer blackBackground = InputImageType::New(); + blackBackground->SetRegions(reader->GetOutput()->GetLargestPossibleRegion()); + blackBackground->Allocate(); + blackBackground->FillBuffer(0); + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // We tell the \doxygen{otb}{DrawPathListFilter} to try to use the likehood value + // embedded within the polyline as a value for drawing this polyline if possible. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + drawingFilter->UseInternalPathValueOn(); + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // The \code{itk::RescaleIntensityImageFilter} needs to know which + // is the minimum and maximum values of the output generated + // image. Those can be chosen in a generic way by using the + // \code{NumericTraits} functions, since they are templated over + // the pixel type. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + rescaleFilter->SetOutputMinimum(itk::NumericTraits<OutputPixelType>::min()); + rescaleFilter->SetOutputMaximum(itk::NumericTraits<OutputPixelType>::max()); + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // Now it is time for some pipeline wiring. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + roadExtractionFilter->SetInput(reader->GetOutput()); + drawingFilter->SetInput(blackBackground); + drawingFilter->SetInputPath(roadExtractionFilter->GetOutput()); + rescaleFilter->SetInput(drawingFilter->GetOutput()); + + // Software Guide : EndCodeSnippet + + // Software Guide : BeginLatex + // + // The update of the pipeline is triggered by the \code{Update()} method + // of the rescale intensity filter. + // + // Software Guide : EndLatex + + // Software Guide : BeginCodeSnippet + + rescaleFilter->Update(); + + // Software Guide : EndCodeSnippet + + // output image enhancement + typedef itk::BinaryBallStructuringElement<OutputPixelType, + Dimension> + StructuringElementType; + typedef itk::GrayscaleDilateImageFilter<OutputImageType, OutputImageType, + StructuringElementType> + DilateFilterType; + typedef itk::InvertIntensityImageFilter<OutputImageType, + OutputImageType> + InvertFilterType; + + StructuringElementType se; + se.SetRadius(1); + se.CreateStructuringElement(); + + DilateFilterType::Pointer dilater = DilateFilterType::New(); + + dilater->SetInput(rescaleFilter->GetOutput()); + dilater->SetKernel(se); + + InvertFilterType::Pointer invertFilter = InvertFilterType::New(); + invertFilter->SetInput(dilater->GetOutput()); + + writer->SetFileName(argv[2]); + writer->SetInput(invertFilter->GetOutput()); + writer->Update(); + + // Software Guide : BeginLatex + // + // Figure~\ref{fig:ROADEXTRACTION_FILTER} shows the result of applying + // the road extraction filter to a fusionned Quickbird image. + // \begin{figure} + // \center + // \includegraphics[width=0.44\textwidth]{qb_ExtractRoad_pretty.eps} + // \includegraphics[width=0.44\textwidth]{ExtractRoadOutput.eps} + // \itkcaption[Road extraction filter application]{Result of applying + // the \doxygen{otb}{RoadExtractionFilter} to a fusionned Quickbird + // image. From left to right : original image, extracted road with their + // likehood values (color are inverted for display).} + // \label{fig:ROADEXTRACTION_FILTER} + // \end{figure} + // + // Software Guide : EndLatex + + return EXIT_SUCCESS; +} diff --git a/Examples/IO/ImageSeriesIOExample.cxx b/Examples/IO/ImageSeriesIOExample.cxx index f706d02f52..6fc3ae8d80 100644 --- a/Examples/IO/ImageSeriesIOExample.cxx +++ b/Examples/IO/ImageSeriesIOExample.cxx @@ -1,202 +1,202 @@ -/*========================================================================= - - Program: ORFEO Toolbox - Language: C++ - Date: $Date$ - Version: $Revision$ - - - Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. - See OTBCopyright.txt for details. - - Some parts of this code are derived from ITK. See ITKCopyright.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 - -#include <iostream> - -// Software Guide : BeginLatex -// -// This example shows how to read a list of images and concatenate -// them into a vector image. We will write a program which is able to -// perform this operation taking advantage of the streaming -// functionnalities of the processing pipeline. We will assume that -// all the input images have the same size and a single band. -// -// The following header files will be needed: -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "otbImage.h" -#include "otbVectorImage.h" -#include "otbImageFileReader.h" -#include "otbObjectList.h" -#include "otbImageList.h" -#include "otbImageListToVectorImageFilter.h" -#include "otbStreamingImageFileWriter.h" -// Software Guide : EndCodeSnippet - -int main(int argc, char** argv) -{ - if (argc < 4) - { - std::cerr << "Usage: " << argv[0]; - std::cerr << "outputImage image1 image2 ... " << std::endl; - } - - const unsigned int NbImages = argc - 2; - - std::cout << "Concat of " << NbImages << - " images into a multi-band image " << - std::endl; - -// Software Guide : BeginLatex -// -// We will start by defining the types for the input images and the -// associated readers. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - typedef unsigned short int PixelType; - const unsigned int Dimension = 2; - - typedef otb::Image<PixelType, Dimension> InputImageType; - - typedef otb::ImageFileReader<InputImageType> ImageReaderType; -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// We will use a list of image file readers in order to open all the -// input images at once. For this, we use the -// \doxygen{otb}{ObjectList} object and we template it over the type -// of the readers. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - typedef otb::ObjectList<ImageReaderType> ReaderListType; - - ReaderListType::Pointer readerList = ReaderListType::New(); - -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// We will also build a list of input images in order to store the -// smart pointers obtained at the output of each reader. This allows -// us to build a pipeline without really reading the images and using -// lots of RAM. The \doxygen{otb}{ImageList} object will be used. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - typedef otb::ImageList<InputImageType> ImageListType; - - ImageListType::Pointer imageList = ImageListType::New(); - -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// We can now loop over the input image list in order to populate the -// reader list and the input image list. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - for (unsigned int i = 0; i < NbImages; i++) - { - - ImageReaderType::Pointer imageReader = ImageReaderType::New(); - - imageReader->SetFileName(argv[i + 2]); - - std::cout << "Adding image " << argv[i + 2] << std::endl; - - imageReader->UpdateOutputInformation(); - - imageList->PushBack(imageReader->GetOutput()); - - readerList->PushBack(imageReader); - - } - -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// All the input images will be concatenated into a single output -// vector image. For this matter, we will use the -// \doxygen{otb}{ImageListToVectorImageFilter} which is templated -// over the input image list type and the output vector image type. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - typedef otb::VectorImage<PixelType, Dimension> VectorImageType; - - typedef otb::ImageListToVectorImageFilter<ImageListType, VectorImageType> - ImageListToVectorImageFilterType; - - ImageListToVectorImageFilterType::Pointer iL2VI = - ImageListToVectorImageFilterType::New(); - -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// We plug the image list as input of the filter and use a -// \doxygen{otb}{StreamingImageFileWriter} to write the result image -// to a file, so that the streaming capabilities of all the readers -// and the filter are used. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - iL2VI->SetInput(imageList); - - typedef otb::StreamingImageFileWriter<VectorImageType> ImageWriterType; - - ImageWriterType::Pointer imageWriter = ImageWriterType::New(); - - imageWriter->SetFileName(argv[1]); - -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// We can tune the size of the image tiles as a function of the -// number of input images, so that the total memory footprint of the -// pipeline is constant for any execution of the program. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - - unsigned long size = (10000 * 10000 * sizeof(PixelType)) / NbImages; - - std::cout << "Streaming size: " << size << std::endl; - - imageWriter->SetBufferMemorySize(size); - - imageWriter->SetInput(iL2VI->GetOutput()); - - imageWriter->Update(); - -// Software Guide : EndCodeSnippet - - 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. + + Some parts of this code are derived from ITK. See ITKCopyright.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 + +#include <iostream> + +// Software Guide : BeginLatex +// +// This example shows how to read a list of images and concatenate +// them into a vector image. We will write a program which is able to +// perform this operation taking advantage of the streaming +// functionnalities of the processing pipeline. We will assume that +// all the input images have the same size and a single band. +// +// The following header files will be needed: +// +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet +#include "otbImage.h" +#include "otbVectorImage.h" +#include "otbImageFileReader.h" +#include "otbObjectList.h" +#include "otbImageList.h" +#include "otbImageListToVectorImageFilter.h" +#include "otbStreamingImageFileWriter.h" +// Software Guide : EndCodeSnippet + +int main(int argc, char** argv) +{ + if (argc < 4) + { + std::cerr << "Usage: " << argv[0]; + std::cerr << "outputImage image1 image2 ... " << std::endl; + } + + const unsigned int NbImages = argc - 2; + + std::cout << "Concat of " << NbImages << + " images into a multi-band image " << + std::endl; + +// Software Guide : BeginLatex +// +// We will start by defining the types for the input images and the +// associated readers. +// +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet + typedef unsigned short int PixelType; + const unsigned int Dimension = 2; + + typedef otb::Image<PixelType, Dimension> InputImageType; + + typedef otb::ImageFileReader<InputImageType> ImageReaderType; +// Software Guide : EndCodeSnippet + +// Software Guide : BeginLatex +// +// We will use a list of image file readers in order to open all the +// input images at once. For this, we use the +// \doxygen{otb}{ObjectList} object and we template it over the type +// of the readers. +// +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet + typedef otb::ObjectList<ImageReaderType> ReaderListType; + + ReaderListType::Pointer readerList = ReaderListType::New(); + +// Software Guide : EndCodeSnippet + +// Software Guide : BeginLatex +// +// We will also build a list of input images in order to store the +// smart pointers obtained at the output of each reader. This allows +// us to build a pipeline without really reading the images and using +// lots of RAM. The \doxygen{otb}{ImageList} object will be used. +// +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet + typedef otb::ImageList<InputImageType> ImageListType; + + ImageListType::Pointer imageList = ImageListType::New(); + +// Software Guide : EndCodeSnippet + +// Software Guide : BeginLatex +// +// We can now loop over the input image list in order to populate the +// reader list and the input image list. +// +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet + for (unsigned int i = 0; i < NbImages; i++) + { + + ImageReaderType::Pointer imageReader = ImageReaderType::New(); + + imageReader->SetFileName(argv[i + 2]); + + std::cout << "Adding image " << argv[i + 2] << std::endl; + + imageReader->UpdateOutputInformation(); + + imageList->PushBack(imageReader->GetOutput()); + + readerList->PushBack(imageReader); + + } + +// Software Guide : EndCodeSnippet + +// Software Guide : BeginLatex +// +// All the input images will be concatenated into a single output +// vector image. For this matter, we will use the +// \doxygen{otb}{ImageListToVectorImageFilter} which is templated +// over the input image list type and the output vector image type. +// +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet + typedef otb::VectorImage<PixelType, Dimension> VectorImageType; + + typedef otb::ImageListToVectorImageFilter<ImageListType, VectorImageType> + ImageListToVectorImageFilterType; + + ImageListToVectorImageFilterType::Pointer iL2VI = + ImageListToVectorImageFilterType::New(); + +// Software Guide : EndCodeSnippet + +// Software Guide : BeginLatex +// +// We plug the image list as input of the filter and use a +// \doxygen{otb}{StreamingImageFileWriter} to write the result image +// to a file, so that the streaming capabilities of all the readers +// and the filter are used. +// +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet + iL2VI->SetInput(imageList); + + typedef otb::StreamingImageFileWriter<VectorImageType> ImageWriterType; + + ImageWriterType::Pointer imageWriter = ImageWriterType::New(); + + imageWriter->SetFileName(argv[1]); + +// Software Guide : EndCodeSnippet + +// Software Guide : BeginLatex +// +// We can tune the size of the image tiles as a function of the +// number of input images, so that the total memory footprint of the +// pipeline is constant for any execution of the program. +// +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet + + unsigned long size = (10000 * 10000 * sizeof(PixelType)) / NbImages; + + std::cout << "Streaming size: " << size << std::endl; + + imageWriter->SetBufferMemorySize(size); + + imageWriter->SetInput(iL2VI->GetOutput()); + + imageWriter->Update(); + +// Software Guide : EndCodeSnippet + + return EXIT_SUCCESS; +} diff --git a/Testing/Code/SpatialReasoning/otbRCC8VertexBase.cxx b/Testing/Code/SpatialReasoning/otbRCC8VertexBase.cxx index 0f20a8fa0b..440154bf7b 100644 --- a/Testing/Code/SpatialReasoning/otbRCC8VertexBase.cxx +++ b/Testing/Code/SpatialReasoning/otbRCC8VertexBase.cxx @@ -1,104 +1,104 @@ -/*========================================================================= - - 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. - -=========================================================================*/ -#include "itkExceptionObject.h" -#include "otbRCC8VertexBase.h" -#include "otbPolygon.h" -#include "otbMacro.h" - -int otbRCC8VertexBase(int argc, char* argv[]) -{ - typedef otb::Polygon<> PathType; - unsigned int imageLevel = atoi(argv[1]); - bool imageType = atoi(argv[2]); - typedef otb::RCC8VertexBase<PathType> RCC8VertexType; - typedef RCC8VertexType::AttributesMapType AttributesMapType; - // Instantiation - RCC8VertexType::Pointer vertex1 = RCC8VertexType::New(); - - PathType::Pointer path = PathType::New(); - path->Initialize(); - - PathType::ContinuousIndexType p1, p2, p3; - - p1[0] = 0; - p1[1] = 0; - - p2[0] = 10; - p2[1] = 10; - - p3[0] = -5; - p3[1] = 2; - - path->AddVertex(p1); - path->AddVertex(p2); - path->AddVertex(p3); - - // Getters / setters tests - vertex1->SetSegmentationLevel(imageLevel); - vertex1->SetSegmentationType(imageType); - vertex1->SetPath(path); - - otbControlConditionTestMacro(vertex1->GetSegmentationLevel() != imageLevel, - "Test failed: vertex1->GetSegmentationLevel()!=imageLevel"); - otbControlConditionTestMacro(vertex1->GetSegmentationType() != imageType, - "Test failed: vertex1->GetSegmentationType()!=imageType"); - - otbControlConditionTestMacro(vertex1->GetPath()->GetVertexList()->GetElement(0) != p1, - "Test failed:vertex1->GetPath()->GetVertexList()->GetElement(0)!=p1"); - otbControlConditionTestMacro(vertex1->GetPath()->GetVertexList()->GetElement(1) != p2, - "Test failed:vertex1->GetPath()->GetVertexList()->GetElement(1)!=p2"); - otbControlConditionTestMacro(vertex1->GetPath()->GetVertexList()->GetElement(2) != p3, - "Test failed:vertex1->GetPath()->GetVertexList()->GetElement(2)!=p3"); - - // attributes vector set test - AttributesMapType attr1 = vertex1->GetAttributesMap(); - otbControlConditionTestMacro(attr1["SegmentationLevel"].compare(std::string(argv[1])) != 0, - "Test failed: vertex1->GetAttributesMap()[\"SegmentationLevel\"]!=std::string(argv[1])"); - otbControlConditionTestMacro(atoi(attr1["SegmentationType"].c_str()) != static_cast<int>(imageType), - "Test failed:atoi(attr1[\"SegmentationType\"].c_str())!=imageType "); - - otbControlConditionTestMacro(atof(attr1["P0x"].c_str()) != p1[0], - "Test failed: atof(attr1[\"P0x\"].c_str())!=p1[0]"); - otbControlConditionTestMacro(atof(attr1["P0y"].c_str()) != p1[1], - "Test failed: atof(attr1[\"P0y\"].c_str())!=p1[1]"); - otbControlConditionTestMacro(atof(attr1["P1x"].c_str()) != p2[0], - "Test failed: atof(attr1[\"P1x\"].c_str())!=p2[0]"); - otbControlConditionTestMacro(atof(attr1["P1y"].c_str()) != p2[1], - "Test failed: atof(attr1[\"P1y\"].c_str())!=p2[1]"); - otbControlConditionTestMacro(atof(attr1["P2x"].c_str()) != p3[0], - "Test failed: atof(attr1[\"P2x\"].c_str())!=p3[0]"); - otbControlConditionTestMacro(atof(attr1["P2y"].c_str()) != p3[1], - "Test failed: atof( attr1[\"P2y\"].c_str())!=p3[1]"); - - // attributes vector get test - RCC8VertexType::Pointer vertex2 = RCC8VertexType::New(); - vertex2->SetAttributesMap(attr1); - otbControlConditionTestMacro(vertex1->GetSegmentationLevel() != vertex2->GetSegmentationLevel(), - "Test failed: vertex1->GetSegmentationLevel()!=vertex2->GetSegmentationLevel()"); - otbControlConditionTestMacro(vertex1->GetSegmentationType() != vertex2->GetSegmentationType(), - "Test failed: vertex1->GetSegmentationType()!=vertex2->GetSegmentationType()"); - - otbControlConditionTestMacro(vertex2->GetPath()->GetVertexList()->GetElement(0) != p1, - "Test failed:vertex2->GetPath()->GetVertexList()->GetElement(0)!=p1"); - otbControlConditionTestMacro(vertex2->GetPath()->GetVertexList()->GetElement(1) != p2, - "Test failed:vertex2->GetPath()->GetVertexList()->GetElement(1)!=p2"); - otbControlConditionTestMacro(vertex2->GetPath()->GetVertexList()->GetElement(2) != p3, - "Test failed:vertex2->GetPath()->GetVertexList()->GetElement(2)!=p3"); - - 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. + +=========================================================================*/ +#include "itkExceptionObject.h" +#include "otbRCC8VertexBase.h" +#include "otbPolygon.h" +#include "otbMacro.h" + +int otbRCC8VertexBase(int argc, char* argv[]) +{ + typedef otb::Polygon<> PathType; + unsigned int imageLevel = atoi(argv[1]); + bool imageType = atoi(argv[2]); + typedef otb::RCC8VertexBase<PathType> RCC8VertexType; + typedef RCC8VertexType::AttributesMapType AttributesMapType; + // Instantiation + RCC8VertexType::Pointer vertex1 = RCC8VertexType::New(); + + PathType::Pointer path = PathType::New(); + path->Initialize(); + + PathType::ContinuousIndexType p1, p2, p3; + + p1[0] = 0; + p1[1] = 0; + + p2[0] = 10; + p2[1] = 10; + + p3[0] = -5; + p3[1] = 2; + + path->AddVertex(p1); + path->AddVertex(p2); + path->AddVertex(p3); + + // Getters / setters tests + vertex1->SetSegmentationLevel(imageLevel); + vertex1->SetSegmentationType(imageType); + vertex1->SetPath(path); + + otbControlConditionTestMacro(vertex1->GetSegmentationLevel() != imageLevel, + "Test failed: vertex1->GetSegmentationLevel()!=imageLevel"); + otbControlConditionTestMacro(vertex1->GetSegmentationType() != imageType, + "Test failed: vertex1->GetSegmentationType()!=imageType"); + + otbControlConditionTestMacro(vertex1->GetPath()->GetVertexList()->GetElement(0) != p1, + "Test failed:vertex1->GetPath()->GetVertexList()->GetElement(0)!=p1"); + otbControlConditionTestMacro(vertex1->GetPath()->GetVertexList()->GetElement(1) != p2, + "Test failed:vertex1->GetPath()->GetVertexList()->GetElement(1)!=p2"); + otbControlConditionTestMacro(vertex1->GetPath()->GetVertexList()->GetElement(2) != p3, + "Test failed:vertex1->GetPath()->GetVertexList()->GetElement(2)!=p3"); + + // attributes vector set test + AttributesMapType attr1 = vertex1->GetAttributesMap(); + otbControlConditionTestMacro(attr1["SegmentationLevel"].compare(std::string(argv[1])) != 0, + "Test failed: vertex1->GetAttributesMap()[\"SegmentationLevel\"]!=std::string(argv[1])"); + otbControlConditionTestMacro(atoi(attr1["SegmentationType"].c_str()) != static_cast<int>(imageType), + "Test failed:atoi(attr1[\"SegmentationType\"].c_str())!=imageType "); + + otbControlConditionTestMacro(atof(attr1["P0x"].c_str()) != p1[0], + "Test failed: atof(attr1[\"P0x\"].c_str())!=p1[0]"); + otbControlConditionTestMacro(atof(attr1["P0y"].c_str()) != p1[1], + "Test failed: atof(attr1[\"P0y\"].c_str())!=p1[1]"); + otbControlConditionTestMacro(atof(attr1["P1x"].c_str()) != p2[0], + "Test failed: atof(attr1[\"P1x\"].c_str())!=p2[0]"); + otbControlConditionTestMacro(atof(attr1["P1y"].c_str()) != p2[1], + "Test failed: atof(attr1[\"P1y\"].c_str())!=p2[1]"); + otbControlConditionTestMacro(atof(attr1["P2x"].c_str()) != p3[0], + "Test failed: atof(attr1[\"P2x\"].c_str())!=p3[0]"); + otbControlConditionTestMacro(atof(attr1["P2y"].c_str()) != p3[1], + "Test failed: atof( attr1[\"P2y\"].c_str())!=p3[1]"); + + // attributes vector get test + RCC8VertexType::Pointer vertex2 = RCC8VertexType::New(); + vertex2->SetAttributesMap(attr1); + otbControlConditionTestMacro(vertex1->GetSegmentationLevel() != vertex2->GetSegmentationLevel(), + "Test failed: vertex1->GetSegmentationLevel()!=vertex2->GetSegmentationLevel()"); + otbControlConditionTestMacro(vertex1->GetSegmentationType() != vertex2->GetSegmentationType(), + "Test failed: vertex1->GetSegmentationType()!=vertex2->GetSegmentationType()"); + + otbControlConditionTestMacro(vertex2->GetPath()->GetVertexList()->GetElement(0) != p1, + "Test failed:vertex2->GetPath()->GetVertexList()->GetElement(0)!=p1"); + otbControlConditionTestMacro(vertex2->GetPath()->GetVertexList()->GetElement(1) != p2, + "Test failed:vertex2->GetPath()->GetVertexList()->GetElement(1)!=p2"); + otbControlConditionTestMacro(vertex2->GetPath()->GetVertexList()->GetElement(2) != p3, + "Test failed:vertex2->GetPath()->GetVertexList()->GetElement(2)!=p3"); + + return EXIT_SUCCESS; +} -- GitLab