22 #ifndef otbKullbackLeiblerProfileImageFilter_hxx
23 #define otbKullbackLeiblerProfileImageFilter_hxx
37 template <
class TInput>
40 m_debug = MakeSumAndMoments(input, mask);
46 template <
class TInput>
47 template <
class TInput2>
50 itk::VariableLengthVector<double> resu(fCum.size());
55 for (
unsigned int level = 0; level < resu.GetSize(); level++)
56 resu[level] = KL_profile((*iter1++), (*iter2++));
63 template <
class TInput>
66 double cum1 = cumulants1[0];
67 double cum2 = cumulants1[1];
68 double cum3 = cumulants1[2];
71 double sqrt_cum2 = sqrt(cum2);
72 double cum2_3 = cum2 * cum2 * cum2;
73 double cum3_2 = cum3 * cum3;
75 double tilde_cum1 = cumulants2[0];
76 double tilde_cum2 = cumulants2[1];
77 double tilde_cum3 = cumulants2[2];
78 double tilde_cum4 = cumulants2[3];
80 double tilde_cum2_2 = cum2 * cum2;
81 double tilde_cum2_3 = cum2 * tilde_cum2_2;
82 double tilde_cum2_6 = tilde_cum2_3 * tilde_cum2_3;
83 double tilde_cum3_2 = tilde_cum3 * tilde_cum3;
85 double beta = sqrt_cum2 / tilde_cum2;
86 double alpha = (cum1 - tilde_cum1) / tilde_cum2;
88 double alpha_2 = alpha * alpha;
89 double alpha_4 = alpha_2 * alpha_2;
90 double alpha_6 = alpha_2 * alpha_4;
92 double beta_2 = beta * beta;
93 double beta_4 = beta_2 * beta_2;
94 double beta_6 = beta_2 * beta_4;
96 double c2 = alpha_2 + beta_2;
97 double c3 = alpha * (alpha_2 + 3.0 * beta_2);
98 double c4 = alpha_4 + 6.0 * alpha_2 * beta_2 + 3.0 * beta_4;
99 double c6 = alpha_6 + 15.0 * alpha_4 * beta_2 + 45.0 * alpha_2 * beta_4 + 15.0 * beta_6;
101 double a1 = c3 - 3.0 * alpha / tilde_cum2;
102 double a2 = c4 - 6.0 * c2 / tilde_cum2 + 3.0 / tilde_cum2_2;
103 double a3 = c6 - 15.0 * c4 / tilde_cum2 + 45.0 * c2 / tilde_cum2_2 - 15.0 / tilde_cum2_3;
105 double tmp = cum1 - tilde_cum1 + sqrt_cum2;
106 double resu = cum3_2 / (12.0 * cum2_3) + (log(tilde_cum2 / cum2) - 1.0 + tmp * tmp / tilde_cum2) / 2.0 -
107 (tilde_cum3 * a1 / 6.0 + tilde_cum4 * a2 / 24.0 + tilde_cum3_2 * a3 / 72.0) -
108 tilde_cum3_2 * (c6 - 6.0 * c4 / cum2 + 9.0 * c2 / tilde_cum2_2) / 72.0 -
109 10.0 * cum3 * tilde_cum3 * (cum1 - tilde_cum1) * (cum2 - tilde_cum2) / tilde_cum2_6;
111 if (vnl_math_isnan(resu) || resu > 1e3)
114 return resu < 0.0 ? 0.0 : resu;
119 template <
class TInput>
122 fMu.resize(mask.size());
123 std::vector<itk::Array2D<int>>::iterator iter = mask.begin();
125 if (InitSumAndMoments(input, (*iter++)))
128 for (
unsigned int level = 1; level < mask.size(); level++)
129 if (ReInitSumAndMoments(input, (*iter++), level))
138 template <
class TInput>
141 fSum0 = fSum1 = fSum2 = fSum3 = fSum4 = 0.0;
146 double pixel, pixel_2;
149 for (i = 0; i < mask.rows(); ++i)
151 for (j = 0; j < mask.cols(); ++j)
154 if (mask.get(i, j) == 1)
156 pixel =
static_cast<double>(input.GetPixel(k));
157 pixel_2 = pixel * pixel;
162 fSum3 += pixel_2 * pixel;
163 fSum4 += pixel_2 * pixel_2;
171 fDataAvailable =
false;
178 mu2 = fSum2 / fSum0 - mu1 * mu1;
182 fDataAvailable =
false;
186 double sigma = sqrt(mu2);
188 itk::VariableLengthVector<double> tab(input.Size());
189 double* x =
const_cast<double*
>(tab.GetDataPointer());
190 for (
unsigned long cp = 0; cp < input.Size(); ++cp)
191 *x++ = (
static_cast<double>(input.GetPixel(cp)) - mu1) / sigma;
195 x =
const_cast<double*
>(tab.GetDataPointer());
198 for (i = 0; i < mask.rows(); ++i)
200 for (j = 0; j < mask.cols(); ++j)
202 if (mask.get(i, j) == 1)
205 pixel_2 = pixel * pixel;
207 mu3 += pixel * pixel_2;
208 mu4 += pixel_2 * pixel_2;
218 if (vnl_math_isnan(mu3) || vnl_math_isnan(mu4))
220 fDataAvailable =
false;
229 fDataAvailable =
true;
236 template <
class TInput>
239 fMu[level].Fill(0.0);
241 double sum0 = 0.0, sum1 = 0.0, sum2 = 0.0, sum3 = 0.0, sum4 = 0.0;
243 double pixel, pixel_2;
246 unsigned long k = 0L;
249 for (i = 0; i < mask.rows(); ++i)
251 for (j = 0; j < mask.cols(); ++j)
253 if (mask.get(i, j) == 1)
255 pixel =
static_cast<double>(input.GetPixel(k));
256 pixel_2 = pixel * pixel;
261 sum3 += pixel * pixel_2;
262 sum4 += pixel_2 * pixel_2;
274 double mu = fSum1 / fSum0;
275 double mu_2 = mu * mu;
276 double mu_3 = mu_2 * mu;
277 double mu_4 = mu_2 * mu_2;
280 fMu[level][1] = fSum2 / fSum0 - mu_2;
282 double sigma = sqrt(fSum2);
283 double sigma_2 = fSum2;
284 double sigma_3 = sigma * sigma_2;
285 double sigma_4 = sigma_2 * sigma_2;
287 fMu[level][2] = (fSum3 - 3.0 * mu * fSum2 + 3.0 * mu_2 * fSum1 - fSum0 * mu_3) / (sigma_3 * fSum0);
288 fMu[level][3] = (fSum4 - 4.0 * mu * fSum3 + 6.0 * mu_2 * fSum2 - 4.0 * mu_3 * fSum1 + fSum0 * mu_4) / (sigma_4 * fSum0);
295 template <
class TInput>
298 if (!IsDataAvailable())
301 fCum.resize(fMu.size());
304 for (
unsigned int i = 0; i < fCum.size(); ++i)
320 template <
class TInput1,
class TInput2,
class TOutput>
329 template <
class TInput1,
class TInput2,
class TOutput>
332 m_RadiusMin = min < max ? min : max;
333 m_RadiusMax = max > min ? max : min;
334 MakeMultiscaleProfile();
337 template <
class TInput1,
class TInput2,
class TOutput>
343 template <
class TInput1,
class TInput2,
class TOutput>
351 template <
class TInput1,
class TInput2,
class TOutput>
354 m_mask.resize(m_RadiusMax - m_RadiusMin + 1);
355 int lenMax = 2 * m_RadiusMax + 1;
356 int i, j, middle = m_RadiusMax;
359 std::vector<itk::Array2D<int>>::iterator outer_iter = m_mask.begin();
360 (*outer_iter).SetSize(lenMax, lenMax);
361 (*outer_iter).fill(0);
362 for (i = middle - m_RadiusMin; i <= middle + m_RadiusMin; ++i)
363 for (j = middle - m_RadiusMin; j <= middle + m_RadiusMin; ++j)
364 (*outer_iter).put(i, j, 1);
370 for (
int radius = m_RadiusMin + 1; radius <= m_RadiusMax; ++radius)
372 (*outer_iter).SetSize(lenMax, lenMax);
373 (*outer_iter).fill(0);
375 for (i = middle - radius; i <= middle + radius; ++i)
377 (*outer_iter).put(i, middle - radius, 1);
378 (*outer_iter).put(i, middle + radius, 1);
379 (*outer_iter).put(middle - radius, i, 1);
380 (*outer_iter).put(middle + radius, i, 1);
390 template <
class TInput1,
class TInput2,
class TOutput>
397 itk::VariableLengthVector<double> resu(m_RadiusMax - m_RadiusMin + 1);
399 return static_cast<TOutput
>(resu);
406 itk::VariableLengthVector<double> resu(m_RadiusMax - m_RadiusMin + 1);
408 return static_cast<TOutput
>(resu);