20 #ifndef __otbKullbackLeiblerDistanceImageFilter_txx
21 #define __otbKullbackLeiblerDistanceImageFilter_txx
36 template <
class TInput>
40 MakeSumAndMoments(input);
44 template <
class TInput>
48 MakeSumAndMoments(input);
54 template <
class TInput>
55 template <
class TInput2>
60 double cum1 = GetMean();
61 double cum2 = GetVariance();
62 double cum3 = GetSkewness();
64 double sqrt_cum2 = sqrt(cum2);
65 double cum2_3 = cum2 * cum2 * cum2;
66 double cum3_2 = cum3 * cum3;
68 double tilde_cum1 = cumulants.
GetMean();
73 double tilde_cum2_2 = cum2 * cum2;
74 double tilde_cum2_3 = cum2 * tilde_cum2_2;
75 double tilde_cum2_6 = tilde_cum2_3 * tilde_cum2_3;
76 double tilde_cum3_2 = tilde_cum3 * tilde_cum3;
78 double beta = sqrt_cum2 / tilde_cum2;
79 double alpha = (cum1 - tilde_cum1) / tilde_cum2;
81 double alpha_2 = alpha * alpha;
82 double alpha_4 = alpha_2 * alpha_2;
83 double alpha_6 = alpha_2 * alpha_4;
85 double beta_2 = beta * beta;
86 double beta_4 = beta_2 * beta_2;
87 double beta_6 = beta_2 * beta_4;
89 double c2 = alpha_2 + beta_2;
90 double c3 = alpha * (alpha_2 + 3.0 * beta_2);
91 double c4 = alpha_4 + 6.0 * alpha_2 * beta_2 + 3.0 * beta_4;
92 double c6 = alpha_6 + 15.0 * alpha_4 * beta_2 + 45.0 * alpha_2 * beta_4 + 15.0 * beta_6;
94 double a1 = c3 - 3.0 * alpha / tilde_cum2;
95 double a2 = c4 - 6.0 * c2 / tilde_cum2 + 3.0 / tilde_cum2_2;
96 double a3 = c6 - 15.0 * c4 / tilde_cum2 + 45.0 * c2 / tilde_cum2_2 - 15.0 / tilde_cum2_3;
98 double tmp = cum1 - tilde_cum1 + sqrt_cum2;
99 double resu = cum3_2 / (12.0 * cum2_3)
100 + (log(tilde_cum2 / cum2)
101 - 1.0 + tmp * tmp / tilde_cum2) / 2.0
102 - (tilde_cum3 * a1 / 6.0 + tilde_cum4 * a2 / 24.0 + tilde_cum3_2 * a3 / 72.0)
103 - tilde_cum3_2 * (c6 - 6.0 * c4 / cum2 + 9.0 * c2 / tilde_cum2_2) / 72.0
104 - 10.0 * cum3 * tilde_cum3 * (cum1 - tilde_cum1) * (cum2 - tilde_cum2) / tilde_cum2_6;
106 return resu < 0.0 ? 0.0 : resu;
111 template <
class TInput>
117 fSum0 = fSum1 = fSum2 = fSum3 = fSum4 = 0.0;
118 double pixel, pixel_2;
120 for (
unsigned long i = 0; i < input.Size(); ++i)
122 pixel =
static_cast<double> (input.GetPixel(i));
123 pixel_2 = pixel * pixel;
128 fSum3 += pixel_2 * pixel;
129 fSum4 += pixel_2 * pixel_2;
132 fMu1 = fSum1 / fSum0;
133 fMu2 = fSum2 / fSum0 - fMu1 * fMu1;
140 fDataAvailable =
false;
144 double sigma = sqrt(fMu2);
147 double * x =
const_cast<double *
> (tab.GetDataPointer());
148 for (
unsigned long i = 0; i < input.Size(); ++i)
149 *x++ = (static_cast<double> (input.GetPixel(i)) - fMu1) / sigma;
152 x =
const_cast<double *
> (tab.GetDataPointer());
153 for (
unsigned long i = 0; i < input.Size(); ++i)
156 pixel_2 = pixel * pixel;
158 fMu3 += pixel * pixel_2;
159 fMu4 += pixel_2 * pixel_2;
165 fDataAvailable =
true;
170 template <
class TInput>
176 fSum0 = fSum1 = fSum2 = fSum3 = fSum4 = 0.0;
177 double pixel, pixel_2;
184 unsigned int inputSize = 0;
186 while (!inputIter.IsAtEnd())
188 pixel =
static_cast<double> (inputIter.Get());
189 pixel_2 = pixel * pixel;
194 fSum3 += pixel_2 * pixel;
195 fSum4 += pixel_2 * pixel_2;
201 fMu1 = fSum1 / fSum0;
202 fMu2 = fSum2 / fSum0 - fMu1 * fMu1;
210 fDataAvailable =
false;
215 double sigma = sqrt(fMu2);
217 std::vector<double> tab(inputSize);
218 std::vector<double>::iterator iterTab = tab.begin();
220 inputIter.GoToBegin();
222 while (!inputIter.IsAtEnd())
224 *iterTab = (
static_cast<double> (inputIter.Get()) - fMu1) / sigma;
231 for (
unsigned int i = 0; i < inputSize; ++i)
234 pixel_2 = pixel * pixel;
236 fMu3 += pixel * pixel_2;
237 fMu4 += pixel_2 * pixel_2;
245 fDataAvailable =
true;
251 template <
class TInput>
261 fKurtosis = fMu4 - 3.0;