36 #ifndef VIGRA_watersheds3D_HXX 
   37 #define VIGRA_watersheds3D_HXX 
   39 #include "voxelneighborhood.hxx" 
   40 #include "multi_array.hxx" 
   41 #include "multi_localminmax.hxx" 
   42 #include "labelvolume.hxx" 
   43 #include "seededregiongrowing3d.hxx" 
   44 #include "watersheds.hxx" 
   49 template <
class SrcIterator, 
class SrcAccessor, 
class SrcShape,
 
   50           class DestIterator, 
class DestAccessor, 
class Neighborhood3D>
 
   51 int preparewatersheds3D( SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
 
   52                          DestIterator d_Iter, DestAccessor da, Neighborhood3D)
 
   55     int w = srcShape[0], h = srcShape[1], d = srcShape[2];
 
   56     int x,y,z, local_min_count=0;
 
   59     SrcIterator zs = s_Iter;
 
   64     DestIterator zd = d_Iter;
 
   66     for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
 
   71         for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
 
   76             for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
 
   79                 typename SrcAccessor::value_type v = sa(xs);
 
   84                 typename SrcAccessor::value_type my_v = v;
 
   87                     NeighborhoodCirculator<SrcIterator, Neighborhood3D>  c(xs), cend(c);
 
   95                         else if(sa(c) == my_v && my_v == v)
 
   97                             o =  o | c.directionBit();
 
  104                     RestrictedNeighborhoodCirculator<SrcIterator, Neighborhood3D>  c(xs, atBorder), cend(c);
 
  109                             o = c.directionBit();
 
  111                         else if(sa(c) == my_v && my_v == v)
 
  113                             o =  o | c.directionBit();
 
  118                 if (o==0) local_min_count++;
 
  123     return local_min_count;
 
  126 template <
class SrcIterator, 
class SrcAccessor,
class SrcShape,
 
  127           class DestIterator, 
