37 #ifndef VIGRA_SEEDEDREGIONGROWING_3D_HXX
38 #define VIGRA_SEEDEDREGIONGROWING_3D_HXX
43 #include "utilities.hxx"
44 #include "stdimage.hxx"
45 #include "stdimagefunctions.hxx"
46 #include "seededregiongrowing.hxx"
47 #include "multi_pointoperators.hxx"
48 #include "voxelneighborhood.hxx"
54 template <
class COST,
class Diff_type>
58 Diff_type location_, nearest_;
67 location_ = Diff_type(0,0,0);
68 nearest_ = Diff_type(0,0,0);
74 SeedRgVoxel(Diff_type
const & location, Diff_type
const & nearest,
75 COST
const & cost,
int const & count,
int const & label)
76 : location_(location), nearest_(nearest),
77 cost_(cost), count_(count), label_(label)
79 int dx = location_[0] - nearest_[0];
80 int dy = location_[1] - nearest_[1];
81 int dz = location_[2] - nearest_[2];
82 dist_ = dx * dx + dy * dy + dz * dz;
85 void set(Diff_type
const & location, Diff_type
const & nearest,
86 COST
const & cost,
int const & count,
int const & label)
94 int dx = location_[0] - nearest_[0];
95 int dy = location_[1] - nearest_[1];
96 int dz = location_[2] - nearest_[2];
97 dist_ = dx * dx + dy * dy + dz * dz;
103 bool operator()(SeedRgVoxel
const & l,
104 SeedRgVoxel
const & r)
const
106 if(r.cost_ == l.cost_)
108 if(r.dist_ == l.dist_)
return r.count_ < l.count_;
110 return r.dist_ < l.dist_;
113 return r.cost_ < l.cost_;
115 bool operator()(SeedRgVoxel
const * l,
116 SeedRgVoxel
const * r)
const
118 if(r->cost_ == l->cost_)
120 if(r->dist_ == l->dist_)
return r->count_ < l->count_;
122 return r->dist_ < l->dist_;
125 return r->cost_ < l->cost_;
133 while(!freelist_.empty())
135 delete freelist_.top();
140 SeedRgVoxel * create(Diff_type
const & location, Diff_type
const & nearest,
141 COST
const & cost,
int const & count,
int const & label)
143 if(!freelist_.empty())
145 SeedRgVoxel * res = freelist_.top();
147 res->set(location, nearest, cost, count, label);
151 return new SeedRgVoxel(location, nearest, cost, count, label);
154 void dismiss(SeedRgVoxel * p)
159 std::stack<SeedRgVoxel<COST,Diff_type> *> freelist_;
293 template <
class SrcImageIterator,
class Diff_type,
class SrcAccessor,
294 class SeedImageIterator,
class SeedAccessor,
295 class DestImageIterator,
class DestAccessor,
296 class RegionStatisticsArray,
class Neighborhood>
299 SeedImageIterator seedsul, SeedAccessor aseeds,
300 DestImageIterator destul, DestAccessor ad,
301 RegionStatisticsArray & stats,
306 SrcImageIterator srclr = srcul + shape;
315 SrcImageIterator isy = srcul, isx = srcul, isz = srcul;
317 typedef typename RegionStatisticsArray::value_type RegionStatistics;
318 typedef typename PromoteTraits<typename RegionStatistics::cost_type, double>::Promote CostType;
319 typedef detail::SeedRgVoxel<CostType, Diff_type> Voxel;
321 typename Voxel::Allocator allocator;
323 typedef std::priority_queue< Voxel *,
324 std::vector<Voxel *>,
325 typename Voxel::Compare > SeedRgVoxelHeap;
326 typedef MultiArray<3, int> IVolume;
329 Diff_type regionshape = shape + Diff_type(2,2,2);
330 IVolume regions(regionshape);
331 MultiIterator<3,int> ir = regions.traverser_begin();
332 ir = ir + Diff_type(1,1,1);
335 MultiIterator<3,int> iry, irx, irz;
340 copyMultiArray(seedsul, Diff_type(w,h,d), aseeds, ir, AccessorTraits<int>::default_accessor());
344 SeedRgVoxelHeap pheap;
348 static const Diff_type dist[] = { Diff_type(-1, 0, 0), Diff_type( 0,-1, 0),
349 Diff_type( 1, 0, 0), Diff_type( 0, 1, 0),
350 Diff_type( 0, 0,-1), Diff_type( 0, 0, 1) };
353 typedef typename Neighborhood::Direction
Direction;
354 int directionCount = Neighborhood::DirectionCount;
356 Diff_type pos(0,0,0);
358 for(isz=srcul, irz=ir, pos[2]=0; pos[2]<d;
359 pos[2]++, isz.dim2()++, irz.dim2()++)
363 for(isy=isz, iry=irz, pos[1]=0; pos[1]<h;
364 pos[1]++, isy.dim1()++, iry.dim1()++)
368 for(isx=isy, irx=iry, pos[0]=0; pos[0]<w;
369 pos[0]++, isx.dim0()++, irx.dim0()++)
376 for(
int i=0; i<directionCount; i++)
378 cneighbor = *(irx + Neighborhood::diff((Direction)i));
381 CostType cost = stats[cneighbor].cost(as(isx));
384 allocator.create(pos, pos+Neighborhood::diff((Direction)i), cost, count++, cneighbor);
394 while(pheap.size() != 0)
396 Voxel * voxel = pheap.top();
399 Diff_type pos = voxel->location_;
400 Diff_type nearest = voxel->nearest_;
401 int lab = voxel->label_;
402 CostType cost = voxel->cost_;
404 allocator.dismiss(voxel);
406 if((srgType & StopAtThreshold) != 0 && cost > max_cost)
415 if((srgType & KeepContours) != 0)
417 for(
int i=0; i<directionCount; i++)
419 cneighbor = * (irx + Neighborhood::diff((Direction)i));
420 if((cneighbor>0) && (cneighbor != lab))
422 lab = SRGWatershedLabel;
430 if((srgType & KeepContours) == 0 || lab > 0)
433 stats[*irx](as(isx));
437 for(
int i=0; i<directionCount; i++)
439 if(*(irx + Neighborhood::diff((Direction)i)) == 0)
441 CostType cost = stats[lab].cost(as(isx, Neighborhood::diff((Direction)i)));
444 allocator.create(pos+Neighborhood::diff((Direction)i), nearest, cost, count++, lab);
445 pheap.push(new_voxel);
452 while(pheap.size() != 0)
454 allocator.dismiss(pheap.top());
460 destul, ad, detail::UnlabelWatersheds());
463 template <
class SrcImageIterator,
class Diff_type,
class SrcAccessor,
464 class SeedImageIterator,
class SeedAccessor,
465 class DestImageIterator,
class DestAccessor,
466 class RegionStatisticsArray,
class Neighborhood >
469 SeedImageIterator seedsul, SeedAccessor aseeds,
470 DestImageIterator destul, DestAccessor ad,
471 RegionStatisticsArray & stats, SRGType srgType, Neighborhood n)
474 destul, ad, stats, srgType, n, NumericTraits<double>::max());
477 template <
class SrcImageIterator,
class Diff_type,
class SrcAccessor,
478 class SeedImageIterator,
class SeedAccessor,
479 class DestImageIterator,
class DestAccessor,
480 class RegionStatisticsArray >
483 SeedImageIterator seedsul, SeedAccessor aseeds,
484 DestImageIterator destul, DestAccessor ad,
485 RegionStatisticsArray & stats, SRGType srgType)
491 template <
class SrcImageIterator,
class Diff_type,
class SrcAccessor,
492 class SeedImageIterator,
class SeedAccessor,
493 class DestImageIterator,
class DestAccessor,
494 class RegionStatisticsArray >
497 SeedImageIterator seedsul, SeedAccessor aseeds,
498 DestImageIterator destul, DestAccessor ad,
499 RegionStatisticsArray & stats)
502 stats, CompleteGrow);
505 template <
class SrcImageIterator,
class Shape,
class SrcAccessor,
506 class SeedImageIterator,
class SeedAccessor,
507 class DestImageIterator,
class DestAccessor,
508 class RegionStatisticsArray,
class Neighborhood>
511 pair<SeedImageIterator, SeedAccessor> img3,
512 pair<DestImageIterator, DestAccessor> img4,
513 RegionStatisticsArray & stats,
514 SRGType srgType, Neighborhood n,
double max_cost)
517 img3.first, img3.second,
518 img4.first, img4.second,
519 stats, srgType, n, max_cost);
522 template <
class SrcImageIterator,
class Shape,
class SrcAccessor,
523 class SeedImageIterator,
class SeedAccessor,
524 class DestImageIterator,
class DestAccessor,
525 class RegionStatisticsArray,
class Neighborhood>
528 pair<SeedImageIterator, SeedAccessor> img3,
529 pair<DestImageIterator, DestAccessor> img4,
530 RegionStatisticsArray & stats,
531 SRGType srgType, Neighborhood n)
534 img3.first, img3.second,
535 img4.first, img4.second,
536 stats, srgType, n, NumericTraits<double>::max());
539 template <
class SrcImageIterator,
class Shape,
class SrcAccessor,
540 class SeedImageIterator,
class SeedAccessor,
541 class DestImageIterator,
class DestAccessor,
542 class RegionStatisticsArray>
545 pair<SeedImageIterator, SeedAccessor> img3,
546 pair<DestImageIterator, DestAccessor> img4,
547 RegionStatisticsArray & stats, SRGType srgType)
550 img3.first, img3.second,
551 img4.first, img4.second,
555 template <
class SrcImageIterator,
class Shape,
class SrcAccessor,
556 class SeedImageIterator,
class SeedAccessor,
557 class DestImageIterator,
class DestAccessor,
558 class RegionStatisticsArray>
561 pair<SeedImageIterator, SeedAccessor> img3,
562 pair<DestImageIterator, DestAccessor> img4,
563 RegionStatisticsArray & stats)
566 img3.first, img3.second,
567 img4.first, img4.second,
573 #endif // VIGRA_SEEDEDREGIONGROWING_HXX