36 #ifndef VIGRA_SEEDEDREGIONGROWING_HXX 
   37 #define VIGRA_SEEDEDREGIONGROWING_HXX 
   43 #include "stdimage.hxx" 
   44 #include "stdimagefunctions.hxx" 
   45 #include "pixelneighborhood.hxx" 
   46 #include "bucket_queue.hxx" 
   47 #include "multi_shape.hxx" 
   57     Point2D location_, nearest_;
 
   64     : location_(0,0), nearest_(0,0), cost_(0), count_(0), label_(0)
 
   67     SeedRgPixel(Point2D 
const & location, Point2D 
const & nearest,
 
   68                 COST 
const & cost, 
int const & count, 
int const & label)
 
   69     : location_(location), nearest_(nearest),
 
   70       cost_(cost), count_(count), label_(label)
 
   72         int dx = location_.x - nearest_.x;
 
   73         int dy = location_.y - nearest_.y;
 
   74         dist_ = dx * dx + dy * dy;
 
   77     void set(Point2D 
const & location, Point2D 
const & nearest,
 
   78              COST 
const & cost, 
int const & count, 
int const & label)
 
   86         int dx = location_.x - nearest_.x;
 
   87         int dy = location_.y - nearest_.y;
 
   88         dist_ = dx * dx + dy * dy;
 
   94         bool operator()(SeedRgPixel 
const & l,
 
   95                         SeedRgPixel 
const & r)
 const 
   97             if(r.cost_ == l.cost_)
 
   99                 if(r.dist_ == l.dist_) 
return r.count_ < l.count_;
 
  101                 return r.dist_ < l.dist_;
 
  104             return r.cost_ < l.cost_;
 
  106         bool operator()(SeedRgPixel 
const * l,
 
  107                         SeedRgPixel 
const * r)
 const 
  109             if(r->cost_ == l->cost_)
 
  111                 if(r->dist_ == l->dist_) 
return r->count_ < l->count_;
 
  113                 return r->dist_ < l->dist_;
 
  116             return r->cost_ < l->cost_;
 
  124             while(!freelist_.empty())
 
  126                 delete freelist_.top();
 
  132         create(Point2D 
const & location, Point2D 
const & nearest,
 
  133                COST 
const & cost, 
int const & count, 
int const & label)
 
  135             if(!freelist_.empty())
 
  137                 SeedRgPixel * res = freelist_.top();
 
  139                 res->set(location, nearest, cost, count, label);
 
  143             return new SeedRgPixel(location, nearest, cost, count, label);
 
  146         void dismiss(SeedRgPixel * p)
 
  151         std::stack<SeedRgPixel<COST> *> freelist_;
 
  155 struct UnlabelWatersheds
 
  157     int operator()(
int label)
 const 
  159         return label < 0 ? 0 : label;
 
  180     SRGWatershedLabel = -1
 
  414 template <
class SrcIterator, 
class SrcAccessor,
 
  415           class SeedImageIterator, 
class SeedAccessor,
 
  416           class DestIterator, 
class DestAccessor,
 
  417           class RegionStatisticsArray, 
