36 #ifndef VIGRA_LABELVOLUME_HXX
37 #define VIGRA_LABELVOLUME_HXX
40 #include "voxelneighborhood.hxx"
41 #include "multi_array.hxx"
42 #include "union_find.hxx"
166 doxygen_overloaded_function(template <...>
unsigned int labelVolume)
169 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
170 class DestIterator,
class DestAccessor,
171 class Neighborhood3D>
172 unsigned int labelVolume(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
173 DestIterator d_Iter, DestAccessor da,
174 Neighborhood3D neighborhood3D)
176 return labelVolume(s_Iter, srcShape, sa, d_Iter, da, neighborhood3D, std::equal_to<typename SrcAccessor::value_type>());
179 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
180 class DestIterator,
class DestAccessor,
181 class Neighborhood3D>
182 unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
183 pair<DestIterator, DestAccessor> dest,
184 Neighborhood3D neighborhood3D)
186 return labelVolume(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, std::equal_to<typename SrcAccessor::value_type>());
189 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
190 class DestIterator,
class DestAccessor,
191 class Neighborhood3D,
class EqualityFunctor>
192 unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
193 pair<DestIterator, DestAccessor> dest,
194 Neighborhood3D neighborhood3D, EqualityFunctor equal)
196 return labelVolume(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, equal);
199 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
200 class DestIterator,
class DestAccessor,
201 class Neighborhood3D,
class EqualityFunctor>
202 unsigned int labelVolume(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
203 DestIterator d_Iter, DestAccessor da,
204 Neighborhood3D, EqualityFunctor equal)
206 typedef typename DestAccessor::value_type LabelType;
209 int w = srcShape[0], h = srcShape[1], d = srcShape[2];
213 detail::UnionFindArray<LabelType> label;
216 SrcIterator zs = s_Iter;
217 DestIterator zd = d_Iter;
220 NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
235 for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
240 for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
245 for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
247 LabelType currentLabel = label.nextFreeLabel();
255 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
260 if(equal(sa(xs), sa(xs, *nc)))
262 currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
270 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
272 while(nc.direction() != Neighborhood3D::Error)
285 if(equal(sa(xs), sa(xs, *nc)))
287 currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
289 nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
292 da.set(label.finalizeLabel(currentLabel), xd);
297 LabelType count = label.makeContiguous();
302 for(z=0; z != d; ++z, ++zd.dim2())
306 for(y=0; y != h; ++y, ++yd.dim1())
310 for(x = 0; x != w; ++x, ++xd.dim0())
312 da.set(label[da(xd)], xd);
331 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
332 class DestIterator,
class DestAccessor>
334 pair<DestIterator, DestAccessor> dest)
336 return labelVolume(src.first, src.second, src.third, dest.first, dest.second,
NeighborCode3DSix(), std::equal_to<typename SrcAccessor::value_type>());
451 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
452 class DestIterator,
class DestAccessor,
453 class Neighborhood3D,
456 DestIterator d_Iter, DestAccessor da,
457 Neighborhood3D neighborhood3D, ValueType backgroundValue)
459 return labelVolumeWithBackground(s_Iter, srcShape, sa, d_Iter, da, neighborhood3D, backgroundValue, std::equal_to<typename SrcAccessor::value_type>());
462 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
463 class DestIterator,
class DestAccessor,
464 class Neighborhood3D,
467 pair<DestIterator, DestAccessor> dest,
468 Neighborhood3D neighborhood3D, ValueType backgroundValue)
470 return labelVolumeWithBackground(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, backgroundValue, std::equal_to<typename SrcAccessor::value_type>());
473 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
474 class DestIterator,
class DestAccessor,
475 class Neighborhood3D,
476 class ValueType,
class EqualityFunctor>
478 pair<DestIterator, DestAccessor> dest,
479 Neighborhood3D neighborhood3D, ValueType backgroundValue, EqualityFunctor equal)
481 return labelVolumeWithBackground(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, backgroundValue, equal);
484 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
485 class DestIterator,
class DestAccessor,
486 class Neighborhood3D,
487 class ValueType,
class EqualityFunctor>
489 DestIterator d_Iter, DestAccessor da,
491 ValueType backgroundValue, EqualityFunctor equal)
493 typedef typename DestAccessor::value_type LabelType;
496 int w = srcShape[0], h = srcShape[1], d = srcShape[2];
500 detail::UnionFindArray<LabelType> label;
503 SrcIterator zs = s_Iter;
504 DestIterator zd = d_Iter;
507 NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
522 for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
527 for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
532 for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
534 if(equal(sa(xs), backgroundValue))
536 da.set(label[0], xd);
540 LabelType currentLabel = label.nextFreeLabel();
548 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
553 if(equal(sa(xs), sa(xs, *nc)))
555 currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
563 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
565 while(nc.direction() != Neighborhood3D::Error)
568 if(equal(sa(xs), sa(xs, *nc)))
570 currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
572 nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
575 da.set(label.finalizeLabel(currentLabel), xd);
580 LabelType count = label.makeContiguous();
585 for(z=0; z != d; ++z, ++zd.dim2())
589 for(y=0; y != h; ++y, ++yd.dim1())
593 for(x = 0; x != w; ++x, ++xd.dim0())
595 da.set(label[da(xd)], xd);
606 #endif //VIGRA_LABELVOLUME_HXX
unsigned int labelVolume(...)
Find the connected components of a segmented volume.
AtImageBorder AtVolumeBorder
Encode whether a voxel is near the volume border.
Definition: voxelneighborhood.hxx:72
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
unsigned int labelVolumeSix(triple< SrcIterator, SrcShape, SrcAccessor > src, pair< DestIterator, DestAccessor > dest)
Find the connected components of a segmented volume using the 6-neighborhood.
Definition: labelvolume.hxx:333
unsigned int labelVolumeWithBackground(...)
Find the connected components of a segmented volume, excluding the background from labeling...
Encapsulation of direction management of neighbors for a 3D 6-neighborhood.
Definition: voxelneighborhood.hxx:163
Definition: pixelneighborhood.hxx:70