36 #ifndef VIGRA_LABELVOLUME_HXX
37 #define VIGRA_LABELVOLUME_HXX
40 #include "voxelneighborhood.hxx"
41 #include "multi_array.hxx"
42 #include "union_find.hxx"
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 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 currentIndex = label.nextFreeIndex();
255 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
260 if(equal(sa(xs), sa(xs, *nc)))
262 currentIndex = label.makeUnion(da(xd,*nc), currentIndex);
270 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
272 while(nc.direction() != Neighborhood3D::Error)
274 int dummy = x+(*nc)[0];
277 std::cerr <<
"internal error " << dummy << std::endl;
280 if(equal(sa(xs), sa(xs, *nc)))
282 currentIndex = label.makeUnion(da(xd,*nc), currentIndex);
284 nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
287 da.set(label.finalizeIndex(currentIndex), xd);
292 LabelType count = label.makeContiguous();
297 for(z=0; z != d; ++z, ++zd.dim2())
301 for(y=0; y != h; ++y, ++yd.dim1())
305 for(x = 0; x != w; ++x, ++xd.dim0())
307 da.set(label.findLabel(da(xd)), xd);
314 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
315 class DestIterator,
class DestAccessor,
316 class Neighborhood3D>
317 unsigned int labelVolume(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
318 DestIterator d_Iter, DestAccessor da,
319 Neighborhood3D neighborhood3D)
321 return labelVolume(s_Iter, srcShape, sa, d_Iter, da, neighborhood3D, std::equal_to<typename SrcAccessor::value_type>());
324 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
325 class DestIterator,
class DestAccessor,
326 class Neighborhood3D>
327 unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
328 pair<DestIterator, DestAccessor> dest,
329 Neighborhood3D neighborhood3D)
331 return labelVolume(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, std::equal_to<typename SrcAccessor::value_type>());
334 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
335 class DestIterator,
class DestAccessor,
336 class Neighborhood3D,
class EqualityFunctor>
337 unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
338 pair<DestIterator, DestAccessor> dest,
339 Neighborhood3D neighborhood3D, EqualityFunctor equal)
341 return labelVolume(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, equal);
344 template <
class T1,
class S1,
346 class Neighborhood3D,
class EqualityFunctor>
348 labelVolume(MultiArrayView<3, T1, S1>
const & source,
349 MultiArrayView<3, T2, S2> dest,
350 Neighborhood3D neighborhood3D,
351 EqualityFunctor equal)
353 vigra_precondition(source.shape() == dest.shape(),
354 "labelVolume(): shape mismatch between input and output.");
355 return labelVolume(srcMultiArrayRange(source), destMultiArray(dest), neighborhood3D, equal);
358 template <
class T1,
class S1,
360 class Neighborhood3D>
362 labelVolume(MultiArrayView<3, T1, S1>
const & source,
363 MultiArrayView<3, T2, S2> dest,
364 Neighborhood3D neighborhood3D)
366 vigra_precondition(source.shape() == dest.shape(),
367 "labelVolume(): shape mismatch between input and output.");
368 return labelVolume(srcMultiArrayRange(source), destMultiArray(dest), neighborhood3D, std::equal_to<T1>());
383 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
384 class DestIterator,
class DestAccessor>
386 pair<DestIterator, DestAccessor> dest)
388 return labelVolume(src.first, src.second, src.third, dest.first, dest.second,
NeighborCode3DSix(), std::equal_to<typename SrcAccessor::value_type>());
391 template <
class T1,
class S1,
393 unsigned int labelVolumeSix(MultiArrayView<3, T1, S1>
const & source,
394 MultiArrayView<3, T2, S2> dest)
396 return labelVolume(srcMultiArrayRange(source), destMultiArray(dest),
532 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
533 class DestIterator,
class DestAccessor,
534 class Neighborhood3D,
535 class ValueType,
class EqualityFunctor>
537 DestIterator d_Iter, DestAccessor da,
539 ValueType backgroundValue, EqualityFunctor equal)
541 typedef typename DestAccessor::value_type LabelType;
544 int w = srcShape[0], h = srcShape[1], d = srcShape[2];
548 UnionFindArray<LabelType> label;
551 SrcIterator zs = s_Iter;
552 DestIterator zd = d_Iter;
555 NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
570 for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
575 for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
580 for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
582 if(equal(sa(xs), backgroundValue))
589 LabelType currentIndex = label.nextFreeIndex();
597 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
602 if(equal(sa(xs), sa(xs, *nc)))
604 currentIndex = label.makeUnion(da(xd,*nc), currentIndex);
612 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
614 while(nc.direction() != Neighborhood3D::Error)
616 int dummy = x+(*nc)[0];
619 std::cerr <<
"internal error " << dummy << std::endl;
622 if(equal(sa(xs), sa(xs, *nc)))
624 currentIndex = label.makeUnion(da(xd,*nc), currentIndex);
626 nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
629 da.set(label.finalizeIndex(currentIndex), xd);
634 LabelType count = label.makeContiguous();
639 for(z=0; z != d; ++z, ++zd.dim2())
643 for(y=0; y != h; ++y, ++yd.dim1())
647 for(x = 0; x != w; ++x, ++xd.dim0())
649 da.set(label.findLabel(da(xd)), xd);
656 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
657 class DestIterator,
class DestAccessor,
658 class Neighborhood3D,
662 DestIterator d_Iter, DestAccessor da,
663 Neighborhood3D neighborhood3D, ValueType backgroundValue)
665 return labelVolumeWithBackground(s_Iter, srcShape, sa, d_Iter, da, neighborhood3D, backgroundValue, std::equal_to<typename SrcAccessor::value_type>());
668 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
669 class DestIterator,
class DestAccessor,
670 class Neighborhood3D,
672 class EqualityFunctor>
675 pair<DestIterator, DestAccessor> dest,
676 Neighborhood3D neighborhood3D, ValueType backgroundValue, EqualityFunctor equal)
678 return labelVolumeWithBackground(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, backgroundValue, equal);
681 template <
class SrcIterator,
class SrcShape,
class SrcAccessor,
682 class DestIterator,
class DestAccessor,
683 class Neighborhood3D,
687 pair<DestIterator, DestAccessor> dest,
688 Neighborhood3D neighborhood3D, ValueType backgroundValue)
691 neighborhood3D, backgroundValue, std::equal_to<typename SrcAccessor::value_type>());
694 template <
class T1,
class S1,
696 class Neighborhood3D,
698 class EqualityFunctor>
701 MultiArrayView<3, T2, S2> dest,
702 Neighborhood3D neighborhood3D,
703 ValueType backgroundValue,
704 EqualityFunctor equal)
706 vigra_precondition(source.shape() == dest.shape(),
707 "labelVolumeWithBackground(): shape mismatch between input and output.");
709 neighborhood3D, backgroundValue, equal);
712 template <
class T1,
class S1,
714 class Neighborhood3D,
718 MultiArrayView<3, T2, S2> dest,
719 Neighborhood3D neighborhood3D,
720 ValueType backgroundValue)
722 vigra_precondition(source.shape() == dest.shape(),
723 "labelVolumeWithBackground(): shape mismatch between input and output.");
725 neighborhood3D, backgroundValue,
726 std::equal_to<T1>());
733 #endif //VIGRA_LABELVOLUME_HXX