37 #ifndef VIGRA_MULTI_LOCALMINMAX_HXX 
   38 #define VIGRA_MULTI_LOCALMINMAX_HXX 
   42 #include "multi_array.hxx" 
   43 #include "localminmax.hxx" 
   44 #include "multi_gridgraph.hxx" 
   45 #include "multi_labeling.hxx" 
   46 #include "metaprogramming.hxx" 
   51 namespace detail_local_minima{
 
   54         template<
class NODE_ITER>
 
   55         static bool atBorder(
const NODE_ITER &){
 
   60     template<
unsigned int DIM,
class DTAG>
 
   61     struct NodeAtBorder< GridGraph<DIM,DTAG> >{
 
   62         template<
class NODE_ITER>
 
   63         static bool atBorder(
const NODE_ITER & node ){
 
   64             return node.atBorder();
 
   71 namespace boost_graph {
 
   75 template <
class Graph, 
class T1Map, 
class T2Map, 
class Compare>
 
   77 localMinMaxGraph(Graph 
const &g, 
 
   80                  typename property_traits<T2Map>::value_type marker,
 
   81                  typename property_traits<T1Map const>::value_type threshold,
 
   82                  Compare 
const &compare,
 
   83                  bool allowAtBorder = 
true)
 
   85     typedef typename graph_traits<Graph>::vertex_iterator graph_scanner;
 
   86     typedef typename graph_traits<Graph>::adjacency_iterator neighbor_iterator;
 
   88     typedef typename property_traits<T1Map const>::value_type T1;
 
   90     graph_scanner node, srcend;
 
   91     neighbor_iterator arc, nbend;
 
   93     unsigned int count = 0;
 
   95     for (; node != srcend; ++node) 
 
   97         const T1 current = 
get(src, *node);
 
   99         if (!compare(current, threshold))
 
  102         if(!allowAtBorder && node.atBorder())
 
  106         for (;arc != nbend; ++arc) 
 
  107             if (!compare(current, 
get(src, *arc))) 
 
  112             put(dest, *node, marker);
 
  121 namespace lemon_graph { 
 
  123 template <
class Graph, 
class T1Map, 
class T2Map, 
class Compare>
 
  125 localMinMaxGraph(Graph 
const &g, 
 
  128                  typename T2Map::value_type marker,
 
  129                  typename T1Map::value_type threshold,
 
  130                  Compare 
const &compare,
 
  131                  bool allowAtBorder = 
true)
 
  133     typedef typename Graph::NodeIt    graph_scanner;
 
  134     typedef typename Graph::OutArcIt  neighbor_iterator;
 
  136     unsigned int count = 0;
 
  137     for (graph_scanner node(g); node != INVALID; ++node) 
 
  139         typename T1Map::value_type current = src[*node];
 
  141         if (!compare(current, threshold))
 
  144         if(!allowAtBorder && vigra::detail_local_minima::NodeAtBorder<Graph>::atBorder(node))
 
  147         neighbor_iterator arc(g, *node);
 
  148         for (; arc != INVALID; ++arc) 
 
  149             if (!compare(current, src[g.target(*arc)])) 
 
  154             dest[*node] = marker;
 
  162 template <
class Graph, 
class T1Map, 
class T2Map, 
class Compare, 
class Equal>
 
  164 extendedLocalMinMaxGraph(Graph 
const &g, 
 
  167                          typename T2Map::value_type marker,
 
  168                          typename T1Map::value_type threshold,
 
  169                          Compare 
const &compare,
 
  171                          bool allowAtBorder = 
true)
 
  173     typename Graph::template NodeMap<unsigned int> regions(g);
 
  175     int max_region_label = labelGraph(g, src, regions, equal);
 
  178     std::vector<unsigned char> isExtremum(max_region_label+1, (
unsigned char)1);
 
  180     typedef typename Graph::NodeIt    graph_scanner;
 
  181     typedef typename Graph::OutArcIt  neighbor_iterator;
 
  183     unsigned int count = max_region_label;
 
  184     for (graph_scanner node(g); node != INVALID; ++node) 
 
  186         unsigned int label = regions[*node];
 
  188         if(!isExtremum[label])
 
  191         typename T1Map::value_type current = src[*node];
 
  193         if (!compare(current, threshold) ||
 
  194             (!allowAtBorder &&  vigra::detail_local_minima::NodeAtBorder<Graph>::atBorder(node) ))
 
  196             isExtremum[label] = 0;
 
  201         for (neighbor_iterator arc(g, *node); arc != INVALID; ++arc) 
 
  203             if (label != regions[g.target(*arc)] && compare(src[g.target(*arc)], current)) 
 
  205                 isExtremum[label] = 0;
 
  211     for (graph_scanner node(g); node != INVALID; ++node) 
 
  213         if(isExtremum[regions[*node]])
 
  214             dest[*node] = marker;
 
  221 template <
unsigned int N, 
class T1, 
class C1, 
 
  224           class EqualityFunctor>
 
  226 localMinMax(MultiArrayView<N, T1, C1> 
const & src,
 
  227             MultiArrayView<N, T2, C2> dest,
 
  229             Compare 
const & compare,
 
  230             EqualityFunctor 
const & equal,
 
  231             LocalMinmaxOptions 
const & options = LocalMinmaxOptions())
 
  233     vigra_precondition(src.shape() == dest.shape(),
 
  234         "localMinMax(): shape mismatch between input and output.");
 
  238     if(options.neigh == 0 || options.neigh == 2*N)
 
  240     else if(options.neigh == 1 || options.neigh == MetaPow<3, N>::value - 1)
 
  243         vigra_precondition(
false,
 
  244             "localMinMax(): option object specifies invalid neighborhood type.");
 
  246     T2 marker = (T2)options.marker;
 
  248     GridGraph<N, undirected_tag> graph(src.shape(), neighborhood);
 
  249     if(options.allow_plateaus)
 
  250         return lemon_graph::extendedLocalMinMaxGraph(graph, src, dest, marker, threshold, 
 
  251                                             compare, equal, options.allow_at_border);
 
  253         return lemon_graph::localMinMaxGraph(graph, src, dest, marker, threshold, 
 
  254                                              compare, options.allow_at_border);
 
  264 template <
unsigned int N, 
class T1, 
class C1, 
class T2, 
class C2>
 
  267             MultiArrayView<N, T2, C2> dest,
 
  268             LocalMinmaxOptions 
const & options = LocalMinmaxOptions())
 
  270     T1 threshold = options.use_threshold
 
  271                            ? std::min(NumericTraits<T1>::max(), (T1)options.thresh)
 
  272                            : NumericTraits<T1>::max();
 
  273     return localMinMax(src, dest, threshold, std::less<T1>(), std::equal_to<T1>(), options);
 
  277 template <
unsigned int N, 
class T1, 
class S1,
 
  279           class EqualityFunctor>
 
  282                     MultiArrayView<N, T2, S2> dest,
 
  283                     EqualityFunctor 
const & equal,
 
  284                     LocalMinmaxOptions options = LocalMinmaxOptions())
 
  286     options.allowPlateaus();
 
  287     T1 threshold = options.use_threshold
 
  288                            ? std::min(NumericTraits<T1>::max(), (T1)options.thresh)
 
  289                            : NumericTraits<T1>::max();
 
  290     return localMinMax(src, dest, threshold, std::less<T1>(), equal, options);
 
  299 template <
unsigned int N, 
class T1, 
class C1, 
class T2, 
class C2>
 
  302             MultiArrayView<N, T2, C2> dest,
 
  303             LocalMinmaxOptions 
const & options = LocalMinmaxOptions())
 
  305     T1 threshold = options.use_threshold
 
  306                            ? std::max(NumericTraits<T1>::min(), (T1)options.thresh)
 
  307                            : NumericTraits<T1>::min();
 
  308     return localMinMax(src, dest, threshold, std::greater<T1>(), std::equal_to<T1>(), options);
 
  312 template <
unsigned int N, 
class T1, 
class S1,
 
  314           class EqualityFunctor>
 
  317                     MultiArrayView<N, T2, S2> dest,
 
  318                     EqualityFunctor 
const & equal,
 
  319                     LocalMinmaxOptions options = LocalMinmaxOptions())
 
  321     options.allowPlateaus();
 
  322     T1 threshold = options.use_threshold
 
  323                            ? std::max(NumericTraits<T1>::min(), (T1)options.thresh)
 
  324                            : NumericTraits<T1>::min();
 
  325     return localMinMax(src, dest, threshold, std::greater<T1>(), equal, options);
 
  330 #endif // VIGRA_MULTI_LOCALMINMAX_HXX 
std::pair< typename vigra::GridGraph< N, DirectedTag >::adjacency_iterator, typename vigra::GridGraph< N, DirectedTag >::adjacency_iterator > adjacent_vertices(typename vigra::GridGraph< N, DirectedTag >::vertex_descriptor const &v, vigra::GridGraph< N, DirectedTag > const &g)
Get a (begin, end) iterator pair for the neighbor vertices of vertex v in graph g (API: boost)...
Definition: multi_gridgraph.hxx:2863
void extendedLocalMinima(...)
Find local minimal regions (plateaus) in an array. 
void localMinima(...)
Find local minima in an image or multi-dimensional array. 
void put(vigra::MultiArrayView< N, T, Stride > &pmap, typename vigra::MultiArrayView< N, T, Stride >::difference_type const &k, U const &val)
Put value val at key k in the property map pmap (API: boost). 
Definition: multi_gridgraph.hxx:3004
void localMaxima(...)
Find local maxima in an image or multi-dimensional array. 
std::pair< typename vigra::GridGraph< N, DirectedTag >::vertex_iterator, typename vigra::GridGraph< N, DirectedTag >::vertex_iterator > vertices(vigra::GridGraph< N, DirectedTag > const &g)
Get a (begin, end) iterator pair for the vertices of graph g (API: boost). 
Definition: multi_gridgraph.hxx:2840
use direct and indirect neighbors 
Definition: multi_fwd.hxx:188
void extendedLocalMaxima(...)
Find local maximal regions in an array. 
use only direct neighbors 
Definition: multi_fwd.hxx:187
NeighborhoodType
Choose the neighborhood system in a dimension-independent way. 
Definition: multi_fwd.hxx:186