36 #ifndef VIGRA_LABELVOLUME_HXX
37 #define VIGRA_LABELVOLUME_HXX
40 #include "voxelneighborhood.hxx"
41 #include "multi_array.hxx"
42 #include "union_find.hxx"
168 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
169 class DestIterator,
class DestAccessor,
170 class Neighborhood3D>
171 unsigned int labelVolume(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
172 DestIterator d_Iter, DestAccessor da,
173 Neighborhood3D neighborhood3D)
175 return labelVolume(s_Iter, srcShape, sa, d_Iter, da, neighborhood3D, std::equal_to<typename SrcAccessor::value_type>());
178 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
179 class DestIterator,
class DestAccessor,
180 class Neighborhood3D>
181 unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
182 pair<DestIterator, DestAccessor> dest,
183 Neighborhood3D neighborhood3D)
185 return labelVolume(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, std::equal_to<typename SrcAccessor::value_type>());
188 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
189 class DestIterator,
class DestAccessor,
190 class Neighborhood3D,
class EqualityFunctor>
191 unsigned int labelVolume(triple<SrcIterator, SrcShape, SrcAccessor> src,
192 pair<DestIterator, DestAccessor> dest,
193 Neighborhood3D neighborhood3D, EqualityFunctor equal)
195 return labelVolume(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, equal);
198 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
199 class DestIterator,
class DestAccessor,
200 class Neighborhood3D,
class EqualityFunctor>
201 unsigned int labelVolume(SrcIterator s_Iter, SrcShape srcShape, SrcAccessor sa,
202 DestIterator d_Iter, DestAccessor da,
203 Neighborhood3D, EqualityFunctor equal)
205 typedef typename DestAccessor::value_type LabelType;
208 int w = srcShape[0], h = srcShape[1], d = srcShape[2];
212 detail::UnionFindArray<LabelType> label;
215 SrcIterator zs = s_Iter;
216 DestIterator zd = d_Iter;
219 NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
234 for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
239 for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
244 for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
246 LabelType currentLabel = label.nextFreeLabel();
254 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
259 if(equal(sa(xs), sa(xs, *nc)))
261 currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
269 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
271 while(nc.direction() != Neighborhood3D::Error)
274 if(equal(sa(xs), sa(xs, *nc)))
276 currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
278 nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
281 da.set(label.finalizeLabel(currentLabel), xd);
286 LabelType count = label.makeContiguous();
291 for(z=0; z != d; ++z, ++zd.dim2())
295 for(y=0; y != h; ++y, ++yd.dim1())
299 for(x = 0; x != w; ++x, ++xd.dim0())
301 da.set(label[da(xd)], xd);
320 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
321 class DestIterator,
class DestAccessor>
323 pair<DestIterator, DestAccessor> dest)
325 return labelVolume(src.first, src.second, src.third, dest.first, dest.second,
NeighborCode3DSix(), std::equal_to<typename SrcAccessor::value_type>());
440 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
441 class DestIterator,
class DestAccessor,
442 class Neighborhood3D,
445 DestIterator d_Iter, DestAccessor da,
446 Neighborhood3D neighborhood3D, ValueType backgroundValue)
448 return labelVolumeWithBackground(s_Iter, srcShape, sa, d_Iter, da, neighborhood3D, backgroundValue, std::equal_to<typename SrcAccessor::value_type>());
451 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
452 class DestIterator,
class DestAccessor,
453 class Neighborhood3D,
456 pair<DestIterator, DestAccessor> dest,
457 Neighborhood3D neighborhood3D, ValueType backgroundValue)
459 return labelVolumeWithBackground(src.first, src.second, src.third, dest.first, dest.second, 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,
465 class ValueType,
class EqualityFunctor>
467 pair<DestIterator, DestAccessor> dest,
468 Neighborhood3D neighborhood3D, ValueType backgroundValue, EqualityFunctor equal)
470 return labelVolumeWithBackground(src.first, src.second, src.third, dest.first, dest.second, neighborhood3D, backgroundValue, equal);
473 template <
class SrcIterator,
class SrcAccessor,
class SrcShape,
474 class DestIterator,
class DestAccessor,
475 class Neighborhood3D,
476 class ValueType,
class EqualityFunctor>
478 DestIterator d_Iter, DestAccessor da,
480 ValueType backgroundValue, EqualityFunctor equal)
482 typedef typename DestAccessor::value_type LabelType;
485 int w = srcShape[0], h = srcShape[1], d = srcShape[2];
489 detail::UnionFindArray<LabelType> label;
492 SrcIterator zs = s_Iter;
493 DestIterator zd = d_Iter;
496 NeighborOffsetCirculator<Neighborhood3D> nce(Neighborhood3D::CausalLast);
511 for(z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2())
516 for(y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1())
521 for(x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0())
523 if(equal(sa(xs), backgroundValue))
525 da.set(label[0], xd);
529 LabelType currentLabel = label.nextFreeLabel();
537 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::CausalFirst);
542 if(equal(sa(xs), sa(xs, *nc)))
544 currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
552 NeighborOffsetCirculator<Neighborhood3D> nc(Neighborhood3D::nearBorderDirectionsCausal(atBorder,0));
554 while(nc.direction() != Neighborhood3D::Error)
557 if(equal(sa(xs), sa(xs, *nc)))
559 currentLabel = label.makeUnion(label[da(xd,*nc)], currentLabel);
561 nc.turnTo(Neighborhood3D::nearBorderDirectionsCausal(atBorder,++j));
564 da.set(label.finalizeLabel(currentLabel), xd);
569 LabelType count = label.makeContiguous();
574 for(z=0; z != d; ++z, ++zd.dim2())
578 for(y=0; y != h; ++y, ++yd.dim1())
582 for(x = 0; x != w; ++x, ++xd.dim0())
584 da.set(label[da(xd)], xd);
595 #endif //VIGRA_LABELVOLUME_HXX