37 #ifndef VIGRA_SEEDEDREGIONGROWING_3D_HXX
38 #define VIGRA_SEEDEDREGIONGROWING_3D_HXX
44 #include "stdimage.hxx"
45 #include "stdimagefunctions.hxx"
46 #include "seededregiongrowing.hxx"
47 #include "multi_shape.hxx"
48 #include "multi_pointoperators.hxx"
49 #include "voxelneighborhood.hxx"
55 template <
class COST,
class Diff_type>
59 Diff_type location_, nearest_;
68 location_ = Diff_type(0,0,0);
69 nearest_ = Diff_type(0,0,0);
75 SeedRgVoxel(Diff_type
const & location, Diff_type
const & nearest,
76 COST
const & cost,
int const & count,
int const & label)
77 : location_(location), nearest_(nearest),
78 cost_(cost), count_(count), label_(label)
80 int dx = location_[0] - nearest_[0];
81 int dy = location_[1] - nearest_[1];
82 int dz = location_[2] - nearest_[2];
83 dist_ = dx * dx + dy * dy + dz * dz;
86 void set(Diff_type
const & location, Diff_type
const & nearest,
87 COST
const & cost,
int const & count,
int const & label)
95 int dx = location_[0] - nearest_[0];
96 int dy = location_[1] - nearest_[1];
97 int dz = location_[2] - nearest_[2];
98 dist_ = dx * dx + dy * dy + dz * dz;
104 bool operator()(SeedRgVoxel
const & l,
105 SeedRgVoxel
const & r)
const
107 if(r.cost_ == l.cost_)
109 if(r.dist_ == l.dist_)
return r.count_ < l.count_;
111 return r.dist_ < l.dist_;
114 return r.cost_ < l.cost_;
116 bool operator()(SeedRgVoxel
const * l,
117 SeedRgVoxel
const * r)
const
119 if(r->cost_ == l->cost_)
121 if(r->dist_ == l->dist_)
return r->count_ < l->count_;
123 return r->dist_ < l->dist_;
126 return r->cost_ < l->cost_;
134 while(!freelist_.empty())
136 delete freelist_.top();
141 SeedRgVoxel * create(Diff_type
const & location, Diff_type
const & nearest,
142 COST
const & cost,
int const & count,
int const & label)
144 if(!freelist_.empty())
146 SeedRgVoxel * res = freelist_.top();
148 res->set(location, nearest, cost, count, label);
152 return new SeedRgVoxel(location, nearest, cost, count, label);
155 void dismiss(SeedRgVoxel * p)
160 std::stack<SeedRgVoxel<COST,Diff_type> *> freelist_;
318 template <
class SrcImageIterator,
class Diff_type,
class SrcAccessor,
319 class SeedImageIterator,
class SeedAccessor,
320 class DestImageIterator,
class DestAccessor,
321 class RegionStatisticsArray,
class Neighborhood>
324 SeedImageIterator seedsul, SeedAccessor aseeds,
325 DestImageIterator destul, DestAccessor ad,
326 RegionStatisticsArray & stats,
340 SrcImageIterator isy = srcul, isx = srcul, isz = srcul;
342 typedef typename RegionStatisticsArray::value_type RegionStatistics;
343 typedef typename PromoteTraits<typename RegionStatistics::cost_type, double>::Promote CostType;
344 typedef detail::SeedRgVoxel<CostType, Diff_type> Voxel;
346 typename Voxel::Allocator allocator;
348 typedef std::priority_queue< Voxel *,
349 std::vector<Voxel *>,
350 typename Voxel::Compare > SeedRgVoxelHeap;
351 typedef MultiArray<3, int> IVolume;
352 typedef IVolume::traverser Traverser;
355 Diff_type regionshape = shape + Diff_type(2,2,2);
356 IVolume regions(regionshape);
357 Traverser ir = regions.traverser_begin();
358 ir = ir + Diff_type(1,1,1);
361 Traverser iry, irx, irz;
366 copyMultiArray(seedsul, Diff_type(w,h,d), aseeds, ir, AccessorTraits<int>::default_accessor());
370 SeedRgVoxelHeap pheap;
373 typedef typename Neighborhood::Direction
Direction;
374 int directionCount = Neighborhood::DirectionCount;
376 Diff_type pos(0,0,0);
378 for(isz=srcul, irz=ir, pos[2]=0; pos[2]<d;
379 pos[2]++, isz.dim2()++, irz.dim2()++)
383 for(isy=isz, iry=irz, pos[1]=0; pos[1]<h;
384 pos[1]++, isy.dim1()++, iry.dim1()++)
388 for(isx=isy, irx=iry, pos[0]=0; pos[0]<w;
389 pos[0]++, isx.dim0()++, irx.dim0()++)
396 for(
int i=0; i<directionCount; i++)
398 cneighbor = *(irx + Neighborhood::diff((Direction)i));
401 CostType cost = stats[cneighbor].cost(as(isx));
404 allocator.create(pos, pos+Neighborhood::diff((Direction)i), cost, count++, cneighbor);
414 while(pheap.size() != 0)
416 Voxel * voxel = pheap.top();
419 Diff_type pos = voxel->location_;
420 Diff_type nearest = voxel->nearest_;
421 int lab = voxel->label_;
422 CostType cost = voxel->cost_;
424 allocator.dismiss(voxel);
426 if((srgType & StopAtThreshold) != 0 && cost > max_cost)
435 if((srgType & KeepContours) != 0)
437 for(
int i=0; i<directionCount; i++)
439 cneighbor = * (irx + Neighborhood::diff((Direction)i));
440 if((cneighbor>0) && (cneighbor != lab))
442 lab = SRGWatershedLabel;
450 if((srgType & KeepContours) == 0 || lab > 0)
453 stats[*irx](as(isx));
457 for(
int i=0; i<directionCount; i++)
459 if(*(irx + Neighborhood::diff((Direction)i)) == 0)
461 CostType cost = stats[lab].cost(as(isx, Neighborhood::diff((Direction)i)));
464 allocator.create(pos+Neighborhood::diff((Direction)i), nearest, cost, count++, lab);
465 pheap.push(new_voxel);
472 while(pheap.size() != 0)
474 allocator.dismiss(pheap.top());
480 destul, ad, detail::UnlabelWatersheds());
483 template <
class SrcImageIterator,
class Diff_type,
class SrcAccessor,
484 class SeedImageIterator,
class SeedAccessor,
485 class DestImageIterator,
class DestAccessor,
486 class RegionStatisticsArray,
class Neighborhood >
489 SeedImageIterator seedsul, SeedAccessor aseeds,
490 DestImageIterator destul, DestAccessor ad,
491 RegionStatisticsArray & stats,
SRGType srgType, Neighborhood n)
494 destul, ad, stats, srgType, n, NumericTraits<double>::max());
497 template <
class SrcImageIterator,
class Diff_type,
class SrcAccessor,
498 class SeedImageIterator,
class SeedAccessor,
499 class DestImageIterator,
class DestAccessor,
500 class RegionStatisticsArray >
503 SeedImageIterator seedsul, SeedAccessor aseeds,
504 DestImageIterator destul, DestAccessor ad,
505 RegionStatisticsArray & stats,
SRGType srgType)
511 template <
class SrcImageIterator,
class Diff_type,
class SrcAccessor,
512 class SeedImageIterator,
class SeedAccessor,
513 class DestImageIterator,
class DestAccessor,
514 class RegionStatisticsArray >
517 SeedImageIterator seedsul, SeedAccessor aseeds,
518 DestImageIterator destul, DestAccessor ad,
519 RegionStatisticsArray & stats)
522 stats, CompleteGrow);
525 template <
class SrcImageIterator,
class Shape,
class SrcAccessor,
526 class SeedImageIterator,
class SeedAccessor,
527 class DestImageIterator,
class DestAccessor,
528 class RegionStatisticsArray,
class Neighborhood>
531 pair<SeedImageIterator, SeedAccessor> img3,
532 pair<DestImageIterator, DestAccessor> img4,
533 RegionStatisticsArray & stats,
534 SRGType srgType, Neighborhood n,
double max_cost)
537 img3.first, img3.second,
538 img4.first, img4.second,
539 stats, srgType, n, max_cost);
542 template <
class SrcImageIterator,
class Shape,
class SrcAccessor,
543 class SeedImageIterator,
class SeedAccessor,
544 class DestImageIterator,
class DestAccessor,
545 class RegionStatisticsArray,
class Neighborhood>
548 pair<SeedImageIterator, SeedAccessor> img3,
549 pair<DestImageIterator, DestAccessor> img4,
550 RegionStatisticsArray & stats,
551 SRGType srgType, Neighborhood n)
554 img3.first, img3.second,
555 img4.first, img4.second,
556 stats, srgType, n, NumericTraits<double>::max());
559 template <
class SrcImageIterator,
class Shape,
class SrcAccessor,
560 class SeedImageIterator,
class SeedAccessor,
561 class DestImageIterator,
class DestAccessor,
562 class RegionStatisticsArray>
565 pair<SeedImageIterator, SeedAccessor> img3,
566 pair<DestImageIterator, DestAccessor> img4,
567 RegionStatisticsArray & stats,
SRGType srgType)
570 img3.first, img3.second,
571 img4.first, img4.second,
575 template <
class SrcImageIterator,
class Shape,
class SrcAccessor,
576 class SeedImageIterator,
class SeedAccessor,
577 class DestImageIterator,
class DestAccessor,
578 class RegionStatisticsArray>
581 pair<SeedImageIterator, SeedAccessor> img3,
582 pair<DestImageIterator, DestAccessor> img4,
583 RegionStatisticsArray & stats)
586 img3.first, img3.second,
587 img4.first, img4.second,
591 template <
class T1,
class S1,
594 class RegionStatisticsArray,
class Neighborhood>
597 MultiArrayView<3, TS, AS>
const & img3,
598 MultiArrayView<3, T2, S2> img4,
599 RegionStatisticsArray & stats,
600 SRGType srgType, Neighborhood n,
double max_cost)
602 vigra_precondition(img1.shape() == img3.shape(),
603 "seededRegionGrowing3D(): shape mismatch between input and output.");
606 destMultiArray(img4),
607 stats, srgType, n, max_cost);
610 template <
class T1,
class S1,
613 class RegionStatisticsArray,
class Neighborhood>
616 MultiArrayView<3, TS, AS>
const & img3,
617 MultiArrayView<3, T2, S2> img4,
618 RegionStatisticsArray & stats,
619 SRGType srgType, Neighborhood n)
621 vigra_precondition(img1.shape() == img3.shape(),
622 "seededRegionGrowing3D(): shape mismatch between input and output.");
625 destMultiArray(img4),
626 stats, srgType, n, NumericTraits<double>::max());
629 template <
class T1,
class S1,
632 class RegionStatisticsArray>
635 MultiArrayView<3, TS, AS>
const & img3,
636 MultiArrayView<3, T2, S2> img4,
637 RegionStatisticsArray & stats,
SRGType srgType)
639 vigra_precondition(img1.shape() == img3.shape(),
640 "seededRegionGrowing3D(): shape mismatch between input and output.");
643 destMultiArray(img4),
647 template <
class T1,
class S1,
650 class RegionStatisticsArray>
653 MultiArrayView<3, TS, AS>
const & img3,
654 MultiArrayView<3, T2, S2> img4,
655 RegionStatisticsArray & stats)
657 vigra_precondition(img1.shape() == img3.shape(),
658 "seededRegionGrowing3D(): shape mismatch between input and output.");
661 destMultiArray(img4),
667 #endif // VIGRA_SEEDEDREGIONGROWING_HXX
void initMultiArrayBorder(...)
Write values to the specified border values in the array.
SRGType
Definition: seededregiongrowing.hxx:176
void seededRegionGrowing3D(...)
Three-dimensional Region Segmentation by means of Seeded Region Growing.
NeighborCode::Direction Direction
Definition: pixelneighborhood.hxx:321
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
void copyMultiArray(...)
Copy a multi-dimensional array.
Neighborhood3DSix::NeighborCode3D NeighborCode3DSix
Definition: voxelneighborhood.hxx:490
void transformMultiArray(...)
Transform a multi-dimensional array with a unary function or functor.