36 #ifndef VIGRA_BLOCKWISE_WATERSHEDS_HXX 
   37 #define VIGRA_BLOCKWISE_WATERSHEDS_HXX 
   39 #include "threadpool.hxx" 
   40 #include "multi_array.hxx" 
   41 #include "multi_gridgraph.hxx" 
   42 #include "blockify.hxx" 
   43 #include "blockwise_labeling.hxx" 
   44 #include "metaprogramming.hxx" 
   45 #include "overlapped_blocks.hxx" 
   56 namespace blockwise_watersheds_detail
 
   59 template <
class DataArray, 
class DirectionsBlocksIterator>
 
   60 void prepareBlockwiseWatersheds(
const Overlaps<DataArray>& overlaps,
 
   61                                 DirectionsBlocksIterator directions_blocks_begin,
 
   62                                 BlockwiseLabelOptions 
const & options)
 
   64     static const unsigned int N = DataArray::actual_dimension;
 
   66     typedef typename MultiArrayShape<DataArray::actual_dimension>::type Shape;
 
   67     typedef typename DirectionsBlocksIterator::value_type DirectionsBlock;
 
   68     Shape shape = overlaps.shape();
 
   69     vigra_assert(shape == directions_blocks_begin.shape(), 
"");
 
   71     MultiCoordinateIterator<DataArray::actual_dimension> itBegin(shape);
 
   72     MultiCoordinateIterator<DataArray::actual_dimension> end = itBegin.getEndIterator();
 
   73     typedef typename MultiCoordinateIterator<DataArray::actual_dimension>::value_type Coordinate;
 
   77         [&](
const int , 
const Coordinate  iterVal){
 
   79             DirectionsBlock directions_block = directions_blocks_begin[iterVal];
 
   80             OverlappingBlock<DataArray> data_block = overlaps[iterVal];
 
   82             typedef GridGraph<DataArray::actual_dimension, undirected_tag> Graph;
 
   83             typedef typename Graph::NodeIt GraphScanner;
 
   84             typedef typename Graph::OutArcIt NeighborIterator;
 
   86             Graph graph(data_block.block.shape(), options.getNeighborhood());
 
   87             for(GraphScanner node(graph); node != lemon::INVALID; ++node)
 
   89                 if(within(*node, data_block.inner_bounds))
 
   91                     typedef typename DataArray::value_type Data;
 
   92                     Data lowest_neighbor = data_block.block[*node];
 
   94                     typedef typename DirectionsBlock::value_type 
Direction;
 
   95                     Direction lowest_neighbor_direction = std::numeric_limits<unsigned short>::max();
 
   97                     for(NeighborIterator arc(graph, *node); arc != lemon::INVALID; ++arc)
 
   99                         Shape neighbor_coordinates = graph.target(*arc);
 
  100                         Data neighbor_data = data_block.block[neighbor_coordinates];
 
  101                         if(neighbor_data < lowest_neighbor)
 
  103                             lowest_neighbor = neighbor_data;
 
  104                             lowest_neighbor_direction = arc.neighborIndex();
 
  107                     directions_block[*node - data_block.inner_bounds.first] = lowest_neighbor_direction;
 
  114 template <
unsigned int N>
 
  115 struct UnionFindWatershedsEquality
 
  119     GridGraph<N, undirected_tag>* graph;
 
  121     template <
class Shape>
 
  122     bool operator()(
unsigned short u, 
const unsigned short v, 
const Shape& diff)
 const 
  124         static const unsigned short plateau_id = std::numeric_limits<unsigned short>::max();
 
  125         return (u == plateau_id && v == plateau_id) ||
 
  126                (u != plateau_id && graph->neighborOffset(u) == diff) ||
 
  127                (v != plateau_id && graph->neighborOffset(graph->oppositeIndex(v)) == diff);
 
  200 template <
unsigned int N, 
class Data, 
class S1,
 
  201                           class Label, 
class S2>
 
  203                                    MultiArrayView<N, Label, S2> labels,
 
  204                                    BlockwiseLabelOptions 
const & options = BlockwiseLabelOptions())
 
  206     using namespace blockwise_watersheds_detail;
 
  208     typedef typename MultiArrayView<N, Data, S1>::difference_type Shape;
 
  209     Shape shape = data.shape();
 
  210     vigra_precondition(shape == labels.shape(), 
"shapes of data and labels do not match");
 
  212     MultiArray<N, unsigned short> directions(shape);
 
  213     Shape block_shape = options.getBlockShapeN<N>();
 
  215     MultiArray<N, MultiArrayView<N, unsigned short> > directions_blocks = blockify(directions, block_shape);
 
  217     Overlaps<MultiArrayView<N, Data, S1> > overlaps(data, block_shape, Shape(1), Shape(1));
 
  218     prepareBlockwiseWatersheds(overlaps, directions_blocks.begin(), options);
 
  219     GridGraph<N, undirected_tag> graph(data.shape(), options.getNeighborhood());
 
  220     UnionFindWatershedsEquality<N> equal = {&graph};
 
  224 template <
unsigned int N, 
class Data, 
class Label>
 
  226                                    ChunkedArray<N, Label>& labels,
 
  227                                    BlockwiseLabelOptions 
const & options,
 
  228                                    ChunkedArray<N, unsigned short>& directions)
 
  230     using namespace blockwise_watersheds_detail;
 
  232     typedef typename ChunkedArray<N, Data>::shape_type Shape;
 
  233     Shape shape = data.shape();
 
  234     vigra_precondition(shape == labels.shape() && shape == directions.shape(),
 
  235         "unionFindWatershedsBlockwise(): shapes of data and labels do not match");
 
  236     Shape chunk_shape = data.chunkShape();
 
  237     vigra_precondition(chunk_shape == labels.chunkShape() && chunk_shape == directions.chunkShape(),
 
  238         "unionFindWatershedsBlockwise(): chunk shapes do not match");
 
  240     Overlaps<ChunkedArray<N, Data> > overlaps(data, data.chunkShape(), Shape(1), Shape(1));
 
  242     prepareBlockwiseWatersheds(overlaps, directions.chunk_begin(Shape(0), shape), options);
 
  244     GridGraph<N, undirected_tag> graph(shape, options.getNeighborhood());
 
  245     UnionFindWatershedsEquality<N> equal = {&graph};
 
  249 template <
unsigned int N, 
class Data,
 
  253                                    ChunkedArray<N, Label>& labels,
 
  254                                    BlockwiseLabelOptions 
const & options = BlockwiseLabelOptions())
 
  256     ChunkedArrayLazy<N, unsigned short> directions(data.shape(), data.chunkShape());
 
  264 #endif // VIGRA_BLOCKWISE_WATERSHEDS_HXX 
NeighborCode::Direction Direction
Definition: pixelneighborhood.hxx:321
unsigned int labelMultiArrayBlockwise(...)
Connected components labeling for MultiArrays and ChunkedArrays. 
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays. 
void parallel_foreach(...)
Apply a functor to all items in a range in parallel. 
unsigned int unionFindWatershedsBlockwise(...)
Blockwise union-find watersheds transform for MultiArrays and ChunkedArrays.