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_;
292 template <
class SrcImageIterator,
class Diff_type,
class SrcAccessor,
293 class SeedImageIterator,
class SeedAccessor,
294 class DestImageIterator,
class DestAccessor,
295 class RegionStatisticsArray,
class Neighborhood>
298 SeedImageIterator seedsul, SeedAccessor aseeds,
299 DestImageIterator destul, DestAccessor ad,
300 RegionStatisticsArray & stats,
305 SrcImageIterator srclr = srcul + shape;
314 SrcImageIterator isy = srcul, isx = srcul, isz = srcul;
316 typedef typename RegionStatisticsArray::value_type RegionStatistics;
317 typedef typename PromoteTraits<typename RegionStatistics::cost_type, double>::Promote CostType;
318 typedef detail::SeedRgVoxel<CostType, Diff_type> Voxel;
320 typename Voxel::Allocator allocator;
322 typedef std::priority_queue< Voxel *,
323 std::vector<Voxel *>,
324 typename Voxel::Compare > SeedRgVoxelHeap;
325 typedef MultiArray<3, int> IVolume;
328 Diff_type regionshape = shape + Diff_type(2,2,2);
329 IVolume regions(regionshape);
330 MultiIterator<3,int> ir = regions.traverser_begin();
331 ir = ir + Diff_type(1,1,1);
334 MultiIterator<3,int> iry, irx, irz;
339 copyMultiArray(seedsul, Diff_type(w,h,d), aseeds, ir, AccessorTraits<int>::default_accessor());
343 SeedRgVoxelHeap pheap;
347 static const Diff_type dist[] = { Diff_type(-1, 0, 0), Diff_type( 0,-1, 0),
348 Diff_type( 1, 0, 0), Diff_type( 0, 1, 0),
349 Diff_type( 0, 0,-1), Diff_type( 0, 0, 1) };
352 typedef typename Neighborhood::Direction
Direction;
353 int directionCount = Neighborhood::DirectionCount;
355 Diff_type pos(0,0,0);
357 for(isz=srcul, irz=ir, pos[2]=0; pos[2]<d;
358 pos[2]++, isz.dim2()++, irz.dim2()++)
362 for(isy=isz, iry=irz, pos[1]=0; pos[1]<h;
363 pos[1]++, isy.dim1()++, iry.dim1()++)
367 for(isx=isy, irx=iry, pos[0]=0; pos[0]<w;
368 pos[0]++, isx.dim0()++, irx.dim0()++)
375 for(
int i=0; i<directionCount; i++)
377 cneighbor = *(irx + Neighborhood::diff((Direction)i));
380 CostType cost = stats[cneighbor].cost(as(isx));
383 allocator.create(pos, pos+Neighborhood::diff((Direction)i), cost, count++, cneighbor);
393 while(pheap.size() != 0)
395 Voxel * voxel = pheap.top();
398 Diff_type pos = voxel->location_;
399 Diff_type nearest = voxel->nearest_;
400 int lab = voxel->label_;
401 CostType cost = voxel->cost_;
403 allocator.dismiss(voxel);
405 if((srgType & StopAtThreshold) != 0 && cost > max_cost)
414 if((srgType & KeepContours) != 0)
416 for(
int i=0; i<directionCount; i++)
418 cneighbor = * (irx + Neighborhood::diff((Direction)i));
419 if((cneighbor>0) && (cneighbor != lab))
421 lab = SRGWatershedLabel;
429 if((srgType & KeepContours) == 0 || lab > 0)
432 stats[*irx](as(isx));
436 for(
int i=0; i<directionCount; i++)
438 if(*(irx + Neighborhood::diff((Direction)i)) == 0)
440 CostType cost = stats[lab].cost(as(isx, Neighborhood::diff((Direction)i)));
443 allocator.create(pos+Neighborhood::diff((Direction)i), nearest, cost, count++, lab);
444 pheap.push(new_voxel);
451 while(pheap.size() != 0)
453 allocator.dismiss(pheap.top());
459 destul, ad, detail::UnlabelWatersheds());
462 template <
class SrcImageIterator,
class Diff_type,
class SrcAccessor,
463 class SeedImageIterator,
class SeedAccessor,
464 class DestImageIterator,
class DestAccessor,
465 class RegionStatisticsArray,
class Neighborhood >
468 SeedImageIterator seedsul, SeedAccessor aseeds,
469 DestImageIterator destul, DestAccessor ad,
470 RegionStatisticsArray & stats,
SRGType srgType, Neighborhood n)
476 template <
class SrcImageIterator,
class Diff_type,
class SrcAccessor,
477 class SeedImageIterator,
class SeedAccessor,
478 class DestImageIterator,
class DestAccessor,
479 class RegionStatisticsArray >
482 SeedImageIterator seedsul, SeedAccessor aseeds,
483 DestImageIterator destul, DestAccessor ad,
484 RegionStatisticsArray & stats,
SRGType srgType)
490 template <
class SrcImageIterator,
class Diff_type,
class SrcAccessor,
491 class SeedImageIterator,
class SeedAccessor,
492 class DestImageIterator,
class DestAccessor,
493 class RegionStatisticsArray >
496 SeedImageIterator seedsul, SeedAccessor aseeds,
497 DestImageIterator destul, DestAccessor ad,
498 RegionStatisticsArray & stats)
501 stats, CompleteGrow);
504 template <
class SrcImageIterator,
class Shape,
class SrcAccessor,
505 class SeedImageIterator,
class SeedAccessor,
506 class DestImageIterator,
class DestAccessor,
507 class RegionStatisticsArray,
class Neighborhood>
510 pair<SeedImageIterator, SeedAccessor> img3,
511 pair<DestImageIterator, DestAccessor> img4,
512 RegionStatisticsArray & stats,
513 SRGType srgType, Neighborhood n,
double max_cost)
516 img3.first, img3.second,
517 img4.first, img4.second,
518 stats, srgType, n, max_cost);
521 template <
class SrcImageIterator,
class Shape,
class SrcAccessor,
522 class SeedImageIterator,
class SeedAccessor,
523 class DestImageIterator,
class DestAccessor,
524 class RegionStatisticsArray,
class Neighborhood>
527 pair<SeedImageIterator, SeedAccessor> img3,
528 pair<DestImageIterator, DestAccessor> img4,
529 RegionStatisticsArray & stats,
530 SRGType srgType, Neighborhood n)
533 img3.first, img3.second,
534 img4.first, img4.second,
538 template <
class SrcImageIterator,
class Shape,
class SrcAccessor,
539 class SeedImageIterator,
class SeedAccessor,
540 class DestImageIterator,
class DestAccessor,
541 class RegionStatisticsArray>
544 pair<SeedImageIterator, SeedAccessor> img3,
545 pair<DestImageIterator, DestAccessor> img4,
546 RegionStatisticsArray & stats,
SRGType srgType)
549 img3.first, img3.second,
550 img4.first, img4.second,
554 template <
class SrcImageIterator,
class Shape,
class SrcAccessor,
555 class SeedImageIterator,
class SeedAccessor,
556 class DestImageIterator,
class DestAccessor,
557 class RegionStatisticsArray>
560 pair<SeedImageIterator, SeedAccessor> img3,
561 pair<DestImageIterator, DestAccessor> img4,
562 RegionStatisticsArray & stats)
565 img3.first, img3.second,
566 img4.first, img4.second,
572 #endif // VIGRA_SEEDEDREGIONGROWING_HXX