class Neighborhood>
 
  418 typename SeedAccessor::value_type
 
  420                     SrcIterator srclr, SrcAccessor as,
 
  421                     SeedImageIterator seedsul, SeedAccessor aseeds,
 
  422                     DestIterator destul, DestAccessor ad,
 
  423                     RegionStatisticsArray & stats,
 
  428     int w = srclr.x - srcul.x;
 
  429     int h = srclr.y - srcul.y;
 
  432     SrcIterator isy = srcul, isx = srcul;  
 
  434     typedef typename SeedAccessor::value_type LabelType;
 
  435     typedef typename RegionStatisticsArray::value_type RegionStatistics;
 
  436     typedef typename RegionStatistics::cost_type CostType;
 
  437     typedef detail::SeedRgPixel<CostType> Pixel;
 
  439     typename Pixel::Allocator allocator;
 
  441     typedef std::priority_queue<Pixel *, std::vector<Pixel *>,
 
  442                                 typename Pixel::Compare>  SeedRgPixelHeap;
 
  450     copyImage(seedsul, seedsul+Diff2D(w,h), aseeds, ir, regions.accessor());
 
  454     SeedRgPixelHeap pheap;
 
  455     int cneighbor, maxRegionLabel = 0;
 
  457     typedef typename Neighborhood::Direction Direction;
 
  458     int directionCount = Neighborhood::DirectionCount;
 
  461     for(isy=srcul, iry=ir, pos.y=0; pos.y<h;
 
  462         ++pos.y, ++isy.y, ++iry.y)
 
  464         for(isx=isy, irx=iry, pos.x=0; pos.x<w;
 
  465             ++pos.x, ++isx.x, ++irx.x)
 
  470                 for(
int i=0; i<directionCount; i++)
 
  473                     cneighbor = irx[Neighborhood::diff((Direction)i)];
 
  476                         CostType cost = stats[cneighbor].cost(as(isx));
 
  479                             allocator.create(pos, pos+Neighborhood::diff((Direction)i), cost, count++, cneighbor);
 
  486                 vigra_precondition((LabelType)*irx <= (LabelType)stats.maxRegionLabel(),
 
  487                     "seededRegionGrowing(): Largest label exceeds size of RegionStatisticsArray.");
 
  488                 if(maxRegionLabel < *irx)
 
  489                     maxRegionLabel = *irx;
 
  495     while(pheap.size() != 0)
 
  497         Pixel * pixel = pheap.top();
 
  500         Point2D pos = pixel->location_;
 
  501         Point2D nearest = pixel->nearest_;
 
  502         int lab = pixel->label_;
 
  503         CostType cost = pixel->cost_;
 
  505         allocator.dismiss(pixel);
 
  507         if((srgType & StopAtThreshold) != 0 && cost > max_cost)
 
  516         if((srgType & KeepContours) != 0)
 
  518             for(
int i=0; i<directionCount; i++)
 
  520                 cneighbor = irx[Neighborhood::diff((Direction)i)];
 
  521                 if((cneighbor>0) && (cneighbor != lab))
 
  523                     lab = SRGWatershedLabel;
 
  531         if((srgType & KeepContours) == 0 || lab > 0)
 
  534             stats[*irx](as(isx));
 
  538             for(
int i=0; i<directionCount; i++)
 
  540                 if(irx[Neighborhood::diff((Direction)i)] == 0)
 
  542                     CostType cost = stats[lab].cost(as(isx, Neighborhood::diff((Direction)i)));
 
  545                         allocator.create(pos+Neighborhood::diff((Direction)i), nearest, cost, count++, lab);
 
  546                     pheap.push(new_pixel);
 
  553     while(pheap.size() != 0)
 
  555         allocator.dismiss(pheap.top());
 
  560     transformImage(ir, ir+Point2D(w,h), regions.accessor(), destul, ad,
 
  561                    detail::UnlabelWatersheds());
 
  563     return (LabelType)maxRegionLabel;
 
  566 template <
class SrcIterator, 
class SrcAccessor,
 
  567           class SeedImageIterator, 
class SeedAccessor,
 
  568           class DestIterator, 
class DestAccessor,
 
  569           class RegionStatisticsArray, 
class Neighborhood>
 
  570 inline typename SeedAccessor::value_type
 
  572                     SrcIterator srclr, SrcAccessor as,
 
  573                     SeedImageIterator seedsul, SeedAccessor aseeds,
 
  574                     DestIterator destul, DestAccessor ad,
 
  575                     RegionStatisticsArray & stats,
 
  582                                 stats, srgType, n, NumericTraits<double>::max());
 
  587 template <
class SrcIterator, 
class SrcAccessor,
 
  588           class SeedImageIterator, 
class SeedAccessor,
 
  589           class DestIterator, 
class DestAccessor,
 
  590           class RegionStatisticsArray>
 
  591 inline typename SeedAccessor::value_type
 
  593                     SrcIterator srclr, SrcAccessor as,
 
  594                     SeedImageIterator seedsul, SeedAccessor aseeds,
 
  595                     DestIterator destul, DestAccessor ad,
 
  596                     RegionStatisticsArray & stats,
 
  605 template <
