36 #ifndef VIGRA_VISIT_BORDER_HXX
37 #define VIGRA_VISIT_BORDER_HXX
39 #include "multi_array.hxx"
44 namespace visit_border_detail
47 template <
unsigned int K>
48 struct visit_border_impl
50 template <
unsigned int N,
class Data,
class S1,
51 class Label,
class S2,
52 class Shape,
class Visitor>
53 static void exec(
const MultiArrayView<N, Data, S1>& u_data, MultiArrayView<N, Label, S2> u_labels,
54 const MultiArrayView<N, Data, S1>& v_data, MultiArrayView<N, Label, S2> v_labels,
55 const Shape& block_difference,
NeighborhoodType neighborhood, Visitor visitor)
57 static const unsigned int D = K - 1;
58 typedef visit_border_impl<D> next;
60 if(block_difference[D] == -1)
63 next::exec(u_data.bindAt(D, 0), u_labels.bindAt(D, 0),
64 v_data.bindAt(D, last), v_labels.bindAt(D, last),
65 block_difference, neighborhood, visitor);
67 else if(block_difference[D] == 1)
70 next::exec(u_data.bindAt(D, last), u_labels.bindAt(D, last),
71 v_data.bindAt(D, 0), v_labels.bindAt(D, 0),
72 block_difference, neighborhood, visitor);
74 else if(block_difference[D] == 0)
76 next::exec(u_data, u_labels, v_data, v_labels, block_difference, neighborhood, visitor);
80 vigra_precondition(
false,
"invalid block difference");
86 struct visit_border_impl<0>
88 template <
class Data,
class S1,
89 class Label,
class S2,
90 class Shape,
class Visitor>
91 static void exec(
const MultiArrayView<0, Data, S1>& u_data, MultiArrayView<0, Label, S2> u_labels,
92 const MultiArrayView<0, Data, S1>& v_data, MultiArrayView<0, Label, S2> v_labels,
95 visitor(u_data(0), u_labels(0), v_data(0), v_labels(0), block_difference);
97 template <
unsigned int N,
class Data,
class S1,
98 class Label,
class S2,
99 class Shape,
class Visitor>
100 static void exec(
const MultiArrayView<N, Data, S1>& u_data, MultiArrayView<N, Label, S2> u_labels,
101 const MultiArrayView<N, Data, S1>& v_data, MultiArrayView<N, Label, S2> v_labels,
102 const Shape& block_difference,
NeighborhoodType neighborhood, Visitor visitor)
106 typedef typename MultiArrayView<N, Data, S1>::const_iterator DataIterator;
107 typedef typename MultiArrayView<N, Label, S2>::iterator LabelsIterator;
109 DataIterator u_data_it = u_data.begin();
110 LabelsIterator u_labels_it = u_labels.begin();
112 DataIterator v_data_it = v_data.begin();
113 LabelsIterator v_labels_it = v_labels.begin();
115 for( ; u_data_it != u_data.end(); ++u_data_it, ++u_labels_it, ++v_data_it, ++v_labels_it)
117 visitor(*u_data_it, *u_labels_it, *v_data_it, *v_labels_it, block_difference);
122 typedef GridGraph<N, undirected_tag> Graph;
123 typedef typename Graph::NodeIt GraphScanner;
124 typedef typename Graph::OutArcIt NeighborIterator;
126 static const int global_dim_number = Shape::static_size;
127 TinyVector<unsigned int, N> dim_mapping;
128 int local_dims_pos = 0;
129 int global_dims_pos = 0;
130 for( ; global_dims_pos != global_dim_number; ++global_dims_pos)
132 if(block_difference[global_dims_pos] == 0)
134 vigra_assert(local_dims_pos != N,
"");
135 dim_mapping[local_dims_pos] = global_dims_pos;
139 vigra_assert(local_dims_pos == N,
"");
141 Graph graph(u_data.shape(), neighborhood);
142 Shape pixel_difference = block_difference;
143 for(GraphScanner node(graph); node != lemon::INVALID; ++node)
147 visitor(u_data[*node], u_labels[*node], v_data[*node], v_labels[*node], block_difference);
149 for(NeighborIterator arc(graph, *node); arc != lemon::INVALID; ++arc)
151 for(
int i = 0; i != N; ++i)
152 pixel_difference[dim_mapping[i]] = graph.target(*arc)[i] - (*node)[i];
153 visitor(u_data[*node], u_labels[*node], v_data[graph.target(*arc)], v_labels[graph.target(*arc)], pixel_difference);
162 template <
unsigned int N,
class Data,
class S1,
163 class Label,
class S2,
164 class Shape,
class Visitor>
166 visitBorder(
const MultiArrayView<N, Data, S1>& u_data, MultiArrayView<N, Label, S2> u_labels,
167 const MultiArrayView<N, Data, S1>& v_data, MultiArrayView<N, Label, S2> v_labels,
170 vigra_precondition(u_data.shape() == u_labels.shape() && v_data.shape() == v_labels.shape(),
171 "differing block shapes");
172 visit_border_detail::visit_border_impl<N>::exec(u_data, u_labels,
174 difference, neighborhood, visitor);
179 #endif // VIGRA_VISIT_BORDER_HXX
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
use direct and indirect neighbors
Definition: multi_fwd.hxx:188
use only direct neighbors
Definition: multi_fwd.hxx:187
NeighborhoodType
Choose the neighborhood system in a dimension-independent way.
Definition: multi_fwd.hxx:186