[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]
![]() |
Region Segmentation Algorithms | ![]() |
---|
Classes | |
class | SeedRgDirectValueFunctor |
Statistics functor to be used for seeded region growing. More... | |
Functions | |
template<...> void | seededRegionGrowing (SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor as, SeedImageIterator seedsul, SeedAccessor aseeds, DestImageIterator destul, DestAccessor ad, RegionStatisticsArray &stats, const SRGType srgType) |
Region Segmentation by means of Seeded Region Growing. | |
template<...> unsigned int | watersheds (SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa, DestIterator upperleftd, DestAccessor da, Neighborhood neighborhood) |
Region Segmentation by means of the watershed algorithm. |
Detailed Description |
Region growing, watersheds, and voronoi tesselation
void seededRegionGrowing (...) |
Region Segmentation by means of Seeded Region Growing. This algorithm implements seeded region growing as described in R. Adams, L. Bischof: " Seeded Region Growing", IEEE Trans. on Pattern Analysis and Maschine Intelligence, vol 16, no 6, 1994, and Ullrich Köthe: "Primary Image Segmentation", in: G. Sagerer, S. Posch, F. Kummert (eds.): Mustererkennung 1995, Proc. 17. DAGM-Symposium, Springer 1995 The seed image is a partly segmented image which contains uniquely labeled regions (the seeds) and unlabeled pixels (the candidates, label 0). Seed regions can be as large as you wish and as small as one pixel. If there are no candidates, the algorithm will simply copy the seed image into the output image. Otherwise it will aggregate the candidates into the existing regions so that a cost function is minimized. This works as follows:
SRGType == CompleteGrow (the default), this algorithm will produce a complete 4-connected tesselation of the image. If SRGType == KeepContours , a one-pixel-wide border will be left between the regions. The border pixels get label 0 (zero).
The cost is determined jointly by the source image and the region statistics functor. The source image contains feature values for each pixel which will be used by the region statistics functor to calculate and update statistics for each region and to calculate the cost for each candidate. The
For each candidate If a candidate could be merged into more than one regions with identical cost, the algorithm will favour the nearest region.
In some cases, the cost only depends on the feature value of the current pixel. Then the update operation will simply be a no-op, and the Declarations: pass arguments explicitly: namespace vigra { template <class SrcImageIterator, class SrcAccessor, class SeedImageIterator, class SeedAccessor, class DestImageIterator, class DestAccessor, class RegionStatisticsArray> void seededRegionGrowing(SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor as, SeedImageIterator seedsul, SeedAccessor aseeds, DestImageIterator destul, DestAccessor ad, RegionStatisticsArray & stats, SRGType srgType = CompleteGrow); } use argument objects in conjunction with Argument Object Factories: namespace vigra { template <class SrcImageIterator, class SrcAccessor, class SeedImageIterator, class SeedAccessor, class DestImageIterator, class DestAccessor, class RegionStatisticsArray> inline void seededRegionGrowing(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> img1, pair<SeedImageIterator, SeedAccessor> img3, pair<DestImageIterator, DestAccessor> img4, RegionStatisticsArray & stats, SRGType srgType = CompleteGrow); } Usage:
#include "vigra/seededregiongrowing.hxx" Example: implementation of the voronoi tesselation
vigra::BImage points(w,h); vigra::FImage dist(x,y); // empty edge image points = 0; dist = 0; int max_region_label = 100; // throw in some random points: for(int i = 1; i <= max_region_label; ++i) points(w * rand() / RAND_MAX , h * rand() / RAND_MAX) = i; // calculate Euclidean distance transform vigra::distanceTransform(srcImageRange(points), destImage(dist), 2); // init statistics functor vigra::ArrayOfRegionStatistics<vigra::SeedRgDirectValueFunctor<float> > stats(max_region_label); // find voronoi region of each point vigra:: seededRegionGrowing(srcImageRange(dist), srcImage(points), destImage(points), stats); Required Interface:
SrcImageIterator src_upperleft, src_lowerright; SeedImageIterator seed_upperleft; DestImageIterator dest_upperleft; SrcAccessor src_accessor; SeedAccessor seed_accessor; DestAccessor dest_accessor; RegionStatisticsArray stats; // calculate costs RegionStatisticsArray::value_type::cost_type cost = stats[seed_accessor(seed_upperleft)].cost(src_accessor(src_upperleft)); // compare costs cost < cost; // update statistics stats[seed_accessor(seed_upperleft)](src_accessor(src_upperleft)); // set result dest_accessor.set(seed_accessor(seed_upperleft), dest_upperleft);
Further requirements are determined by the |
unsigned int watersheds (...) |
Region Segmentation by means of the watershed algorithm. This function implements the union-find version of the watershed algorithms as described in J. Roerdink, R. Meijster: "The watershed transform: definitions, algorithms, and parallelization stretegies", Fundamenta Informaticae, 41:187-228, 2000
The source image is a boundary indicator such as the gradient magnitude of the trace of the boundaryTensor(). Local minima of the boundary indicator are used as region seeds, and all other pixels are recursively assigned to the same region as their lowest neighbor. Pass Utilities to manage pixel neighborhoods or Utilities to manage pixel neighborhoods to determine the neighborhood where pixel values are compared. The pixel type of the input image must be Note that VIGRA provides an alternative implementaion of the watershed transform via seededRegionGrowing(). It is slower, but handles plateaus better and allows to keep a one pixel wide boundary between regions. Declarations: pass arguments explicitly: namespace vigra { template <class SrcIterator, class SrcAccessor, class DestIterator, class DestAccessor, class Neighborhood = EightNeighborCode> unsigned int watersheds(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa, DestIterator upperleftd, DestAccessor da, Neighborhood neighborhood = EightNeighborCode()) } use argument objects in conjunction with Argument Object Factories: namespace vigra { template <class SrcIterator, class SrcAccessor, class DestIterator, class DestAccessor, class Neighborhood = EightNeighborCode> unsigned int watersheds(triple<SrcIterator, SrcIterator, SrcAccessor> src, pair<DestIterator, DestAccessor> dest, Neighborhood neighborhood = EightNeighborCode()) } Usage:
#include "vigra/watersheds.hxx" Example: watersheds of the gradient magnitude.
vigra::BImage in(w,h); ... // read input data vigra::FImage gradx(x,y), grady(x,y), gradMag(x,y); gaussianGradient(srcImageRange(src), destImage(gradx), destImage(grady), 3.0); combineTwoImages(srcImageRange(gradx), srcImage(grady), destImage(gradMag), vigra::MagnitudeFunctor<float>()); // the pixel type of the destination image must be large enough to hold // numbers up to 'max_region_label' to prevent overflow vigra::IImage labeling(x,y); int max_region_label = watersheds(srcImageRange(gradMag), destImage(labeling)); Required Interface:
SrcImageIterator src_upperleft, src_lowerright; DestImageIterator dest_upperleft; SrcAccessor src_accessor; DestAccessor dest_accessor; // compare src values src_accessor(src_upperleft) <= src_accessor(src_upperleft) // set result int label; dest_accessor.set(label, dest_upperleft); |
© Ullrich Köthe (koethe@informatik.uni-hamburg.de) |
html generated using doxygen and Python
|