class SrcIterator, 
class SrcAccessor,
 
  606           class SeedImageIterator, 
class SeedAccessor,
 
  607           class DestIterator, 
class DestAccessor,
 
  608           class RegionStatisticsArray>
 
  609 inline typename SeedAccessor::value_type
 
  611                     SrcIterator srclr, SrcAccessor as,
 
  612                     SeedImageIterator seedsul, SeedAccessor aseeds,
 
  613                     DestIterator destul, DestAccessor ad,
 
  614                     RegionStatisticsArray & stats)
 
  619                                 stats, CompleteGrow);
 
  622 template <
class SrcIterator, 
class SrcAccessor,
 
  623           class SeedImageIterator, 
class SeedAccessor,
 
  624           class DestIterator, 
class DestAccessor,
 
  625           class RegionStatisticsArray, 
class Neighborhood>
 
  626 inline typename SeedAccessor::value_type
 
  628                     pair<SeedImageIterator, SeedAccessor> img3,
 
  629                     pair<DestIterator, DestAccessor> img4,
 
  630                     RegionStatisticsArray & stats,
 
  633                     double max_cost = NumericTraits<double>::max())
 
  636                                 img3.first, img3.second,
 
  637                                 img4.first, img4.second,
 
  638                                 stats, srgType, n, max_cost);
 
  641 template <
class SrcIterator, 
class SrcAccessor,
 
  642           class SeedImageIterator, 
class SeedAccessor,
 
  643           class DestIterator, 
class DestAccessor,
 
  644           class RegionStatisticsArray>
 
  645 inline typename SeedAccessor::value_type
 
  647                     pair<SeedImageIterator, SeedAccessor> img3,
 
  648                     pair<DestIterator, DestAccessor> img4,
 
  649                     RegionStatisticsArray & stats,
 
  653                                 img3.first, img3.second,
 
  654                                 img4.first, img4.second,
 
  658 template <
class SrcIterator, 
class SrcAccessor,
 
  659           class SeedImageIterator, 
class SeedAccessor,
 
  660           class DestIterator, 
class DestAccessor,
 
  661           class RegionStatisticsArray>
 
  662 inline typename SeedAccessor::value_type
 
  664                     pair<SeedImageIterator, SeedAccessor> img3,
 
  665                     pair<DestIterator, DestAccessor> img4,
 
  666                     RegionStatisticsArray & stats)
 
  669                             img3.first, img3.second,
 
  670                             img4.first, img4.second,
 
  671                             stats, CompleteGrow);
 
  674 template <
class T1, 
class S1,
 
  677           class RegionStatisticsArray, 
class Neighborhood>
 
  680                     MultiArrayView<2, TS, AS> 
const & img3,
 
  681                     MultiArrayView<2, T2, S2> img4,
 
  682                     RegionStatisticsArray & stats,
 
  685                     double max_cost = NumericTraits<double>::max())
 
  687     vigra_precondition(img1.shape() == img3.shape(),
 
  688         "seededRegionGrowing(): shape mismatch between input and output.");
 
  692                                stats, srgType, n, max_cost);
 
  695 template <
class T1, 
class S1,
 
  698           class RegionStatisticsArray>
 
  701                     MultiArrayView<2, TS, AS> 
const & img3,
 
  702                     MultiArrayView<2, T2, S2> img4,
 
  703                     RegionStatisticsArray & stats,
 
  706     vigra_precondition(img1.shape() == img3.shape(),
 
  707         "seededRegionGrowing(): shape mismatch between input and output.");
 
  714 template <
class T1, 
class S1,
 
  717           class RegionStatisticsArray>
 
  720                     MultiArrayView<2, TS, AS> 
const & img3,
 
  721                     MultiArrayView<2, T2, S2> img4,
 
  722                     RegionStatisticsArray & stats)
 
  724     vigra_precondition(img1.shape() == img3.shape(),
 
  725         "seededRegionGrowing(): shape mismatch between input and output.");
 
  729                                stats, CompleteGrow);
 
  738 template <
class SrcIterator, 
class SrcAccessor,
 
  739           class DestIterator, 
class DestAccessor,
 
  740           class RegionStatisticsArray, 
