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