36 #ifndef VIGRA_LABELVOLUME_HXX
37 #define VIGRA_LABELVOLUME_HXX
40 #include "voxelneighborhood.hxx"
41 #include "multi_array.hxx"
42 #include "union_find.hxx"
201 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
202 class DestIterator,
class DestAccessor,
203 class Neighborhood3D,
class EqualityFunctor>
204 unsigned int labelVolume(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
205 DestIterator d_Iter, DestAccessor da,
206 Neighborhood3D, EqualityFunctor equal)
208 typedef typename DestAccessor::value_type LabelType;
211 int w = srcShape[0], h = srcShape[1], d = srcShape[2];
215 UnionFindArray<LabelType> label;
218 SrcIterator zs = s_Iter;
219 DestIterator zd = d_Iter;
222 NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
237 for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
242 for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
247 for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
249 LabelType currentIndex = label.nextFreeIndex();
257 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
262 if(equal(sa(xs), sa(xs, *nc)))
264 currentIndex = label.makeUnion(da(xd,*nc), currentIndex);
272 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
274 while(nc.direction() != Neighborhood3D::Error)
276 int dummy = x+(*nc)[0];
279 std::cerr <<
"internal error " << dummy << std::endl;
282 if(equal(sa(xs), sa(xs, *nc)))
284 currentIndex = label.makeUnion(da(xd,*nc), currentIndex);
286 nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
289 da.set(label.finalizeIndex(currentIndex), xd);
294 LabelType count = label.makeContiguous();
299 for(z=0; z != d; ++z, ++zd.dim2())
303 for(y=0; y != h; ++y, ++yd.dim1())
307 for(x = 0; x != w; ++x, ++xd.dim0())
309 da.set(label.findLabel(da(xd)), xd);
316 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
317 class DestIterator,
class DestAccessor,
318 class Neighborhood3D>
319 unsigned int labelVolume(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
320 DestIterator d_Iter, DestAccessor da,
321 Neighborhood3D neighborhood3D)
323 return labelVolume(s_Iter, srcShape, sa, d_Iter, da, neighborhood3D, std::equal_to<typename SrcAccessor::value_type>());
326 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
327 class DestIterator,
class DestAccessor,
328 class Neighborhood3D>
329 unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
330 pair<DestIterator, DestAccessor> dest,
331 Neighborhood3D neighborhood3D)
333 return labelVolume(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, std::equal_to<typename SrcAccessor::value_type>());
336 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
337 class DestIterator,
class DestAccessor,
338 class Neighborhood3D,
class EqualityFunctor>
339 unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
340 pair<DestIterator, DestAccessor> dest,
341 Neighborhood3D neighborhood3D, EqualityFunctor equal)
343 return labelVolume(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, equal);
346 template <
class T1,
class S1,
348 class Neighborhood3D,
class EqualityFunctor>
351 MultiArrayView<3, T2, S2> dest,
352 Neighborhood3D neighborhood3D,
353 EqualityFunctor equal)
355 vigra_precondition(source.shape() == dest.shape(),
356 "labelVolume(): shape mismatch between input and output.");
357 return labelVolume(srcMultiArrayRange(source), destMultiArray(dest), neighborhood3D, equal);
360 template <
class T1,
class S1,
362 class Neighborhood3D>
364 labelVolume(MultiArrayView<3, T1, S1>
const & source,
365 MultiArrayView<3, T2, S2> dest,
366 Neighborhood3D neighborhood3D)
368 vigra_precondition(source.shape() == dest.shape(),
369 "labelVolume(): shape mismatch between input and output.");
370 return labelVolume(srcMultiArrayRange(source), destMultiArray(dest), neighborhood3D, std::equal_to<T1>());
385 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
386 class DestIterator,
class DestAccessor>
388 pair<DestIterator, DestAccessor> dest)
390 return labelVolume(src.first, src.second, src.third, dest.first, dest.second,
NeighborCode3DSix(), std::equal_to<typename SrcAccessor::value_type>());
393 template <
class T1,
class S1,
395 unsigned int labelVolumeSix(MultiArrayView<3, T1, S1>
const & source,
396 MultiArrayView<3, T2, S2> dest)
398 return labelVolume(srcMultiArrayRange(source), destMultiArray(dest),
536 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
537 class DestIterator,
class DestAccessor,
538 class Neighborhood3D,
539 class ValueType,
class EqualityFunctor>
541 DestIterator d_Iter, DestAccessor da,
543 ValueType backgroundValue, EqualityFunctor equal)
545 typedef typename DestAccessor::value_type LabelType;
548 int w = srcShape[0], h = srcShape[1], d = srcShape[2];
552 UnionFindArray<LabelType> label;
555 SrcIterator zs = s_Iter;
556 DestIterator zd = d_Iter;
559 NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
574 for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
579 for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
584 for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
586 if(equal(sa(xs), backgroundValue))
593 LabelType currentIndex = label.nextFreeIndex();
601 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
606 if(equal(sa(xs), sa(xs, *nc)))
608 currentIndex = label.makeUnion(da(xd,*nc), currentIndex);
616 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
618 while(nc.direction() != Neighborhood3D::Error)
620 int dummy = x+(*nc)[0];
623 std::cerr <<
"internal error " << dummy << std::endl;
626 if(equal(sa(xs), sa(xs, *nc)))
628 currentIndex = label.makeUnion(da(xd,*nc), currentIndex);
630 nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
633 da.set(label.finalizeIndex(currentIndex), xd);
638 LabelType count = label.makeContiguous();
643 for(z=0; z != d; ++z, ++zd.dim2())
647 for(y=0; y != h; ++y, ++yd.dim1())
651 for(x = 0; x != w; ++x, ++xd.dim0())
653 da.set(label.findLabel(da(xd)), xd);
660 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
661 class DestIterator,
class DestAccessor,
662 class Neighborhood3D,
666 DestIterator d_Iter, DestAccessor da,
667 Neighborhood3D neighborhood3D, ValueType backgroundValue)
669 return labelVolumeWithBackground(s_Iter, srcShape, sa, d_Iter, da, neighborhood3D, backgroundValue, std::equal_to<typename SrcAccessor::value_type>());
672 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
673 class DestIterator,
class DestAccessor,
674 class Neighborhood3D,
676 class EqualityFunctor>
679 pair<DestIterator, DestAccessor> dest,
680 Neighborhood3D neighborhood3D, ValueType backgroundValue, EqualityFunctor equal)
682 return labelVolumeWithBackground(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, backgroundValue, equal);
685 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
686 class DestIterator,
class DestAccessor,
687 class Neighborhood3D,
691 pair<DestIterator, DestAccessor> dest,
692 Neighborhood3D neighborhood3D, ValueType backgroundValue)
695 neighborhood3D, backgroundValue, std::equal_to<typename SrcAccessor::value_type>());
698 template <
class T1,
class S1,
700 class Neighborhood3D,
702 class EqualityFunctor>
705 MultiArrayView<3, T2, S2> dest,
706 Neighborhood3D neighborhood3D,
707 ValueType backgroundValue,
708 EqualityFunctor equal)
710 vigra_precondition(source.shape() == dest.shape(),
711 "labelVolumeWithBackground(): shape mismatch between input and output.");
713 neighborhood3D, backgroundValue, equal);
716 template <
class T1,
class S1,
718 class Neighborhood3D,
722 MultiArrayView<3, T2, S2> dest,
723 Neighborhood3D neighborhood3D,
724 ValueType backgroundValue)
726 vigra_precondition(source.shape() == dest.shape(),
727 "labelVolumeWithBackground(): shape mismatch between input and output.");
729 neighborhood3D, backgroundValue,
730 std::equal_to<T1>());
737 #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:387
unsigned int labelVolumeWithBackground(...)
Find the connected components of a segmented volume, excluding the background from labeling...
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
Encapsulation of direction management of neighbors for a 3D 6-neighborhood.
Definition: voxelneighborhood.hxx:163
Definition: pixelneighborhood.hxx:70