36 #ifndef VIGRA_watersheds3D_HXX
37 #define VIGRA_watersheds3D_HXX
39 #include "voxelneighborhood.hxx"
40 #include "multi_array.hxx"
41 #include "union_find.hxx"
46 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
47 class DestIterator,
class DestAccessor,
class Neighborhood3D>
48 int preparewatersheds3D( SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
49 DestIterator d_Iter, DestAccessor da, Neighborhood3D)
52 int w = srcShape[0], h = srcShape[1], d = srcShape[2];
53 int x,y,z, local_min_count=0;
56 SrcIterator zs = s_Iter;
61 DestIterator zd = d_Iter;
63 for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
68 for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
73 for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
76 typename SrcAccessor::value_type v = sa(xs);
81 typename SrcAccessor::value_type my_v = v;
84 NeighborhoodCirculator<SrcIterator, Neighborhood3D> c(xs), cend(c);
92 else if(sa(c) == my_v && my_v == v)
94 o = o | c.directionBit();
101 RestrictedNeighborhoodCirculator<SrcIterator, Neighborhood3D> c(xs, atBorder), cend(c);
106 o = c.directionBit();
108 else if(sa(c) == my_v && my_v == v)
110 o = o | c.directionBit();
115 if (o==0) local_min_count++;
120 return local_min_count;
123 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
124 class DestIterator,
class DestAccessor,
125 class Neighborhood3D>
126 unsigned int watershedLabeling3D( SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
127 DestIterator d_Iter, DestAccessor da,
130 typedef typename DestAccessor::value_type LabelType;
133 int w = srcShape[0], h = srcShape[1], d = srcShape[2];
137 SrcIterator zs = s_Iter;
138 DestIterator zd = d_Iter;
141 detail::UnionFindArray<LabelType> labels;
144 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
145 NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
160 for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
163 DestIterator yd = zd;
165 for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
168 DestIterator xd = yd;
170 for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
172 LabelType currentLabel = labels.nextFreeLabel();
181 nc = NeighborOffsetCirculator<Neighborhood3D>(Neighborhood3D::CausalFirst);
187 if((sa(xs) & nc.directionBit()) || (sa(xs,*nc) & nc.oppositeDirectionBit()))
189 currentLabel = labels.makeUnion(da(xd,*nc), currentLabel);
197 nc = NeighborOffsetCirculator<Neighborhood3D>(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
199 while(nc.direction() != Neighborhood3D::Error)
203 if((sa(xs) & nc.directionBit()) || (sa(xs,*nc) & nc.oppositeDirectionBit()))
205 currentLabel = labels.makeUnion(da(xd,*nc), currentLabel);
207 nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
210 da.set(labels.finalizeLabel(currentLabel), xd);
215 unsigned int count = labels.makeContiguous();
220 for(z=0; z != d; ++z, ++zd.dim2())
224 for(y=0; y != h; ++y, ++yd.dim1())
228 for(x = 0; x != w; ++x, ++xd.dim0())
230 da.set(labels[da(xd)], xd);
370 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
371 class DestIterator,
class DestAccessor,
372 class Neighborhood3D>
373 unsigned int watersheds3D( SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
374 DestIterator d_Iter, DestAccessor da, Neighborhood3D neighborhood3D)
377 if ((
int)Neighborhood3D::DirectionCount>7){
381 preparewatersheds3D( s_Iter, srcShape, sa,
382 destMultiArray(orientationVolume).first, destMultiArray(orientationVolume).second,
385 return watershedLabeling3D( srcMultiArray(orientationVolume).first, srcShape, srcMultiArray(orientationVolume).second,
393 preparewatersheds3D( s_Iter, srcShape, sa,
394 destMultiArray(orientationVolume).first, destMultiArray(orientationVolume).second,
397 return watershedLabeling3D( srcMultiArray(orientationVolume).first, srcShape, srcMultiArray(orientationVolume).second,
403 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
404 class DestIterator,
class DestAccessor>
405 inline unsigned int watersheds3DSix( vigra::triple<SrcIterator, SrcShape, SrcAccessor> src,
406 vigra::pair<DestIterator, DestAccessor> dest)
411 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
412 class DestIterator,
class DestAccessor>
413 inline unsigned int watersheds3DTwentySix( vigra::triple<SrcIterator, SrcShape, SrcAccessor> src,
414 vigra::pair<DestIterator, DestAccessor> dest)
421 #endif //VIGRA_watersheds3D_HXX