22 #ifndef otbKullbackLeiblerDistanceImageFilter_hxx
23 #define otbKullbackLeiblerDistanceImageFilter_hxx
28 #include "itkImageRegionConstIterator.h"
39 template <
class TInput>
42 MakeSumAndMoments(input);
46 template <
class TInput>
49 MakeSumAndMoments(input);
55 template <
class TInput>
56 template <
class TInput2>
59 double cum1 = GetMean();
60 double cum2 = GetVariance();
61 double cum3 = GetSkewness();
63 double sqrt_cum2 = sqrt(cum2);
64 double cum2_3 = cum2 * cum2 * cum2;
65 double cum3_2 = cum3 * cum3;
67 double tilde_cum1 = cumulants.
GetMean();
72 double tilde_cum2_2 = cum2 * cum2;
73 double tilde_cum2_3 = cum2 * tilde_cum2_2;
74 double tilde_cum2_6 = tilde_cum2_3 * tilde_cum2_3;
75 double tilde_cum3_2 = tilde_cum3 * tilde_cum3;
77 double beta = sqrt_cum2 / tilde_cum2;
78 double alpha = (cum1 - tilde_cum1) / tilde_cum2;
80 double alpha_2 = alpha * alpha;
81 double alpha_4 = alpha_2 * alpha_2;
82 double alpha_6 = alpha_2 * alpha_4;
84 double beta_2 = beta * beta;
85 double beta_4 = beta_2 * beta_2;
86 double beta_6 = beta_2 * beta_4;
88 double c2 = alpha_2 + beta_2;
89 double c3 = alpha * (alpha_2 + 3.0 * beta_2);
90 double c4 = alpha_4 + 6.0 * alpha_2 * beta_2 + 3.0 * beta_4;
91 double c6 = alpha_6 + 15.0 * alpha_4 * beta_2 + 45.0 * alpha_2 * beta_4 + 15.0 * beta_6;
93 double a1 = c3 - 3.0 * alpha / tilde_cum2;
94 double a2 = c4 - 6.0 * c2 / tilde_cum2 + 3.0 / tilde_cum2_2;
95 double a3 = c6 - 15.0 * c4 / tilde_cum2 + 45.0 * c2 / tilde_cum2_2 - 15.0 / tilde_cum2_3;
97 double tmp = cum1 - tilde_cum1 + sqrt_cum2;
98 double resu = cum3_2 / (12.0 * cum2_3) + (log(tilde_cum2 / cum2) - 1.0 + tmp * tmp / tilde_cum2) / 2.0 -
99 (tilde_cum3 * a1 / 6.0 + tilde_cum4 * a2 / 24.0 + tilde_cum3_2 * a3 / 72.0) -
100 tilde_cum3_2 * (c6 - 6.0 * c4 / cum2 + 9.0 * c2 / tilde_cum2_2) / 72.0 -
101 10.0 * cum3 * tilde_cum3 * (cum1 - tilde_cum1) * (cum2 - tilde_cum2) / tilde_cum2_6;
103 return resu < 0.0 ? 0.0 : resu;
108 template <
class TInput>
112 fSum0 = fSum1 = fSum2 = fSum3 = fSum4 = 0.0;
113 double pixel, pixel_2;
115 for (
unsigned long i = 0; i < input.Size(); ++i)
117 pixel =
static_cast<double>(input.GetPixel(i));
118 pixel_2 = pixel * pixel;
123 fSum3 += pixel_2 * pixel;
124 fSum4 += pixel_2 * pixel_2;
127 fMu1 = fSum1 / fSum0;
128 fMu2 = fSum2 / fSum0 - fMu1 * fMu1;
135 fDataAvailable =
false;
139 double sigma = sqrt(fMu2);
141 itk::VariableLengthVector<double> tab(input.Size());
142 double* x =
const_cast<double*
>(tab.GetDataPointer());
143 for (
unsigned long i = 0; i < input.Size(); ++i)
144 *x++ = (
static_cast<double>(input.GetPixel(i)) - fMu1) / sigma;
147 x =
const_cast<double*
>(tab.GetDataPointer());
148 for (
unsigned long i = 0; i < input.Size(); ++i)
151 pixel_2 = pixel * pixel;
153 fMu3 += pixel * pixel_2;
154 fMu4 += pixel_2 * pixel_2;
160 fDataAvailable =
true;
165 template <
class TInput>
169 fSum0 = fSum1 = fSum2 = fSum3 = fSum4 = 0.0;
170 double pixel, pixel_2;
172 typedef itk::Image<typename TInput::ImageType::PixelType, 1> LocalImageType;
173 typedef itk::ImageRegionConstIterator<LocalImageType> ImageRegionConstIteratorType;
175 ImageRegionConstIteratorType inputIter(input, input->GetRequestedRegion());
176 inputIter.GoToBegin();
177 unsigned int inputSize = 0;
179 while (!inputIter.IsAtEnd())
181 pixel =
static_cast<double>(inputIter.Get());
182 pixel_2 = pixel * pixel;
187 fSum3 += pixel_2 * pixel;
188 fSum4 += pixel_2 * pixel_2;
194 fMu1 = fSum1 / fSum0;
195 fMu2 = fSum2 / fSum0 - fMu1 * fMu1;
203 fDataAvailable =
false;
208 double sigma = sqrt(fMu2);
210 std::vector<double> tab(inputSize);
211 std::vector<double>::iterator iterTab = tab.begin();
213 inputIter.GoToBegin();
215 while (!inputIter.IsAtEnd())
217 *iterTab = (
static_cast<double>(inputIter.Get()) - fMu1) / sigma;
224 for (
unsigned int i = 0; i < inputSize; ++i)
227 pixel_2 = pixel * pixel;
229 fMu3 += pixel * pixel_2;
230 fMu4 += pixel_2 * pixel_2;
238 fDataAvailable =
true;
244 template <
class TInput>
252 fKurtosis = fMu4 - 3.0;