class Neighborhood>
 
  741 typename DestAccessor::value_type
 
  742 fastSeededRegionGrowing(SrcIterator srcul, SrcIterator srclr, SrcAccessor as,
 
  743                         DestIterator destul, DestAccessor ad,
 
  744                         RegionStatisticsArray & stats,
 
  748                         std::ptrdiff_t bucket_count = 256)
 
  750     typedef typename DestAccessor::value_type LabelType;
 
  752     vigra_precondition((srgType & KeepContours) == 0,
 
  753        "fastSeededRegionGrowing(): the turbo algorithm doesn't support 'KeepContours', sorry.");
 
  755     int w = srclr.x - srcul.x;
 
  756     int h = srclr.y - srcul.y;
 
  758     SrcIterator isy = srcul, isx = srcul;  
 
  759     DestIterator idy = destul, idx = destul;  
 
  761     BucketQueue<Point2D, true> pqueue(bucket_count);
 
  762     LabelType maxRegionLabel = 0;
 
  765     for(isy=srcul, idy = destul, pos.y=0; pos.y<h; ++pos.y, ++isy.y, ++idy.y)
 
  767         for(isx=isy, idx=idy, pos.x=0; pos.x<w; ++pos.x, ++isx.x, ++idx.x)
 
  769             LabelType label = ad(idx);
 
  772                 vigra_precondition(label <= stats.maxRegionLabel(),
 
  773                     "fastSeededRegionGrowing(): Largest label exceeds size of RegionStatisticsArray.");
 
  775                 if(maxRegionLabel < label)
 
  776                     maxRegionLabel = label;
 
  781                     NeighborhoodCirculator<DestIterator, Neighborhood> c(idx), cend(c);
 
  786                             std::ptrdiff_t priority = (std::ptrdiff_t)stats[label].cost(as(isx));
 
  787                             pqueue.push(pos, priority);
 
  795                     RestrictedNeighborhoodCirculator<DestIterator, Neighborhood>
 
  796                                                             c(idx, atBorder), cend(c);
 
  801                             std::ptrdiff_t priority = (std::ptrdiff_t)stats[label].cost(as(isx));
 
  802                             pqueue.push(pos, priority);
 
  813     while(!pqueue.empty())
 
  815         Point2D pos = pqueue.top();
 
  816         std::ptrdiff_t cost = pqueue.topPriority();
 
  819         if((srgType & StopAtThreshold) != 0 && cost > max_cost)
 
  825         std::ptrdiff_t label = ad(idx);
 
  830             NeighborhoodCirculator<DestIterator, Neighborhood> c(idx), cend(c);
 
  834                 std::ptrdiff_t nlabel = ad(c);
 
  837                     ad.set(label, idx, c.diff());
 
  838                     std::ptrdiff_t priority =
 
  839                            std::max((std::ptrdiff_t)stats[label].cost(as(isx, c.diff())), cost);
 
  840                     pqueue.push(pos+c.diff(), priority);
 
  847             RestrictedNeighborhoodCirculator<DestIterator, Neighborhood>
 
  848                                                     c(idx, atBorder), cend(c);
 
  851                 std::ptrdiff_t nlabel = ad(c);
 
  854                     ad.set(label, idx, c.diff());
 
  855                     std::ptrdiff_t priority =
 
  856                            std::max((std::ptrdiff_t)stats[label].cost(as(isx, c.diff())), cost);
 
  857                     pqueue.push(pos+c.diff(), priority);
 
  864     return maxRegionLabel;
 
  867 template <
class SrcIterator, 
class SrcAccessor,
 
  868           class DestIterator, 
class DestAccessor,
 
  869           class RegionStatisticsArray, 