class DestAccessor,
 
  128           class Neighborhood3D>
 
  129 unsigned int watershedLabeling3D( SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
 
  130                                   DestIterator d_Iter, DestAccessor da,
 
  133     typedef typename DestAccessor::value_type LabelType;
 
  136     int w = srcShape[0], h = srcShape[1], d = srcShape[2];
 
  140     SrcIterator zs = s_Iter;
 
  141     DestIterator zd = d_Iter;
 
  144     UnionFindArray<LabelType> labels;
 
  147     NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
 
  148     NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
 
  163     for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
 
  166         DestIterator yd = zd;
 
  168         for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
 
  171             DestIterator xd = yd;
 
  173             for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
 
  175                 LabelType currentIndex = labels.nextFreeIndex(); 
 
  184                     nc = NeighborOffsetCirculator<Neighborhood3D>(Neighborhood3D::CausalFirst);
 
  190                         if((sa(xs) & nc.directionBit()) || (sa(xs,*nc) & nc.oppositeDirectionBit()))
 
  192                             currentIndex = labels.makeUnion(da(xd,*nc), currentIndex);
 
  200                     nc = NeighborOffsetCirculator<Neighborhood3D>(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
 
  202                     while(nc.direction() != Neighborhood3D::Error)
 
  206                         if((sa(xs) & nc.directionBit()) || (sa(xs,*nc) & nc.oppositeDirectionBit()))
 
  208                             currentIndex = labels.makeUnion(da(xd,*nc), currentIndex);
 
  210                         nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
 
  213                 da.set(labels.finalizeIndex(currentIndex), xd);
 
  218     unsigned int count = labels.makeContiguous();
 
  223     for(z=0; z != d; ++z, ++zd.dim2())
 
  227         for(y=0; y != h; ++y, ++yd.dim1())
 
  231             for(x = 0; x != w; ++x, ++xd.dim0())
 
  233                 da.set(labels.findLabel(da(xd)), xd);
 
  387 template <
class SrcIterator, 
class SrcAccessor, 
class SrcShape,
 
  388           class DestIterator, 
class DestAccessor,
 
  389           class Neighborhood3D>
 
  390 unsigned int watersheds3D( SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
 
  391                            DestIterator d_Iter, DestAccessor da, Neighborhood3D neighborhood3D)
 
  394     if ((
int)Neighborhood3D::DirectionCount>7){  
 
  398         preparewatersheds3D( s_Iter, srcShape, sa,
 
  399                              destMultiArray(orientationVolume).first, destMultiArray(orientationVolume).second,
 
  402         return watershedLabeling3D( srcMultiArray(orientationVolume).first, srcShape, srcMultiArray(orientationVolume).second,
 
  410         preparewatersheds3D( s_Iter, srcShape, sa,
 
  411                               destMultiArray(orientationVolume).first, destMultiArray(orientationVolume).second,
 
  414         return watershedLabeling3D( srcMultiArray(orientationVolume).first, srcShape, srcMultiArray(orientationVolume).second,
 
  420 template <
class SrcIterator, 
class SrcShape, 
class SrcAccessor,
 
  421           class DestIterator, 
class DestAccessor>
 
  422 inline unsigned int watersheds3DSix( triple<SrcIterator, SrcShape, SrcAccessor> src,
 
  423                                      pair<DestIterator, DestAccessor> dest)
 
  428 template <
class SrcIterator, 
class SrcShape, 
class SrcAccessor,
 
  429           class DestIterator, 
class DestAccessor>
 
  430 inline unsigned int watersheds3DTwentySix( triple<SrcIterator, SrcShape, SrcAccessor> src,
 
  431                                            pair<DestIterator, DestAccessor> dest)
 
  436 template <
unsigned int N, 
class T1, 
class S1,
 
  439 watersheds3DSix(MultiArrayView<N, T1, S1> 
const & 
source,
 
  440                 MultiArrayView<N, T2, S2> dest)
 
  442     vigra_precondition(source.shape() == dest.shape(),
 
  443         "watersheds3DSix(): shape mismatch between input and output.");
 
  444     return watersheds3DSix(srcMultiArrayRange(source), destMultiArray(dest));
 
  447 template <
unsigned int N, 
class T1, 
class S1,
 
  450 watersheds3DTwentySix(MultiArrayView<N, T1, S1> 
const & source,
 
  451                       MultiArrayView<N, T2, S2> dest)
 
  453     vigra_precondition(source.shape() == dest.shape(),
 
  454         "watersheds3DTwentySix(): shape mismatch between input and output.");
 
  455     return watersheds3DTwentySix(srcMultiArrayRange(source), destMultiArray(dest));
 
  460 #endif //VIGRA_watersheds3D_HXX 
AtImageBorder AtVolumeBorder
Encode whether a voxel is near the volume border. 
Definition: voxelneighborhood.hxx:72
Neighborhood3DTwentySix::NeighborCode3D NeighborCode3DTwentySix
Definition: voxelneighborhood.hxx:1646
Main MultiArray class containing the memory management. 
Definition: multi_array.hxx:2474
AtVolumeBorder isAtVolumeBorderCausal(int x, int y, int z, int width, int height, int)
Find out whether a voxel is at a scan-order relevant volume border. This function checks if x == 0 or...
Definition: voxelneighborhood.hxx:112
AtVolumeBorder isAtVolumeBorder(int x, int y, int z, int width, int height, int depth)
Find out whether a voxel is at the volume border. 
Definition: voxelneighborhood.hxx:82
vigra::GridGraph< N, DirectedTag >::vertex_descriptor source(typename vigra::GridGraph< N, DirectedTag >::edge_descriptor const &e, vigra::GridGraph< N, DirectedTag > const &g)
Get a vertex descriptor for the start vertex of edge e in graph g (API: boost). 
Definition: multi_gridgraph.hxx:2943
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays. 
Neighborhood3DSix::NeighborCode3D NeighborCode3DSix
Definition: voxelneighborhood.hxx:490
unsigned int watersheds3D(...)
Region Segmentation by means of the watershed algorithm. 
  
Definition: pixelneighborhood.hxx:70