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