class Neighborhood>
 
  870 inline typename DestAccessor::value_type
 
  871 fastSeededRegionGrowing(SrcIterator srcul, SrcIterator srclr, SrcAccessor as,
 
  872                         DestIterator destul, DestAccessor ad,
 
  873                         RegionStatisticsArray & stats,
 
  877     return fastSeededRegionGrowing(srcul, srclr, as,
 
  879                                     stats, srgType, n, NumericTraits<double>::max(), 256);
 
  882 template <
class SrcIterator, 
class SrcAccessor,
 
  883           class DestIterator, 
class DestAccessor,
 
  884           class RegionStatisticsArray>
 
  885 inline typename DestAccessor::value_type
 
  886 fastSeededRegionGrowing(SrcIterator srcul, SrcIterator srclr, SrcAccessor as,
 
  887                         DestIterator destul, DestAccessor ad,
 
  888                         RegionStatisticsArray & stats,
 
  891     return fastSeededRegionGrowing(srcul, srclr, as,
 
  896 template <
class SrcIterator, 
class SrcAccessor,
 
  897           class DestIterator, 
class DestAccessor,
 
  898           class RegionStatisticsArray>
 
  899 inline typename DestAccessor::value_type
 
  900 fastSeededRegionGrowing(SrcIterator srcul, SrcIterator srclr, SrcAccessor as,
 
  901                         DestIterator destul, DestAccessor ad,
 
  902                         RegionStatisticsArray & stats)
 
  904     return fastSeededRegionGrowing(srcul, srclr, as,
 
  906                                     stats, CompleteGrow);
 
  909 template <
class SrcIterator, 
class SrcAccessor,
 
  910           class DestIterator, 
class DestAccessor,
 
  911           class RegionStatisticsArray, 
class Neighborhood>
 
  912 inline typename DestAccessor::value_type
 
  913 fastSeededRegionGrowing(triple<SrcIterator, SrcIterator, SrcAccessor> src,
 
  914                         pair<DestIterator, DestAccessor> dest,
 
  915                         RegionStatisticsArray & stats,
 
  919                         std::ptrdiff_t bucket_count = 256)
 
  921     return fastSeededRegionGrowing(src.first, src.second, src.third,
 
  922                                    dest.first, dest.second,
 
  923                                    stats, srgType, n, max_cost, bucket_count);
 
  926 template <
class T1, 
class S1,
 
  928           class RegionStatisticsArray, 
class Neighborhood>
 
  930 fastSeededRegionGrowing(MultiArrayView<2, T1, S1> 
const & src,
 
  931                         MultiArrayView<2, T2, S2> dest,
 
  932                         RegionStatisticsArray & stats,
 
  936                         std::ptrdiff_t bucket_count = 256)
 
  938     vigra_precondition(src.shape() == dest.shape(),
 
  939         "fastSeededRegionGrowing(): shape mismatch between input and output.");
 
  940     return fastSeededRegionGrowing(srcImageRange(src),
 
  942                                    stats, srgType, n, max_cost, bucket_count);
 
  961 template <
class Value>
 
  998 #endif // VIGRA_SEEDEDREGIONGROWING_HXX 
Value result_type
Definition: seededregiongrowing.hxx:972
SRGType
Definition: seededregiongrowing.hxx:176
AtImageBorder
Encode whether a point is near the image border. 
Definition: pixelneighborhood.hxx:68
AtImageBorder isAtImageBorder(int x, int y, int width, int height)
Find out whether a point is at the image border. 
Definition: pixelneighborhood.hxx:111
Statistics functor to be used for seeded region growing. 
Definition: seededregiongrowing.hxx:962
Value cost_type
Definition: seededregiongrowing.hxx:980
BasicImageIterator< PIXELTYPE, PIXELTYPE ** > Iterator
Definition: basicimage.hxx:532
void operator()(argument_type const &) const 
Definition: seededregiongrowing.hxx:984
Value value_type
Definition: seededregiongrowing.hxx:976
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays. 
void copyImage(...)
Copy source image into destination image. 
void seededRegionGrowing(...)
Region Segmentation by means of Seeded Region Growing. 
Value argument_type
Definition: seededregiongrowing.hxx:967
FourNeighborhood::NeighborCode FourNeighborCode
Definition: pixelneighborhood.hxx:379
  
Definition: pixelneighborhood.hxx:70
void initImageBorder(...)
Write value to the specified border pixels in the image. 
cost_type const & cost(argument_type const &v) const 
Definition: seededregiongrowing.hxx:988
BasicImage< Int32 > IImage
Definition: stdimage.hxx:116