15inline void Ensemble::C2(
const T& f,
const T& g,
const M& fmask,
const M& gmask)
17 using value_type =
typename T::value_type;
18 using mask_type =
typename M::value_type;
20 static_assert(std::is_integral<value_type>::value,
"Integral image required.");
21 static_assert(std::is_integral<mask_type>::value,
"Integral mask required.");
26 GOOSEEYE_ASSERT(f.dimension() == m_shape_orig.size(), std::out_of_range);
27 GOOSEEYE_ASSERT(xt::all(xt::equal(fmask, 0) || xt::equal(fmask, 1)), std::out_of_range);
28 GOOSEEYE_ASSERT(xt::all(xt::equal(gmask, 0) || xt::equal(gmask, 1)), std::out_of_range);
29 GOOSEEYE_ASSERT(m_stat == Type::C2 || m_stat == Type::Unset, std::out_of_range);
35 xt::pad_mode pad_mode = xt::pad_mode::constant;
40 pad_mode = xt::pad_mode::periodic;
48 xt::pad(xt::atleast_3d(fmask), m_pad, xt::pad_mode::constant, mask_value);
50 xt::pad(xt::atleast_3d(gmask), m_pad, xt::pad_mode::constant, mask_value);
53 for (
size_t h = m_pad[0][0]; h < F.shape(0) - m_pad[0][1]; ++h) {
54 for (
size_t i = m_pad[1][0]; i < F.shape(1) - m_pad[1][1]; ++i) {
55 for (
size_t j = m_pad[2][0]; j < F.shape(2) - m_pad[2][1]; ++j) {
63 xt::range(h - m_pad[0][0], h + m_pad[0][1] + 1),
64 xt::range(i - m_pad[1][0], i + m_pad[1][1] + 1),
65 xt::range(j - m_pad[2][0], j + m_pad[2][1] + 1));
67 auto Gmii = 1.0 - xt::view(
69 xt::range(h - m_pad[0][0], h + m_pad[0][1] + 1),
70 xt::range(i - m_pad[1][0], i + m_pad[1][1] + 1),
71 xt::range(j - m_pad[2][0], j + m_pad[2][1] + 1));
73 if (F(h, i, j) != 0) {
74 m_first += xt::where(xt::equal(F(h, i, j), Gi), Gmii, 0.0);