36 #ifndef VIGRA_LABELVOLUME_HXX
37 #define VIGRA_LABELVOLUME_HXX
40 #include "voxelneighborhood.hxx"
41 #include "multi_array.hxx"
42 #include "union_find.hxx"
196 doxygen_overloaded_function(template <...>
unsigned int labelVolume)
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)
275 SrcShape s(x,y,z), sn = s + *nc;
277 if (sn[0]<0 || sn[0]>=w || sn[1]<0 || sn[1]>=h || sn[2]<0 || sn[2]>=d)
279 std::cerr <<
"coordinate error at " << s <<
", offset " << *nc <<
", index " << (nc).direction() <<
" at border " <<
280 atBorder << std::endl;
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);
319 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
320 class DestIterator,
class DestAccessor,
321 class Neighborhood3D>
322 unsigned int labelVolume(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
323 DestIterator d_Iter, DestAccessor da,
324 Neighborhood3D neighborhood3D)
326 return labelVolume(s_Iter, srcShape, sa, d_Iter, da, neighborhood3D, std::equal_to<typename SrcAccessor::value_type>());
329 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
330 class DestIterator,
class DestAccessor,
331 class Neighborhood3D>
332 unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
333 pair<DestIterator, DestAccessor> dest,
334 Neighborhood3D neighborhood3D)
336 return labelVolume(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, std::equal_to<typename SrcAccessor::value_type>());
339 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
340 class DestIterator,
class DestAccessor,
341 class Neighborhood3D,
class EqualityFunctor>
342 unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
343 pair<DestIterator, DestAccessor> dest,
344 Neighborhood3D neighborhood3D, EqualityFunctor equal)
346 return labelVolume(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, equal);
349 template <
class T1,
class S1,
351 class Neighborhood3D,
class EqualityFunctor>
354 MultiArrayView<3, T2, S2> dest,
355 Neighborhood3D neighborhood3D,
356 EqualityFunctor equal)
358 vigra_precondition(source.shape() == dest.shape(),
359 "labelVolume(): shape mismatch between input and output.");
360 return labelVolume(srcMultiArrayRange(source), destMultiArray(dest), neighborhood3D, equal);
363 template <
class T1,
class S1,
365 class Neighborhood3D>
367 labelVolume(MultiArrayView<3, T1, S1>
const & source,
368 MultiArrayView<3, T2, S2> dest,
369 Neighborhood3D neighborhood3D)
371 vigra_precondition(source.shape() == dest.shape(),
372 "labelVolume(): shape mismatch between input and output.");
373 return labelVolume(srcMultiArrayRange(source), destMultiArray(dest), neighborhood3D, std::equal_to<T1>());
388 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
389 class DestIterator,
class DestAccessor>
391 pair<DestIterator, DestAccessor> dest)
393 return labelVolume(src.first, src.second, src.third, dest.first, dest.second,
NeighborCode3DSix(), std::equal_to<typename SrcAccessor::value_type>());
396 template <
class T1,
class S1,
398 unsigned int labelVolumeSix(MultiArrayView<3, T1, S1>
const & source,
399 MultiArrayView<3, T2, S2> dest)
401 return labelVolume(srcMultiArrayRange(source), destMultiArray(dest),
537 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
538 class DestIterator,
class DestAccessor,
539 class Neighborhood3D,
540 class ValueType,
class EqualityFunctor>
542 DestIterator d_Iter, DestAccessor da,
544 ValueType backgroundValue, EqualityFunctor equal)
546 typedef typename DestAccessor::value_type LabelType;
549 int w = srcShape[0], h = srcShape[1], d = srcShape[2];
553 detail::UnionFindArray<LabelType> label;
556 SrcIterator zs = s_Iter;
557 DestIterator zd = d_Iter;
560 NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
575 for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
580 for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
585 for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
587 if(equal(sa(xs), backgroundValue))
589 da.set(label[0], xd);
593 LabelType currentLabel = label.nextFreeLabel();
601 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
606 if(equal(sa(xs), sa(xs, *nc)))
608 currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
616 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
618 while(nc.direction() != Neighborhood3D::Error)
620 SrcShape s(x,y,z), sn = s + *nc;
622 if (sn[0]<0 || sn[0]>=w || sn[1]<0 || sn[1]>=h || sn[2]<0 || sn[2]>=d)
624 std::cerr <<
"coordinate error at " << s <<
", offset " << *nc <<
", index " << (nc).direction() <<
" at border " <<
625 atBorder << std::endl;
629 if(equal(sa(xs), sa(xs, *nc)))
631 currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
633 nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
636 da.set(label.finalizeLabel(currentLabel), xd);
641 LabelType count = label.makeContiguous();
646 for(z=0; z != d; ++z, ++zd.dim2())
650 for(y=0; y != h; ++y, ++yd.dim1())
654 for(x = 0; x != w; ++x, ++xd.dim0())
656 da.set(label[da(xd)], xd);
663 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
664 class DestIterator,
class DestAccessor,
665 class Neighborhood3D,
669 DestIterator d_Iter, DestAccessor da,
670 Neighborhood3D neighborhood3D, ValueType backgroundValue)
672 return labelVolumeWithBackground(s_Iter, srcShape, sa, d_Iter, da, neighborhood3D, backgroundValue, std::equal_to<typename SrcAccessor::value_type>());
675 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
676 class DestIterator,
class DestAccessor,
677 class Neighborhood3D,
679 class EqualityFunctor>
682 pair<DestIterator, DestAccessor> dest,
683 Neighborhood3D neighborhood3D, ValueType backgroundValue, EqualityFunctor equal)
685 return labelVolumeWithBackground(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, backgroundValue, equal);
688 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
689 class DestIterator,
class DestAccessor,
690 class Neighborhood3D,
694 pair<DestIterator, DestAccessor> dest,
695 Neighborhood3D neighborhood3D, ValueType backgroundValue)
698 neighborhood3D, backgroundValue, std::equal_to<typename SrcAccessor::value_type>());
701 template <
class T1,
class S1,
703 class Neighborhood3D,
705 class EqualityFunctor>
708 MultiArrayView<3, T2, S2> dest,
709 Neighborhood3D neighborhood3D,
710 ValueType backgroundValue,
711 EqualityFunctor equal)
713 vigra_precondition(source.shape() == dest.shape(),
714 "labelVolumeWithBackground(): shape mismatch between input and output.");
716 neighborhood3D, backgroundValue, equal);
719 template <
class T1,
class S1,
721 class Neighborhood3D,
725 MultiArrayView<3, T2, S2> dest,
726 Neighborhood3D neighborhood3D,
727 ValueType backgroundValue)
729 vigra_precondition(source.shape() == dest.shape(),
730 "labelVolumeWithBackground(): shape mismatch between input and output.");
732 neighborhood3D, backgroundValue,
733 std::equal_to<T1>());
740 #endif //VIGRA_LABELVOLUME_HXX
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:2786
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:390
unsigned int labelVolumeWithBackground(...)
Find the connected components of a segmented volume, excluding the background from labeling...
Neighborhood3DSix::NeighborCode3D NeighborCode3DSix
Definition: voxelneighborhood.hxx:490
Encapsulation of direction management of neighbors for a 3D 6-neighborhood.
Definition: voxelneighborhood.hxx:163
Definition: pixelneighborhood.hxx:70