diff --git a/Code/ChangeDetection/otbCBAMI.h b/Code/ChangeDetection/otbCBAMI.h new file mode 100644 index 0000000000000000000000000000000000000000..3980902a4251b8a2c91fce7f92447b2e11b8a327 --- /dev/null +++ b/Code/ChangeDetection/otbCBAMI.h @@ -0,0 +1,281 @@ +/*========================================================================= + + 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 __otbCBAMI_h +#define __otbCBAMI_h + +#include <vector> +#include <stdlib.h> +#include <math.h> + + +namespace otb +{ + +// #define EPSILON_VALUE_CBAMI 0.01 +#define epsilon 0.01 + +namespace Functor +{ + +template< class TInput1, class TInput2, class TOutput> +class CBAMI +{ +public: + + typedef typename std::vector<TOutput> VectorType; + typedef typename VectorType::iterator IteratorType; + typedef typename std::vector<VectorType> VectorOfVectorType; + typedef typename VectorOfVectorType::iterator VecOfVecIteratorType; + + CBAMI() {}; + virtual ~CBAMI() {}; + inline TOutput operator()( const TInput1 & itA, + const TInput2 & itB) + { + //const double epsilon = 0.01; + VectorType vecA; + VectorType vecB; + + for (unsigned long pos = 0; pos< itA.Size(); ++pos) + { + + vecA.push_back(static_cast<double>(itA.GetPixel(pos))); + vecB.push_back(static_cast<double>(itB.GetPixel(pos))); + + } + + normalizeInPlace(vecA); + normalizeInPlace(vecB); + + return static_cast<TOutput>( - vcl_log(PhiMI(vecA, vecB)+epsilon) ); + } + +protected: + + inline void normalizeInPlace(VectorType vx) + { + + TOutput Ex = 0.0; + + IteratorType itx; + + for ( itx = vx.begin(); itx < vx.end(); ++itx) + { + Ex += static_cast<TOutput>(*itx); + } + + Ex /= (vx.size()); + + TOutput Vx = 0.0; + + for ( itx = vx.begin(); itx < vx.end(); ++itx) + { + Vx += static_cast<TOutput>(vcl_pow(static_cast<double>((*itx)-Ex),2)); + } + + Vx /= (vx.size()); + + for ( itx = vx.begin(); itx < vx.end(); ++itx) + { + (*itx) = ((*itx)-Ex)/vcl_sqrt(Vx); + } + + + } + inline TOutput Exyc(VectorType vx, VectorType vy) + { + + TOutput Exy = 0.0; + TOutput Ex = 0.0; + TOutput Ey = 0.0; + + IteratorType itx; + IteratorType ity; + + for ( itx = vx.begin(), ity = vy.begin(); itx < vx.end(); ++itx, ++ity) + { + //Ex += (*itx); + //Ey += (*ity); + Exy += (*itx)*(*ity); + + } + + //Ex /= (vx.size()); + //Ey /= (vy.size()); + Exy /= (vx.size()); + + return Exy-Ex*Ey; + } + + inline TOutput Exyztc(VectorType vx, VectorType vy, VectorType vz, VectorType vt) + { + + TOutput Exyzt = 0.0; + + TOutput Exyz = 0.0; + TOutput Exyt = 0.0; + TOutput Exzt = 0.0; + TOutput Eyzt = 0.0; + + TOutput Exy = 0.0; + TOutput Exz = 0.0; + TOutput Ext = 0.0; + TOutput Eyz = 0.0; + TOutput Eyt = 0.0; + TOutput Ezt = 0.0; + + TOutput Ex = 0.0; + TOutput Ey = 0.0; + TOutput Ez = 0.0; + TOutput Et = 0.0; + + + IteratorType itx; + IteratorType ity; + IteratorType itz; + IteratorType itt; + + for ( itx = vx.begin(), + ity = vy.begin(), + itz = vz.begin(), + itt = vt.begin(); + itx < vx.end(); + ++itx, + ++ity, + itz++, + itt++) + { + //Ex += (*itx); + //Ey += (*ity); + //Ez += (*itz); + //Et += (*itt); + + Exy += (*itx)*(*ity); + Exz += (*itx)*(*itz); + Ext += (*itx)*(*itt); + Eyz += (*ity)*(*itz); + Eyt += (*ity)*(*itt); + Ezt += (*itz)*(*itt); + + Exyz += (*itx)*(*ity)*(*itz); + Exyt += (*itx)*(*ity)*(*itt); + Exzt += (*itx)*(*itz)*(*itt); + Eyzt += (*ity)*(*itz)*(*itt); + + Exyzt += (*itx)*(*ity)*(*itz)*(*itt); + + } + + /*Ex /= (vx.size()); + Ey /= (vx.size()); + Ez /= (vx.size()); + Et /= (vx.size()); */ + + Exy /= (vx.size()); + Exz /= (vx.size()); + Ext /= (vx.size()); + Eyz /= (vx.size()); + Eyt /= (vx.size()); + Ezt /= (vx.size()); + + Exyz /= (vx.size()); + Exyt /= (vx.size()); + Exzt /= (vx.size()); + Eyzt /= (vx.size()); + + + TOutput result = Exyzt - Exyz*Et- Exyt*Ez- Exzt*Ey- Eyzt*Ex + + Exy*Ez*Et + Exz*Et*Ey + Ext*Ey*Ez + Eyz*Et*Ex + Eyt*Ex*Ez + Ezt*Ex*Ey - + 3*Ex*Ey*Ez*Et; + + return result; + } + + inline TOutput Rxy(VectorType va, VectorType vb) + { + + return Exyc(va, vb); + + } + + inline TOutput Qxijkl(VectorType va, VectorType vb, VectorType vc, VectorType vd) + { +// IteratorType ita; +// IteratorType itb; +// IteratorType itc; +// IteratorType itd; + + + TOutput Eabcd_c = Exyztc(va, vb, vc, vd); + + + TOutput Eab_c = Exyc(va, vb); + TOutput Eac_c = Exyc(va, vc); + TOutput Ead_c = Exyc(va, vd); + TOutput Ecd_c = Exyc(vc, vd); + TOutput Ebd_c = Exyc(vb, vd); + TOutput Ebc_c = Exyc(vb, vc); + + return Eabcd_c - Eab_c*Ecd_c - Eac_c*Ebd_c - Ead_c*Ebc_c; + + + + + } + + inline TOutput PhiMI(VectorType v1, VectorType v2) + { + + + VectorOfVectorType donnees; + donnees.push_back(v1); + donnees.push_back(v2); + + VecOfVecIteratorType iti; + VecOfVecIteratorType itj; + VecOfVecIteratorType itk; + VecOfVecIteratorType itl; + + TOutput termeR = 0.0; + TOutput termeQ = 0.0; + + for ( iti = donnees.begin(); iti < donnees.end(); ++iti ) + for ( itj = donnees.begin(); itj < donnees.end(); ++itj ) + { + if (iti != itj) + termeR += static_cast<TOutput>(vcl_pow(static_cast<double>(Rxy((*iti),(*itj))),2)); + + for ( itk = donnees.begin(); itk < donnees.end(); ++itk ) + for ( itl = donnees.begin(); itl < donnees.end(); itl++ ) + { + if ((iti != itj) || (iti != itk) || (iti != itl)) + termeQ += static_cast<TOutput>(vcl_pow( static_cast<double>(Qxijkl((*iti),(*itj),(*itk),(*itl))),2)); + } + } + + + return 1.0/4.0*termeR + 1.0/48.0*termeQ; + + } + +}; +} + +} + +#endif diff --git a/Code/ChangeDetection/otbCBAMIChangeDetector.h b/Code/ChangeDetection/otbCBAMIChangeDetector.h index 339f1b79529ef3a7a76fd5878c2d23772e4c3bdf..e077237c092c8d901b25abc844dd37a4dc96894c 100644 --- a/Code/ChangeDetection/otbCBAMIChangeDetector.h +++ b/Code/ChangeDetection/otbCBAMIChangeDetector.h @@ -20,9 +20,7 @@ #include "otbBinaryFunctorNeighborhoodImageFilter.h" -#include <vector> -#include <stdlib.h> -#include <math.h> +#include "otbCBAMI.h" namespace otb @@ -53,255 +51,6 @@ namespace otb * \ingroup IntensityImageFilters Multithreaded */ -// #define EPSILON_VALUE_CBAMI 0.01 - -namespace Functor -{ - -template< class TInput1, class TInput2, class TOutput> -class CBAMI -{ -public: - - typedef typename std::vector<TOutput> VectorType; - typedef typename VectorType::iterator IteratorType; - typedef typename std::vector<VectorType> VectorOfVectorType; - typedef typename VectorOfVectorType::iterator VecOfVecIteratorType; - - CBAMI() {}; - virtual ~CBAMI() {}; - inline TOutput operator()( const TInput1 & itA, - const TInput2 & itB) - { - const double epsilon = 0.01; - VectorType vecA; - VectorType vecB; - - for (unsigned long pos = 0; pos< itA.Size(); ++pos) - { - - vecA.push_back(static_cast<TOutput>(itA.GetPixel(pos))); - vecB.push_back(static_cast<TOutput>(itB.GetPixel(pos))); - - } - - normalizeInPlace(vecA); - normalizeInPlace(vecB); - - return static_cast<TOutput>( - vcl_log(PhiMI(vecA, vecB)+epsilon) ); - } - -protected: - - inline void normalizeInPlace(VectorType vx) - { - - TOutput Ex = 0.0; - - IteratorType itx; - - for ( itx = vx.begin(); itx < vx.end(); ++itx) - { - Ex += (*itx); - } - - Ex /= (vx.size()); - - TOutput Vx = 0.0; - - for ( itx = vx.begin(); itx < vx.end(); ++itx) - { - Vx += vcl_pow((*itx)-Ex,2); - } - - Vx /= (vx.size()); - - for ( itx = vx.begin(); itx < vx.end(); ++itx) - { - (*itx) = ((*itx)-Ex)/vcl_sqrt(Vx); - } - - - } - inline TOutput Exyc(VectorType vx, VectorType vy) - { - - TOutput Exy = 0.0; - TOutput Ex = 0.0; - TOutput Ey = 0.0; - - IteratorType itx; - IteratorType ity; - - for ( itx = vx.begin(), ity = vy.begin(); itx < vx.end(); ++itx, ++ity) - { - //Ex += (*itx); - //Ey += (*ity); - Exy += (*itx)*(*ity); - - } - - //Ex /= (vx.size()); - //Ey /= (vy.size()); - Exy /= (vx.size()); - - return Exy-Ex*Ey; - } - - inline TOutput Exyztc(VectorType vx, VectorType vy, VectorType vz, VectorType vt) - { - - TOutput Exyzt = 0.0; - - TOutput Exyz = 0.0; - TOutput Exyt = 0.0; - TOutput Exzt = 0.0; - TOutput Eyzt = 0.0; - - TOutput Exy = 0.0; - TOutput Exz = 0.0; - TOutput Ext = 0.0; - TOutput Eyz = 0.0; - TOutput Eyt = 0.0; - TOutput Ezt = 0.0; - - TOutput Ex = 0.0; - TOutput Ey = 0.0; - TOutput Ez = 0.0; - TOutput Et = 0.0; - - - IteratorType itx; - IteratorType ity; - IteratorType itz; - IteratorType itt; - - for ( itx = vx.begin(), - ity = vy.begin(), - itz = vz.begin(), - itt = vt.begin(); - itx < vx.end(); - ++itx, - ++ity, - itz++, - itt++) - { - //Ex += (*itx); - //Ey += (*ity); - //Ez += (*itz); - //Et += (*itt); - - Exy += (*itx)*(*ity); - Exz += (*itx)*(*itz); - Ext += (*itx)*(*itt); - Eyz += (*ity)*(*itz); - Eyt += (*ity)*(*itt); - Ezt += (*itz)*(*itt); - - Exyz += (*itx)*(*ity)*(*itz); - Exyt += (*itx)*(*ity)*(*itt); - Exzt += (*itx)*(*itz)*(*itt); - Eyzt += (*ity)*(*itz)*(*itt); - - Exyzt += (*itx)*(*ity)*(*itz)*(*itt); - - } - - /*Ex /= (vx.size()); - Ey /= (vx.size()); - Ez /= (vx.size()); - Et /= (vx.size()); */ - - Exy /= (vx.size()); - Exz /= (vx.size()); - Ext /= (vx.size()); - Eyz /= (vx.size()); - Eyt /= (vx.size()); - Ezt /= (vx.size()); - - Exyz /= (vx.size()); - Exyt /= (vx.size()); - Exzt /= (vx.size()); - Eyzt /= (vx.size()); - - - TOutput result = Exyzt - Exyz*Et- Exyt*Ez- Exzt*Ey- Eyzt*Ex + - Exy*Ez*Et + Exz*Et*Ey + Ext*Ey*Ez + Eyz*Et*Ex + Eyt*Ex*Ez + Ezt*Ex*Ey - - 3*Ex*Ey*Ez*Et; - - return result; - } - - inline TOutput Rxy(VectorType va, VectorType vb) - { - - return Exyc(va, vb); - - } - - inline TOutput Qxijkl(VectorType va, VectorType vb, VectorType vc, VectorType vd) - { -// IteratorType ita; -// IteratorType itb; -// IteratorType itc; -// IteratorType itd; - - - TOutput Eabcd_c = Exyztc(va, vb, vc, vd); - - - TOutput Eab_c = Exyc(va, vb); - TOutput Eac_c = Exyc(va, vc); - TOutput Ead_c = Exyc(va, vd); - TOutput Ecd_c = Exyc(vc, vd); - TOutput Ebd_c = Exyc(vb, vd); - TOutput Ebc_c = Exyc(vb, vc); - - return Eabcd_c - Eab_c*Ecd_c - Eac_c*Ebd_c - Ead_c*Ebc_c; - - - - - } - - inline TOutput PhiMI(VectorType v1, VectorType v2) - { - - - VectorOfVectorType donnees; - donnees.push_back(v1); - donnees.push_back(v2); - - VecOfVecIteratorType iti; - VecOfVecIteratorType itj; - VecOfVecIteratorType itk; - VecOfVecIteratorType itl; - - TOutput termeR = 0.0; - TOutput termeQ = 0.0; - - for ( iti = donnees.begin(); iti < donnees.end(); ++iti ) - for ( itj = donnees.begin(); itj < donnees.end(); ++itj ) - { - if (iti != itj) - termeR += vcl_pow(Rxy((*iti),(*itj)),2); - - for ( itk = donnees.begin(); itk < donnees.end(); ++itk ) - for ( itl = donnees.begin(); itl < donnees.end(); itl++ ) - { - if ((iti != itj) || (iti != itk) || (iti != itl)) - termeQ += vcl_pow( Qxijkl((*iti),(*itj),(*itk),(*itl)),2); - } - } - - - return 1.0/4.0*termeR + 1.0/48.0*termeQ; - - } - -}; -} - template <class TInputImage1, class TInputImage2, class TOutputImage> class ITK_EXPORT CBAMIChangeDetector : public BinaryFunctorNeighborhoodImageFilter< diff --git a/Code/ChangeDetection/otbCorrelationChangeDetector.h b/Code/ChangeDetection/otbCorrelationChangeDetector.h index b2b252938ba637fbd6a99fde329035d24e5b518e..147e51849e931c22a67487bcdd0bc07b9c120c14 100644 --- a/Code/ChangeDetection/otbCorrelationChangeDetector.h +++ b/Code/ChangeDetection/otbCorrelationChangeDetector.h @@ -19,6 +19,7 @@ #define __otbCorrelationChangeDetector_h #include "otbBinaryFunctorNeighborhoodImageFilter.h" +#include "otbCrossCorrelation.h" namespace otb { @@ -46,65 +47,6 @@ namespace otb * * \ingroup IntensityImageFilters Multithreaded */ -namespace Functor -{ - -template< class TInput1, class TInput2, class TOutput> -class CrossCorrelation -{ -public: - CrossCorrelation() {}; - virtual ~CrossCorrelation() {}; - inline TOutput operator()( const TInput1 & itA, - const TInput2 & itB) - { - - TOutput meanA = itk::NumericTraits<TOutput>::Zero; - TOutput meanB = itk::NumericTraits<TOutput>::Zero; - - for (unsigned long pos = 0; pos< itA.Size(); ++pos) - { - - meanA += static_cast<TOutput>(itA.GetPixel(pos)); - meanB += static_cast<TOutput>(itB.GetPixel(pos)); - - - } - - meanA /= itA.Size(); - meanB /= itB.Size(); - - TOutput varA = itk::NumericTraits<TOutput>::Zero; - TOutput varB = itk::NumericTraits<TOutput>::Zero; - - for (unsigned long pos = 0; pos< itA.Size(); ++pos) - { - - varA += static_cast<TOutput>( vcl_pow( static_cast<double>(itA.GetPixel(pos))-static_cast<double>(meanA),static_cast<double>(2.0))); - varB += static_cast<TOutput>( vcl_pow( static_cast<double>(itB.GetPixel(pos))-static_cast<double>(meanB),static_cast<double>(2.0))); - - } - - varA /= itA.Size(); - varB /= itB.Size(); - - TOutput crossCorrel = itk::NumericTraits<TOutput>::Zero; - - if (varA!= itk::NumericTraits<TOutput>::Zero && varB!= itk::NumericTraits<TOutput>::Zero) - { - for (unsigned long pos = 0; pos< itA.Size(); ++pos) - { - crossCorrel += (static_cast<TOutput>(itA.GetPixel(pos))-meanA)*(static_cast<TOutput>(itB.GetPixel(pos))-meanB)/(itA.Size()*vcl_sqrt(varA*varB)); - } - } - else if (varA==itk::NumericTraits<TOutput>::Zero && varB==itk::NumericTraits<TOutput>::Zero) - { - crossCorrel = itk::NumericTraits<TOutput>::One; - } - return static_cast<TOutput>( itk::NumericTraits<TOutput>::One - crossCorrel ); - } -}; -} template <class TInputImage1, class TInputImage2, class TOutputImage> class ITK_EXPORT CorrelationChangeDetector : diff --git a/Code/ChangeDetection/otbCrossCorrelation.h b/Code/ChangeDetection/otbCrossCorrelation.h new file mode 100644 index 0000000000000000000000000000000000000000..7d179ff353815c322f3d62f8a65587082e84be59 --- /dev/null +++ b/Code/ChangeDetection/otbCrossCorrelation.h @@ -0,0 +1,101 @@ +/*========================================================================= + + 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 __otbCrossCorrelation_h +#define __otbCrossCorrelationChangeDetector_h + + +namespace otb +{ + + +namespace Functor +{ + +/** \class Functor::CrossCorrelation + * + * - cast the input 1 pixel value to \c double + * - cast the input 2 pixel value to \c double + * - compute the difference of the two pixel values + * - compute the value of the cross-correlation + * - cast the \c double value resulting to the pixel type of the output image + * - store the casted value into the output image. + * + */ + + +template< class TInput1, class TInput2, class TOutput> +class CrossCorrelation +{ +public: + CrossCorrelation() {}; + virtual ~CrossCorrelation() {}; + inline TOutput operator()( const TInput1 & itA, + const TInput2 & itB) + { + + TOutput meanA = itk::NumericTraits<TOutput>::Zero; + TOutput meanB = itk::NumericTraits<TOutput>::Zero; + + for (unsigned long pos = 0; pos< itA.Size(); ++pos) + { + + meanA += static_cast<TOutput>(itA.GetPixel(pos)); + meanB += static_cast<TOutput>(itB.GetPixel(pos)); + + + } + + meanA /= itA.Size(); + meanB /= itB.Size(); + + TOutput varA = itk::NumericTraits<TOutput>::Zero; + TOutput varB = itk::NumericTraits<TOutput>::Zero; + + for (unsigned long pos = 0; pos< itA.Size(); ++pos) + { + + varA += static_cast<TOutput>( vcl_pow( static_cast<double>(itA.GetPixel(pos))-static_cast<double>(meanA),static_cast<double>(2.0))); + varB += static_cast<TOutput>( vcl_pow( static_cast<double>(itB.GetPixel(pos))-static_cast<double>(meanB),static_cast<double>(2.0))); + + } + + varA /= itA.Size(); + varB /= itB.Size(); + + TOutput crossCorrel = itk::NumericTraits<TOutput>::Zero; + + if (varA!= itk::NumericTraits<TOutput>::Zero && varB!= itk::NumericTraits<TOutput>::Zero) + { + for (unsigned long pos = 0; pos< itA.Size(); ++pos) + { + crossCorrel += (static_cast<TOutput>(itA.GetPixel(pos))-meanA)*(static_cast<TOutput>(itB.GetPixel(pos))-meanB)/(itA.Size()*vcl_sqrt(varA*varB)); + } + } + else if (varA==itk::NumericTraits<TOutput>::Zero && varB==itk::NumericTraits<TOutput>::Zero) + { + crossCorrel = itk::NumericTraits<TOutput>::One; + } + return static_cast<TOutput>( itk::NumericTraits<TOutput>::One - crossCorrel ); + } +}; +} + +} // end namespace otb + + +#endif diff --git a/Code/ChangeDetection/otbJoinHistogramMI.h b/Code/ChangeDetection/otbJoinHistogramMI.h new file mode 100644 index 0000000000000000000000000000000000000000..35eeef25f1ef98a4c0f39cadca2d3a45d97b8e1e --- /dev/null +++ b/Code/ChangeDetection/otbJoinHistogramMI.h @@ -0,0 +1,136 @@ +/*========================================================================= + + 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 __otbJoinHistogramMI_h +#define __otbJoinHistogramMI_h + +#include "itkHistogram.h" + +namespace otb +{ + +namespace Functor +{ + +template< class TInput1, class TInput2, class TOutput> +class JoinHistogramMI +{ +public: + typedef double HistogramFrequencyType; + typedef typename itk::Statistics::Histogram<HistogramFrequencyType, 2> HistogramType; + JoinHistogramMI() {}; + virtual ~JoinHistogramMI() {}; + inline TOutput operator()( const TInput1 & itA, + const TInput2 & itB, const HistogramType* histogram) + { + TOutput jointEntropy = itk::NumericTraits<TOutput>::Zero; + HistogramFrequencyType totalFreq = histogram->GetTotalFrequency(); + + /* for(unsigned long pos = 0; pos< itA.Size(); ++pos) + { + double value = static_cast<double>(itA.GetPixel(pos)); + + unsigned int bin = + HistogramFrequencyType freq = histogram.GetFrequency(, 0); + if (freq > 0) + { + entropyX += freq*vcl_log(freq); + } + } + + entropyX = -entropyX/static_cast<TOutput>(totalFreq) + vcl_log(totalFreq); + + for (unsigned int i = 0; i < this->GetHistogramSize()[1]; ++i) + { + HistogramFrequencyType freq = histogram.GetFrequency(i, 1); + if (freq > 0) + { + entropyY += freq*vcl_log(freq); + } + } + + entropyY = -entropyY/static_cast<TOutput>(totalFreq) + vcl_log(totalFreq); + + HistogramIteratorType it = histogram.Begin(); + HistogramIteratorType end = histogram.End(); + while (it != end) + { + HistogramFrequencyType freq = it.GetFrequency(); + if (freq > 0) + { + jointEntropy += freq*vcl_log(freq); + } + ++it; + } + + jointEntropy = -jointEntropy/static_cast<TOutput>(totalFreq) + + vcl_log(totalFreq); + + return entropyX + entropyY - jointEntropy;*/ + + + typename HistogramType::MeasurementVectorType sample; + for (unsigned long pos = 0; pos< itA.Size(); ++pos) + { + double valueA = static_cast<double>(itA.GetPixel(pos)); + double valueB = static_cast<double>(itB.GetPixel(pos)); + + sample[0] = valueA; + sample[1] = valueB; + + + HistogramFrequencyType freq = histogram->GetFrequency( + histogram->GetIndex(sample)); + if (freq > 0) + { + jointEntropy += freq*vcl_log(freq); + } + + } + + jointEntropy = -jointEntropy/static_cast<TOutput>(totalFreq) + + vcl_log(totalFreq); + + return jointEntropy; + + /* TOutput meanA = 0.0; + TOutput meanB = 0.0; + + for(unsigned long pos = 0; pos< itA.Size(); ++pos) + { + + meanA += static_cast<TOutput>(itA.GetPixel(pos)); + meanB += static_cast<TOutput>(itB.GetPixel(pos)); + + + }*/ + return static_cast<TOutput>( 0 ); + } + + /* void SetHistogram(HistogramType* histo) + { + m_Histogram = histo; + } + + protected: + HistogramType::Pointer m_Histogram;*/ +}; +} +} // end namespace otb + + +#endif diff --git a/Code/ChangeDetection/otbJoinHistogramMIImageFilter.h b/Code/ChangeDetection/otbJoinHistogramMIImageFilter.h index 65e59e853836f85d84adcc86d076055562feff99..3117a2bba829983312f52e7d0acd65a5fb252312 100644 --- a/Code/ChangeDetection/otbJoinHistogramMIImageFilter.h +++ b/Code/ChangeDetection/otbJoinHistogramMIImageFilter.h @@ -20,6 +20,7 @@ #include "otbBinaryFunctorNeighborhoodJoinHistogramImageFilter.h" #include "itkHistogram.h" +#include "otbJoinHistogramMI.h" namespace otb { @@ -48,113 +49,7 @@ namespace otb * * \ingroup IntensityImageFilters Multithreaded */ -namespace Functor -{ -template< class TInput1, class TInput2, class TOutput> -class JoinHistogramMI -{ -public: - typedef double HistogramFrequencyType; - typedef typename itk::Statistics::Histogram<HistogramFrequencyType, 2> HistogramType; - JoinHistogramMI() {}; - virtual ~JoinHistogramMI() {}; - inline TOutput operator()( const TInput1 & itA, - const TInput2 & itB, const HistogramType* histogram) - { - TOutput jointEntropy = itk::NumericTraits<TOutput>::Zero; - HistogramFrequencyType totalFreq = histogram->GetTotalFrequency(); - - /* for(unsigned long pos = 0; pos< itA.Size(); ++pos) - { - double value = static_cast<double>(itA.GetPixel(pos)); - - unsigned int bin = - HistogramFrequencyType freq = histogram.GetFrequency(, 0); - if (freq > 0) - { - entropyX += freq*vcl_log(freq); - } - } - - entropyX = -entropyX/static_cast<TOutput>(totalFreq) + vcl_log(totalFreq); - - for (unsigned int i = 0; i < this->GetHistogramSize()[1]; ++i) - { - HistogramFrequencyType freq = histogram.GetFrequency(i, 1); - if (freq > 0) - { - entropyY += freq*vcl_log(freq); - } - } - - entropyY = -entropyY/static_cast<TOutput>(totalFreq) + vcl_log(totalFreq); - - HistogramIteratorType it = histogram.Begin(); - HistogramIteratorType end = histogram.End(); - while (it != end) - { - HistogramFrequencyType freq = it.GetFrequency(); - if (freq > 0) - { - jointEntropy += freq*vcl_log(freq); - } - ++it; - } - - jointEntropy = -jointEntropy/static_cast<TOutput>(totalFreq) + - vcl_log(totalFreq); - - return entropyX + entropyY - jointEntropy;*/ - - - typename HistogramType::MeasurementVectorType sample; - for (unsigned long pos = 0; pos< itA.Size(); ++pos) - { - double valueA = static_cast<double>(itA.GetPixel(pos)); - double valueB = static_cast<double>(itB.GetPixel(pos)); - - sample[0] = valueA; - sample[1] = valueB; - - - HistogramFrequencyType freq = histogram->GetFrequency( - histogram->GetIndex(sample)); - if (freq > 0) - { - jointEntropy += freq*vcl_log(freq); - } - - } - - jointEntropy = -jointEntropy/static_cast<TOutput>(totalFreq) + - vcl_log(totalFreq); - - return jointEntropy; - - /* TOutput meanA = 0.0; - TOutput meanB = 0.0; - - for(unsigned long pos = 0; pos< itA.Size(); ++pos) - { - - meanA += static_cast<TOutput>(itA.GetPixel(pos)); - meanB += static_cast<TOutput>(itB.GetPixel(pos)); - - - }*/ - return static_cast<TOutput>( 0 ); - } - - /* void SetHistogram(HistogramType* histo) - { - m_Histogram = histo; - } - - protected: - HistogramType::Pointer m_Histogram;*/ -}; -} template <class TInputImage1, class TInputImage2, class TOutputImage> class ITK_EXPORT JoinHistogramMIImageFilter : diff --git a/Code/ChangeDetection/otbLHMI.h b/Code/ChangeDetection/otbLHMI.h new file mode 100644 index 0000000000000000000000000000000000000000..b2fbae9b313d4fc238dbba2512a08f38587d08d1 --- /dev/null +++ b/Code/ChangeDetection/otbLHMI.h @@ -0,0 +1,179 @@ +/*========================================================================= + + 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 __otbLHMI_h +#define __otbLHMI_h + +#include <vector> +#include <stdlib.h> +#include <math.h> +#include "itkHistogram.h" + + +namespace otb +{ + + +#define epsilon 0.01 + +namespace Functor +{ + +template< class TInput1, class TInput2, class TOutput> +class LHMI +{ + +public: + + typedef typename std::vector<TOutput> VectorType; + typedef typename VectorType::iterator IteratorType; + typedef typename std::vector<VectorType> VectorOfVectorType; + typedef typename VectorOfVectorType::iterator VecOfVecIteratorType; + typedef double HistogramFrequencyType; + typedef typename itk::Statistics::Histogram<HistogramFrequencyType, 2> HistogramType; + typedef typename HistogramType::MeasurementVectorType + MeasurementVectorType; + typedef typename HistogramType::SizeType HistogramSizeType; + typedef typename HistogramType::Iterator HistogramIteratorType; + + + LHMI() {}; + virtual ~LHMI() {}; + inline TOutput operator()( const TInput1 & itA, + const TInput2 & itB) + { + + + HistogramType::Pointer histogram; + + /** The histogram size. */ + HistogramSizeType histogramSize; + /** The lower bound for samples in the histogram. */ + MeasurementVectorType lowerBound; + /** The upper bound for samples in the histogram. */ + MeasurementVectorType upperBound; + + double upperBoundIncreaseFactor = 0.001; + + histogramSize.Fill(256); + + TOutput maxA = itA.GetPixel(0); + TOutput minA = itA.GetPixel(0); + TOutput maxB = itB.GetPixel(0); + TOutput minB = itB.GetPixel(0); + + for (unsigned long pos = 0; pos< itA.Size(); ++pos) + { + + TOutput value = static_cast<TOutput>(itA.GetPixel(pos)); + + if (value > maxA) + maxA = value; + else if (value < minA) + minA = value; + + value = static_cast<TOutput>(itB.GetPixel(pos)); + + if (value > maxB) + maxB = value; + else if (value < minB) + minB = value; + + + } + + + // Initialize the upper and lower bounds of the histogram. + lowerBound[0] = minA; + lowerBound[1] = minB; + upperBound[0] = + maxA + (maxA - minA ) * upperBoundIncreaseFactor; + upperBound[1] = + maxB + (maxB - minB ) * upperBoundIncreaseFactor; + + + histogram = HistogramType::New(); + + histogram->Initialize(histogramSize, lowerBound, upperBound); + + for (unsigned long pos = 0; pos< itA.Size(); ++pos) + { + + typename HistogramType::MeasurementVectorType sample; + sample[0] = itA.GetPixel(pos); + sample[1] = itB.GetPixel(pos); + /*if(sample[0]!=NumericTraits<TOutput>::Zero && + sample[1]!=NumericTraits<TOutput>::Zero)*/ + histogram->IncreaseFrequency(sample, 1); + + } + + + + TOutput entropyX = itk::NumericTraits<TOutput>::Zero; + TOutput entropyY = itk::NumericTraits<TOutput>::Zero; + TOutput jointEntropy = itk::NumericTraits<TOutput>::Zero; + HistogramFrequencyType totalFreq = histogram->GetTotalFrequency(); + + for (unsigned int i = 0; i < histogram->GetSize()[0]; ++i) + { + HistogramFrequencyType freq = histogram->GetFrequency(i, 0); + if (freq > 0) + { + entropyX += freq*vcl_log(freq); + } + } + + entropyX = -entropyX/static_cast<TOutput>(totalFreq) + vcl_log(totalFreq); + + for (unsigned int i = 0; i < histogram->GetSize()[1]; ++i) + { + HistogramFrequencyType freq = histogram->GetFrequency(i, 1); + if (freq > 0) + { + entropyY += freq*vcl_log(freq); + } + } + + entropyY = -entropyY/static_cast<TOutput>(totalFreq) + vcl_log(totalFreq); + + HistogramIteratorType it = histogram->Begin(); + HistogramIteratorType end = histogram->End(); + while (it != end) + { + HistogramFrequencyType freq = it.GetFrequency(); + if (freq > 0) + { + jointEntropy += freq*vcl_log(freq); + } + ++it; + } + + jointEntropy = -jointEntropy/static_cast<TOutput>(totalFreq) + + vcl_log(totalFreq); + + return static_cast<TOutput>( jointEntropy/(entropyX + entropyY) ); + } + + + +}; +} + +} +#endif diff --git a/Code/ChangeDetection/otbLHMIChangeDetector.h b/Code/ChangeDetection/otbLHMIChangeDetector.h index 9383c213de62536f80c274ef9c70663532dae198..621618edb9bea87cfc754f21af93d52240a24cd8 100644 --- a/Code/ChangeDetection/otbLHMIChangeDetector.h +++ b/Code/ChangeDetection/otbLHMIChangeDetector.h @@ -19,11 +19,7 @@ #define __otbLHMIChangeDetector_h #include "otbBinaryFunctorNeighborhoodImageFilter.h" -#include <vector> -#include <stdlib.h> -#include <math.h> -#include "itkHistogram.h" - +#include "otbLHMI.h" namespace otb { @@ -53,152 +49,6 @@ namespace otb * \ingroup IntensityImageFilters Multithreaded */ -#define epsilon 0.01 - -namespace Functor -{ - -template< class TInput1, class TInput2, class TOutput> -class LHMI -{ - -public: - - typedef typename std::vector<TOutput> VectorType; - typedef typename VectorType::iterator IteratorType; - typedef typename std::vector<VectorType> VectorOfVectorType; - typedef typename VectorOfVectorType::iterator VecOfVecIteratorType; - typedef double HistogramFrequencyType; - typedef typename itk::Statistics::Histogram<HistogramFrequencyType, 2> HistogramType; - typedef typename HistogramType::MeasurementVectorType - MeasurementVectorType; - typedef typename HistogramType::SizeType HistogramSizeType; - typedef typename HistogramType::Iterator HistogramIteratorType; - - - LHMI() {}; - virtual ~LHMI() {}; - inline TOutput operator()( const TInput1 & itA, - const TInput2 & itB) - { - - - HistogramType::Pointer histogram; - - /** The histogram size. */ - HistogramSizeType histogramSize; - /** The lower bound for samples in the histogram. */ - MeasurementVectorType lowerBound; - /** The upper bound for samples in the histogram. */ - MeasurementVectorType upperBound; - - double upperBoundIncreaseFactor = 0.001; - - histogramSize.Fill(256); - - TOutput maxA = itA.GetPixel(0); - TOutput minA = itA.GetPixel(0); - TOutput maxB = itB.GetPixel(0); - TOutput minB = itB.GetPixel(0); - - for (unsigned long pos = 0; pos< itA.Size(); ++pos) - { - - TOutput value = static_cast<TOutput>(itA.GetPixel(pos)); - - if (value > maxA) - maxA = value; - else if (value < minA) - minA = value; - - value = static_cast<TOutput>(itB.GetPixel(pos)); - - if (value > maxB) - maxB = value; - else if (value < minB) - minB = value; - - - } - - - // Initialize the upper and lower bounds of the histogram. - lowerBound[0] = minA; - lowerBound[1] = minB; - upperBound[0] = - maxA + (maxA - minA ) * upperBoundIncreaseFactor; - upperBound[1] = - maxB + (maxB - minB ) * upperBoundIncreaseFactor; - - - histogram = HistogramType::New(); - - histogram->Initialize(histogramSize, lowerBound, upperBound); - - for (unsigned long pos = 0; pos< itA.Size(); ++pos) - { - - typename HistogramType::MeasurementVectorType sample; - sample[0] = itA.GetPixel(pos); - sample[1] = itB.GetPixel(pos); - /*if(sample[0]!=NumericTraits<TOutput>::Zero && - sample[1]!=NumericTraits<TOutput>::Zero)*/ - histogram->IncreaseFrequency(sample, 1); - - } - - - - TOutput entropyX = itk::NumericTraits<TOutput>::Zero; - TOutput entropyY = itk::NumericTraits<TOutput>::Zero; - TOutput jointEntropy = itk::NumericTraits<TOutput>::Zero; - HistogramFrequencyType totalFreq = histogram->GetTotalFrequency(); - - for (unsigned int i = 0; i < histogram->GetSize()[0]; ++i) - { - HistogramFrequencyType freq = histogram->GetFrequency(i, 0); - if (freq > 0) - { - entropyX += freq*vcl_log(freq); - } - } - - entropyX = -entropyX/static_cast<TOutput>(totalFreq) + vcl_log(totalFreq); - - for (unsigned int i = 0; i < histogram->GetSize()[1]; ++i) - { - HistogramFrequencyType freq = histogram->GetFrequency(i, 1); - if (freq > 0) - { - entropyY += freq*vcl_log(freq); - } - } - - entropyY = -entropyY/static_cast<TOutput>(totalFreq) + vcl_log(totalFreq); - - HistogramIteratorType it = histogram->Begin(); - HistogramIteratorType end = histogram->End(); - while (it != end) - { - HistogramFrequencyType freq = it.GetFrequency(); - if (freq > 0) - { - jointEntropy += freq*vcl_log(freq); - } - ++it; - } - - jointEntropy = -jointEntropy/static_cast<TOutput>(totalFreq) + - vcl_log(totalFreq); - - return static_cast<TOutput>( jointEntropy/(entropyX + entropyY) ); - } - - - -}; -} - template <class TInputImage1, class TInputImage2, class TOutputImage> class ITK_EXPORT LHMIChangeDetector : public BinaryFunctorNeighborhoodImageFilter< diff --git a/Code/ChangeDetection/otbMeanDifference.h b/Code/ChangeDetection/otbMeanDifference.h new file mode 100644 index 0000000000000000000000000000000000000000..c908f315607f9120ac48cd7d98bcc295593d34ac --- /dev/null +++ b/Code/ChangeDetection/otbMeanDifference.h @@ -0,0 +1,78 @@ +/*========================================================================= + + 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 __otbMeanDifference_h +#define __otbMeanDifference_h + + +namespace otb +{ + +/** \class MeanDifferenceImageFilter + * \brief Implements neighborhood-wise the computation of mean difference. + * + * This filter is parametrized over the types of the two + * input images and the type of the output image. + * + * Numeric conversions (castings) are done by the C++ defaults. + * + * The filter will walk over all the pixels in the two input images, and for + * each one of them it will do the following: + * + * - cast the input 1 pixel value to \c double + * - cast the input 2 pixel value to \c double + * - compute the difference of the two pixel values + * - compute the value of the difference of means + * - cast the \c double value resulting to the pixel type of the output image + * - store the casted value into the output image. + * + * The filter expect all images to have the same dimension + * (e.g. all 2D, or all 3D, or all ND) + * + * \ingroup IntensityImageFilters Multithreaded + */ +namespace Functor +{ + +template< class TInput1, class TInput2, class TOutput> +class MeanDifference +{ +public: + MeanDifference() {}; + virtual ~MeanDifference() {}; + inline TOutput operator()( const TInput1 & itA, + const TInput2 & itB) + { + + TOutput meanA = 0.0; + TOutput meanB = 0.0; + + for (unsigned long pos = 0; pos< itA.Size(); ++pos) + { + + meanA += static_cast<TOutput>(itA.GetPixel(pos)); + meanB += static_cast<TOutput>(itB.GetPixel(pos)); + + + } + return static_cast<TOutput>( (meanA-meanB)/itA.Size() ); + } +}; +} +} + +#endif diff --git a/Code/ChangeDetection/otbMeanDifferenceImageFilter.h b/Code/ChangeDetection/otbMeanDifferenceImageFilter.h index c009eeb5893e9b50586ed208b3d3fdfec999e27e..9e182c82ecb9e17a3067ff37cfaf6d9869e3e374 100644 --- a/Code/ChangeDetection/otbMeanDifferenceImageFilter.h +++ b/Code/ChangeDetection/otbMeanDifferenceImageFilter.h @@ -19,62 +19,11 @@ #define __otbMeanDifferenceImageFilter_h #include "otbBinaryFunctorNeighborhoodImageFilter.h" +#include "otbMeanDifference.h" namespace otb { -/** \class MeanDifferenceImageFilter - * \brief Implements neighborhood-wise the computation of mean difference. - * - * This filter is parametrized over the types of the two - * input images and the type of the output image. - * - * Numeric conversions (castings) are done by the C++ defaults. - * - * The filter will walk over all the pixels in the two input images, and for - * each one of them it will do the following: - * - * - cast the input 1 pixel value to \c double - * - cast the input 2 pixel value to \c double - * - compute the difference of the two pixel values - * - compute the value of the difference of means - * - cast the \c double value resulting to the pixel type of the output image - * - store the casted value into the output image. - * - * The filter expect all images to have the same dimension - * (e.g. all 2D, or all 3D, or all ND) - * - * \ingroup IntensityImageFilters Multithreaded - */ -namespace Functor -{ - -template< class TInput1, class TInput2, class TOutput> -class MeanDifference -{ -public: - MeanDifference() {}; - virtual ~MeanDifference() {}; - inline TOutput operator()( const TInput1 & itA, - const TInput2 & itB) - { - - TOutput meanA = 0.0; - TOutput meanB = 0.0; - - for (unsigned long pos = 0; pos< itA.Size(); ++pos) - { - - meanA += static_cast<TOutput>(itA.GetPixel(pos)); - meanB += static_cast<TOutput>(itB.GetPixel(pos)); - - - } - return static_cast<TOutput>( (meanA-meanB)/itA.Size() ); - } -}; -} - template <class TInputImage1, class TInputImage2, class TOutputImage> class ITK_EXPORT MeanDifferenceImageFilter : public BinaryFunctorNeighborhoodImageFilter< diff --git a/Code/ChangeDetection/otbMeanRatio.h b/Code/ChangeDetection/otbMeanRatio.h new file mode 100644 index 0000000000000000000000000000000000000000..dbe0ba5a91be1e0892d57bd56d5f4871b996be6b --- /dev/null +++ b/Code/ChangeDetection/otbMeanRatio.h @@ -0,0 +1,81 @@ +/*========================================================================= + + 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 __otbMeanRatio_h +#define __otbMeanRatio_h + +#include "otbBinaryFunctorNeighborhoodImageFilter.h" + +namespace otb +{ + +/** \class Functor::MeanRatio + * + * - compute the ratio of the two pixel values + * - compute the value of the ratio of means + * - cast the \c double value resulting to the pixel type of the output image + * - store the casted value into the output image. + * + + * \ingroup Functor + */ +namespace Functor +{ + +template< class TInput1, class TInput2, class TOutput> +class MeanRatio +{ +public: + MeanRatio() {}; + virtual ~MeanRatio() {}; + inline TOutput operator()( const TInput1 & itA, + const TInput2 & itB) + { + + TOutput meanA = 0.0; + TOutput meanB = 0.0; + + for (unsigned long pos = 0; pos< itA.Size(); ++pos) + { + + meanA += static_cast<TOutput>(itA.GetPixel(pos)); + meanB += static_cast<TOutput>(itB.GetPixel(pos)); + + + } + + meanA /= itA.Size(); + meanB /= itB.Size(); + + //std::cout<<"meanA= "<<meanA<<", meanB= "<<meanB<<std::endl; + + TOutput ratio; + + if(meanA == meanB) + ratio = 0.; + else if (meanA>meanB) + ratio = static_cast<TOutput>(1.0 - meanB/meanA); + else ratio = static_cast<TOutput>(1.0 - meanA/meanB); + + return ratio; + } +}; +} +} // end namespace otb + + +#endif diff --git a/Code/ChangeDetection/otbMeanRatioImageFilter.h b/Code/ChangeDetection/otbMeanRatioImageFilter.h index 209aa3c400bca249fb2ddba8111f48d32e66d32a..9e77191fcbb302620fd3cacee2f96696ec909b0a 100644 --- a/Code/ChangeDetection/otbMeanRatioImageFilter.h +++ b/Code/ChangeDetection/otbMeanRatioImageFilter.h @@ -19,6 +19,7 @@ #define __otbMeanRatioImageFilter_h #include "otbBinaryFunctorNeighborhoodImageFilter.h" +#include "otbMeanRatio.h" namespace otb { @@ -44,48 +45,6 @@ namespace otb * * \ingroup IntensityImageFilters Multithreaded */ -namespace Functor -{ - -template< class TInput1, class TInput2, class TOutput> -class MeanRatio -{ -public: - MeanRatio() {}; - virtual ~MeanRatio() {}; - inline TOutput operator()( const TInput1 & itA, - const TInput2 & itB) - { - - TOutput meanA = 0.0; - TOutput meanB = 0.0; - - for (unsigned long pos = 0; pos< itA.Size(); ++pos) - { - - meanA += static_cast<TOutput>(itA.GetPixel(pos)); - meanB += static_cast<TOutput>(itB.GetPixel(pos)); - - - } - - meanA /= itA.Size(); - meanB /= itB.Size(); - - //std::cout<<"meanA= "<<meanA<<", meanB= "<<meanB<<std::endl; - - TOutput ratio; - - if(meanA == meanB) - ratio = 0.; - else if (meanA>meanB) - ratio = static_cast<TOutput>(1.0 - meanB/meanA); - else ratio = static_cast<TOutput>(1.0 - meanA/meanB); - - return ratio; - } -}; -} template <class TInputImage1, class TInputImage2, class TOutputImage> class ITK_EXPORT MeanRatioImageFilter :