[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
vigra/seededregiongrowing.hxx | ![]() |
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2010 by Ullrich Koethe, Hans Meine */ 00004 /* */ 00005 /* This file is part of the VIGRA computer vision library. */ 00006 /* The VIGRA Website is */ 00007 /* http://hci.iwr.uni-heidelberg.de/vigra/ */ 00008 /* Please direct questions, bug reports, and contributions to */ 00009 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00010 /* vigra@informatik.uni-hamburg.de */ 00011 /* */ 00012 /* Permission is hereby granted, free of charge, to any person */ 00013 /* obtaining a copy of this software and associated documentation */ 00014 /* files (the "Software"), to deal in the Software without */ 00015 /* restriction, including without limitation the rights to use, */ 00016 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00017 /* sell copies of the Software, and to permit persons to whom the */ 00018 /* Software is furnished to do so, subject to the following */ 00019 /* conditions: */ 00020 /* */ 00021 /* The above copyright notice and this permission notice shall be */ 00022 /* included in all copies or substantial portions of the */ 00023 /* Software. */ 00024 /* */ 00025 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00026 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00027 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00028 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00029 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00030 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00031 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00032 /* OTHER DEALINGS IN THE SOFTWARE. */ 00033 /* */ 00034 /************************************************************************/ 00035 00036 #ifndef VIGRA_SEEDEDREGIONGROWING_HXX 00037 #define VIGRA_SEEDEDREGIONGROWING_HXX 00038 00039 #include <vector> 00040 #include <stack> 00041 #include <queue> 00042 #include "utilities.hxx" 00043 #include "stdimage.hxx" 00044 #include "stdimagefunctions.hxx" 00045 #include "pixelneighborhood.hxx" 00046 00047 namespace vigra { 00048 00049 namespace detail { 00050 00051 template <class COST> 00052 class SeedRgPixel 00053 { 00054 public: 00055 Point2D location_, nearest_; 00056 COST cost_; 00057 int count_; 00058 int label_; 00059 int dist_; 00060 00061 SeedRgPixel() 00062 : location_(0,0), nearest_(0,0), cost_(0), count_(0), label_(0) 00063 {} 00064 00065 SeedRgPixel(Point2D const & location, Point2D const & nearest, 00066 COST const & cost, int const & count, int const & label) 00067 : location_(location), nearest_(nearest), 00068 cost_(cost), count_(count), label_(label) 00069 { 00070 int dx = location_.x - nearest_.x; 00071 int dy = location_.y - nearest_.y; 00072 dist_ = dx * dx + dy * dy; 00073 } 00074 00075 void set(Point2D const & location, Point2D const & nearest, 00076 COST const & cost, int const & count, int const & label) 00077 { 00078 location_ = location; 00079 nearest_ = nearest; 00080 cost_ = cost; 00081 count_ = count; 00082 label_ = label; 00083 00084 int dx = location_.x - nearest_.x; 00085 int dy = location_.y - nearest_.y; 00086 dist_ = dx * dx + dy * dy; 00087 } 00088 00089 struct Compare 00090 { 00091 // must implement > since priority_queue looks for largest element 00092 bool operator()(SeedRgPixel const & l, 00093 SeedRgPixel const & r) const 00094 { 00095 if(r.cost_ == l.cost_) 00096 { 00097 if(r.dist_ == l.dist_) return r.count_ < l.count_; 00098 00099 return r.dist_ < l.dist_; 00100 } 00101 00102 return r.cost_ < l.cost_; 00103 } 00104 bool operator()(SeedRgPixel const * l, 00105 SeedRgPixel const * r) const 00106 { 00107 if(r->cost_ == l->cost_) 00108 { 00109 if(r->dist_ == l->dist_) return r->count_ < l->count_; 00110 00111 return r->dist_ < l->dist_; 00112 } 00113 00114 return r->cost_ < l->cost_; 00115 } 00116 }; 00117 00118 struct Allocator 00119 { 00120 ~Allocator() 00121 { 00122 while(!freelist_.empty()) 00123 { 00124 delete freelist_.top(); 00125 freelist_.pop(); 00126 } 00127 } 00128 00129 SeedRgPixel * 00130 create(Point2D const & location, Point2D const & nearest, 00131 COST const & cost, int const & count, int const & label) 00132 { 00133 if(!freelist_.empty()) 00134 { 00135 SeedRgPixel * res = freelist_.top(); 00136 freelist_.pop(); 00137 res->set(location, nearest, cost, count, label); 00138 return res; 00139 } 00140 00141 return new SeedRgPixel(location, nearest, cost, count, label); 00142 } 00143 00144 void dismiss(SeedRgPixel * p) 00145 { 00146 freelist_.push(p); 00147 } 00148 00149 std::stack<SeedRgPixel<COST> *> freelist_; 00150 }; 00151 }; 00152 00153 struct UnlabelWatersheds 00154 { 00155 int operator()(int label) const 00156 { 00157 return label < 0 ? 0 : label; 00158 } 00159 }; 00160 00161 } // namespace detail 00162 00163 enum SRGType { CompleteGrow = 0, KeepContours = 1, StopAtThreshold = 2, SRGWatershedLabel = -1 }; 00164 00165 /** \addtogroup SeededRegionGrowing Region Segmentation Algorithms 00166 Region growing, watersheds, and voronoi tesselation 00167 */ 00168 //@{ 00169 00170 /********************************************************/ 00171 /* */ 00172 /* seededRegionGrowing */ 00173 /* */ 00174 /********************************************************/ 00175 00176 /** \brief Region Segmentation by means of Seeded Region Growing. 00177 00178 This algorithm implements seeded region growing as described in 00179 00180 R. Adams, L. Bischof: "<em> Seeded Region Growing</em>", IEEE Trans. on Pattern 00181 Analysis and Maschine Intelligence, vol 16, no 6, 1994, and 00182 00183 Ullrich Köthe: 00184 <em><a href="http://hci.iwr.uni-heidelberg.de/people/ukoethe/papers/index.php#cite_primary_segmentation">Primary Image Segmentation</a></em>, 00185 in: G. Sagerer, S. 00186 Posch, F. Kummert (eds.): Mustererkennung 1995, Proc. 17. DAGM-Symposium, 00187 Springer 1995 00188 00189 The seed image is a partly segmented image which contains uniquely 00190 labeled regions (the seeds) and unlabeled pixels (the candidates, label 0). 00191 Seed regions can be as large as you wish and as small as one pixel. If 00192 there are no candidates, the algorithm will simply copy the seed image 00193 into the output image. Otherwise it will aggregate the candidates into 00194 the existing regions so that a cost function is minimized. 00195 Candidates are taken from the neighborhood of the already assigned pixels, 00196 where the type of neighborhood is determined by parameter <tt>neighborhood</tt> 00197 which can take the values <tt>FourNeighborCode()</tt> (the default) 00198 or <tt>EightNeighborCode()</tt>. The algorithm basically works as follows 00199 (illustrated for 4-neighborhood, but 8-neighborhood works in the same way): 00200 00201 <ol> 00202 00203 <li> Find all candidate pixels that are 4-adjacent to a seed region. 00204 Calculate the cost for aggregating each candidate into its adajacent region 00205 and put the candidates into a priority queue. 00206 00207 <li> While( priority queue is not empty and termination criterion is not fulfilled) 00208 00209 <ol> 00210 00211 <li> Take the candidate with least cost from the queue. If it has not 00212 already been merged, merge it with it's adjacent region. 00213 00214 <li> Put all candidates that are 4-adjacent to the pixel just processed 00215 into the priority queue. 00216 00217 </ol> 00218 00219 </ol> 00220 00221 <tt>SRGType</tt> can take the following values: 00222 00223 <DL> 00224 <DT><tt>CompleteGrow</tt> <DD> produce a complete tesselation of the volume (default). 00225 <DT><tt>KeepContours</tt> <DD> keep a 1-voxel wide unlabeled contour between all regions. 00226 <DT><tt>StopAtThreshold</tt> <DD> stop when the boundary indicator values exceed the 00227 threshold given by parameter <tt>max_cost</tt>. 00228 <DT><tt>KeepContours | StopAtThreshold</tt> <DD> keep 1-voxel wide contour and stop at given <tt>max_cost</tt>. 00229 </DL> 00230 00231 The cost is determined jointly by the source image and the 00232 region statistics functor. The source image contains feature values for each 00233 pixel which will be used by the region statistics functor to calculate and 00234 update statistics for each region and to calculate the cost for each 00235 candidate. The <TT>RegionStatisticsArray</TT> must be compatible to the 00236 \ref ArrayOfRegionStatistics functor and contains an <em> array</em> of 00237 statistics objects for each region. The indices must correspond to the 00238 labels of the seed regions. The statistics for the initial regions must have 00239 been calculated prior to calling <TT>seededRegionGrowing()</TT> (for example by 00240 means of \ref inspectTwoImagesIf()). 00241 00242 For each candidate 00243 <TT>x</TT> that is adjacent to region <TT>i</TT>, the algorithm will call 00244 <TT>stats[i].cost(as(x))</TT> to get the cost (where <TT>x</TT> is a <TT>SrcImageIterator</TT> 00245 and <TT>as</TT> is 00246 the SrcAccessor). When a candidate has been merged with a region, the 00247 statistics are updated by calling <TT>stats[i].operator()(as(x))</TT>. Since 00248 the <TT>RegionStatisticsArray</TT> is passed by reference, this will overwrite 00249 the original statistics. 00250 00251 If a candidate could be merged into more than one regions with identical 00252 cost, the algorithm will favour the nearest region. If <tt>StopAtThreshold</tt> is active, 00253 and the cost of the current candidate at any point in the algorithm exceeds the optional 00254 <tt>max_cost</tt> value (which defaults to <tt>NumericTraits<double>::max()</tt>), 00255 region growing is aborted, and all voxels not yet assigned to a region remain unlabeled. 00256 00257 In some cases, the cost only depends on the feature value of the current 00258 pixel. Then the update operation will simply be a no-op, and the <TT>cost()</TT> 00259 function returns its argument. This behavior is implemented by the 00260 \ref SeedRgDirectValueFunctor. With <tt>SRGType == KeepContours</tt>, 00261 this is equivalent to the watershed algorithm. 00262 00263 <b> Declarations:</b> 00264 00265 pass arguments explicitly: 00266 \code 00267 namespace vigra { 00268 template <class SrcImageIterator, class SrcAccessor, 00269 class SeedImageIterator, class SeedAccessor, 00270 class DestImageIterator, class DestAccessor, 00271 class RegionStatisticsArray, class Neighborhood> 00272 void 00273 seededRegionGrowing(SrcImageIterator srcul, SrcImageIterator srclr, SrcAccessor as, 00274 SeedImageIterator seedsul, SeedAccessor aseeds, 00275 DestImageIterator destul, DestAccessor ad, 00276 RegionStatisticsArray & stats, 00277 SRGType srgType = CompleteGrow, 00278 Neighborhood neighborhood = FourNeighborCode(), 00279 double max_cost = NumericTraits<double>::max()); 00280 } 00281 \endcode 00282 00283 use argument objects in conjunction with \ref ArgumentObjectFactories : 00284 \code 00285 namespace vigra { 00286 template <class SrcImageIterator, class SrcAccessor, 00287 class SeedImageIterator, class SeedAccessor, 00288 class DestImageIterator, class DestAccessor, 00289 class RegionStatisticsArray, class Neighborhood> 00290 void 00291 seededRegionGrowing(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00292 pair<SeedImageIterator, SeedAccessor> seeds, 00293 pair<DestImageIterator, DestAccessor> dest, 00294 RegionStatisticsArray & stats, 00295 SRGType srgType = CompleteGrow, 00296 Neighborhood neighborhood = FourNeighborCode(), 00297 double max_cost = NumericTraits<double>::max()); 00298 } 00299 \endcode 00300 00301 <b> Usage:</b> 00302 00303 <b>\#include</b> <<a href="seededregiongrowing_8hxx-source.html">vigra/seededregiongrowing.hxx</a>><br> 00304 Namespace: vigra 00305 00306 Example: implementation of the voronoi tesselation 00307 00308 \code 00309 vigra::BImage points(w,h); 00310 vigra::FImage dist(x,y); 00311 00312 // empty edge image 00313 points = 0; 00314 dist = 0; 00315 00316 int max_region_label = 100; 00317 00318 // throw in some random points: 00319 for(int i = 1; i <= max_region_label; ++i) 00320 points(w * rand() / RAND_MAX , h * rand() / RAND_MAX) = i; 00321 00322 // calculate Euclidean distance transform 00323 vigra::distanceTransform(srcImageRange(points), destImage(dist), 2); 00324 00325 // init statistics functor 00326 vigra::ArrayOfRegionStatistics<vigra::SeedRgDirectValueFunctor<float> > 00327 stats(max_region_label); 00328 00329 // find voronoi region of each point 00330 vigra:: seededRegionGrowing(srcImageRange(dist), srcImage(points), 00331 destImage(points), stats); 00332 \endcode 00333 00334 <b> Required Interface:</b> 00335 00336 \code 00337 SrcImageIterator src_upperleft, src_lowerright; 00338 SeedImageIterator seed_upperleft; 00339 DestImageIterator dest_upperleft; 00340 00341 SrcAccessor src_accessor; 00342 SeedAccessor seed_accessor; 00343 DestAccessor dest_accessor; 00344 00345 RegionStatisticsArray stats; 00346 00347 // calculate costs 00348 RegionStatisticsArray::value_type::cost_type cost = 00349 stats[seed_accessor(seed_upperleft)].cost(src_accessor(src_upperleft)); 00350 00351 // compare costs 00352 cost < cost; 00353 00354 // update statistics 00355 stats[seed_accessor(seed_upperleft)](src_accessor(src_upperleft)); 00356 00357 // set result 00358 dest_accessor.set(seed_accessor(seed_upperleft), dest_upperleft); 00359 \endcode 00360 00361 Further requirements are determined by the <TT>RegionStatisticsArray</TT>. 00362 */ 00363 doxygen_overloaded_function(template <...> void seededRegionGrowing) 00364 00365 template <class SrcImageIterator, class SrcAccessor, 00366 class SeedImageIterator, class SeedAccessor, 00367 class DestImageIterator, class DestAccessor, 00368 class RegionStatisticsArray, class Neighborhood> 00369 void seededRegionGrowing(SrcImageIterator srcul, 00370 SrcImageIterator srclr, SrcAccessor as, 00371 SeedImageIterator seedsul, SeedAccessor aseeds, 00372 DestImageIterator destul, DestAccessor ad, 00373 RegionStatisticsArray & stats, 00374 SRGType srgType, 00375 Neighborhood, 00376 double max_cost) 00377 { 00378 int w = srclr.x - srcul.x; 00379 int h = srclr.y - srcul.y; 00380 int count = 0; 00381 00382 SrcImageIterator isy = srcul, isx = srcul; // iterators for the src image 00383 00384 typedef typename RegionStatisticsArray::value_type RegionStatistics; 00385 typedef typename RegionStatistics::cost_type CostType; 00386 typedef detail::SeedRgPixel<CostType> Pixel; 00387 00388 typename Pixel::Allocator allocator; 00389 00390 typedef std::priority_queue<Pixel *, std::vector<Pixel *>, 00391 typename Pixel::Compare> SeedRgPixelHeap; 00392 00393 // copy seed image in an image with border 00394 IImage regions(w+2, h+2); 00395 IImage::Iterator ir = regions.upperLeft() + Diff2D(1,1); 00396 IImage::Iterator iry, irx; 00397 00398 initImageBorder(destImageRange(regions), 1, SRGWatershedLabel); 00399 copyImage(seedsul, seedsul+Diff2D(w,h), aseeds, ir, regions.accessor()); 00400 00401 // allocate and init memory for the results 00402 00403 SeedRgPixelHeap pheap; 00404 int cneighbor; 00405 00406 typedef typename Neighborhood::Direction Direction; 00407 int directionCount = Neighborhood::DirectionCount; 00408 00409 Point2D pos(0,0); 00410 for(isy=srcul, iry=ir, pos.y=0; pos.y<h; 00411 ++pos.y, ++isy.y, ++iry.y) 00412 { 00413 for(isx=isy, irx=iry, pos.x=0; pos.x<w; 00414 ++pos.x, ++isx.x, ++irx.x) 00415 { 00416 if(*irx == 0) 00417 { 00418 // find candidate pixels for growing and fill heap 00419 for(int i=0; i<directionCount; i++) 00420 { 00421 // cneighbor = irx[dist[i]]; 00422 cneighbor = irx[Neighborhood::diff((Direction)i)]; 00423 if(cneighbor > 0) 00424 { 00425 CostType cost = stats[cneighbor].cost(as(isx)); 00426 00427 Pixel * pixel = 00428 allocator.create(pos, pos+Neighborhood::diff((Direction)i), cost, count++, cneighbor); 00429 pheap.push(pixel); 00430 } 00431 } 00432 } 00433 } 00434 } 00435 00436 // perform region growing 00437 while(pheap.size() != 0) 00438 { 00439 Pixel * pixel = pheap.top(); 00440 pheap.pop(); 00441 00442 Point2D pos = pixel->location_; 00443 Point2D nearest = pixel->nearest_; 00444 int lab = pixel->label_; 00445 CostType cost = pixel->cost_; 00446 00447 allocator.dismiss(pixel); 00448 00449 if((srgType & StopAtThreshold) != 0 && cost > max_cost) 00450 break; 00451 00452 irx = ir + pos; 00453 isx = srcul + pos; 00454 00455 if(*irx) // already labelled region / watershed? 00456 continue; 00457 00458 if((srgType & KeepContours) != 0) 00459 { 00460 for(int i=0; i<directionCount; i++) 00461 { 00462 cneighbor = irx[Neighborhood::diff((Direction)i)]; 00463 if((cneighbor>0) && (cneighbor != lab)) 00464 { 00465 lab = SRGWatershedLabel; 00466 break; 00467 } 00468 } 00469 } 00470 00471 *irx = lab; 00472 00473 if((srgType & KeepContours) == 0 || lab > 0) 00474 { 00475 // update statistics 00476 stats[*irx](as(isx)); 00477 00478 // search neighborhood 00479 // second pass: find new candidate pixels 00480 for(int i=0; i<directionCount; i++) 00481 { 00482 if(irx[Neighborhood::diff((Direction)i)] == 0) 00483 { 00484 CostType cost = stats[lab].cost(as(isx, Neighborhood::diff((Direction)i))); 00485 00486 Pixel * new_pixel = 00487 allocator.create(pos+Neighborhood::diff((Direction)i), nearest, cost, count++, lab); 00488 pheap.push(new_pixel); 00489 } 00490 } 00491 } 00492 } 00493 00494 // free temporary memory 00495 while(pheap.size() != 0) 00496 { 00497 allocator.dismiss(pheap.top()); 00498 pheap.pop(); 00499 } 00500 00501 // write result 00502 transformImage(ir, ir+Point2D(w,h), regions.accessor(), destul, ad, 00503 detail::UnlabelWatersheds()); 00504 } 00505 00506 template <class SrcImageIterator, class SrcAccessor, 00507 class SeedImageIterator, class SeedAccessor, 00508 class DestImageIterator, class DestAccessor, 00509 class RegionStatisticsArray, class Neighborhood> 00510 inline void 00511 seededRegionGrowing(SrcImageIterator srcul, 00512 SrcImageIterator srclr, SrcAccessor as, 00513 SeedImageIterator seedsul, SeedAccessor aseeds, 00514 DestImageIterator destul, DestAccessor ad, 00515 RegionStatisticsArray & stats, 00516 SRGType srgType, 00517 Neighborhood n) 00518 { 00519 seededRegionGrowing(srcul, srclr, as, 00520 seedsul, aseeds, 00521 destul, ad, 00522 stats, srgType, n, NumericTraits<double>::max()); 00523 } 00524 00525 00526 00527 template <class SrcImageIterator, class SrcAccessor, 00528 class SeedImageIterator, class SeedAccessor, 00529 class DestImageIterator, class DestAccessor, 00530 class RegionStatisticsArray> 00531 inline void 00532 seededRegionGrowing(SrcImageIterator srcul, 00533 SrcImageIterator srclr, SrcAccessor as, 00534 SeedImageIterator seedsul, SeedAccessor aseeds, 00535 DestImageIterator destul, DestAccessor ad, 00536 RegionStatisticsArray & stats, 00537 SRGType srgType) 00538 { 00539 seededRegionGrowing(srcul, srclr, as, 00540 seedsul, aseeds, 00541 destul, ad, 00542 stats, srgType, FourNeighborCode()); 00543 } 00544 00545 template <class SrcImageIterator, class SrcAccessor, 00546 class SeedImageIterator, class SeedAccessor, 00547 class DestImageIterator, class DestAccessor, 00548 class RegionStatisticsArray> 00549 inline void 00550 seededRegionGrowing(SrcImageIterator srcul, 00551 SrcImageIterator srclr, SrcAccessor as, 00552 SeedImageIterator seedsul, SeedAccessor aseeds, 00553 DestImageIterator destul, DestAccessor ad, 00554 RegionStatisticsArray & stats) 00555 { 00556 seededRegionGrowing(srcul, srclr, as, 00557 seedsul, aseeds, 00558 destul, ad, 00559 stats, CompleteGrow); 00560 } 00561 00562 template <class SrcImageIterator, class SrcAccessor, 00563 class SeedImageIterator, class SeedAccessor, 00564 class DestImageIterator, class DestAccessor, 00565 class RegionStatisticsArray, class Neighborhood> 00566 inline void 00567 seededRegionGrowing(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> img1, 00568 pair<SeedImageIterator, SeedAccessor> img3, 00569 pair<DestImageIterator, DestAccessor> img4, 00570 RegionStatisticsArray & stats, 00571 SRGType srgType, 00572 Neighborhood n, 00573 double max_cost) 00574 { 00575 seededRegionGrowing(img1.first, img1.second, img1.third, 00576 img3.first, img3.second, 00577 img4.first, img4.second, 00578 stats, srgType, n, max_cost); 00579 } 00580 00581 template <class SrcImageIterator, class SrcAccessor, 00582 class SeedImageIterator, class SeedAccessor, 00583 class DestImageIterator, class DestAccessor, 00584 class RegionStatisticsArray, class Neighborhood> 00585 inline void 00586 seededRegionGrowing(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> img1, 00587 pair<SeedImageIterator, SeedAccessor> img3, 00588 pair<DestImageIterator, DestAccessor> img4, 00589 RegionStatisticsArray & stats, 00590 SRGType srgType, 00591 Neighborhood n) 00592 { 00593 seededRegionGrowing(img1.first, img1.second, img1.third, 00594 img3.first, img3.second, 00595 img4.first, img4.second, 00596 stats, srgType, n, NumericTraits<double>::max()); 00597 } 00598 00599 template <class SrcImageIterator, class SrcAccessor, 00600 class SeedImageIterator, class SeedAccessor, 00601 class DestImageIterator, class DestAccessor, 00602 class RegionStatisticsArray> 00603 inline void 00604 seededRegionGrowing(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> img1, 00605 pair<SeedImageIterator, SeedAccessor> img3, 00606 pair<DestImageIterator, DestAccessor> img4, 00607 RegionStatisticsArray & stats, 00608 SRGType srgType) 00609 { 00610 seededRegionGrowing(img1.first, img1.second, img1.third, 00611 img3.first, img3.second, 00612 img4.first, img4.second, 00613 stats, srgType, FourNeighborCode()); 00614 } 00615 00616 template <class SrcImageIterator, class SrcAccessor, 00617 class SeedImageIterator, class SeedAccessor, 00618 class DestImageIterator, class DestAccessor, 00619 class RegionStatisticsArray> 00620 inline void 00621 seededRegionGrowing(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> img1, 00622 pair<SeedImageIterator, SeedAccessor> img3, 00623 pair<DestImageIterator, DestAccessor> img4, 00624 RegionStatisticsArray & stats) 00625 { 00626 seededRegionGrowing(img1.first, img1.second, img1.third, 00627 img3.first, img3.second, 00628 img4.first, img4.second, 00629 stats, CompleteGrow); 00630 } 00631 00632 /********************************************************/ 00633 /* */ 00634 /* SeedRgDirectValueFunctor */ 00635 /* */ 00636 /********************************************************/ 00637 00638 /** \brief Statistics functor to be used for seeded region growing. 00639 00640 This functor can be used if the cost of a candidate during 00641 \ref seededRegionGrowing() is equal to the feature value of that 00642 candidate and does not depend on properties of the region it is going to 00643 be merged with. 00644 00645 <b>\#include</b> <<a href="seededregiongrowing_8hxx-source.html">vigra/seededregiongrowing.hxx</a>><br> 00646 Namespace: vigra 00647 00648 00649 <b> Required Interface:</b> 00650 00651 no requirements 00652 */ 00653 template <class Value> 00654 class SeedRgDirectValueFunctor 00655 { 00656 public: 00657 /** the functor's argument type 00658 */ 00659 typedef Value argument_type; 00660 00661 /** the functor's result type (unused, only necessary for 00662 use of SeedRgDirectValueFunctor in \ref vigra::ArrayOfRegionStatistics 00663 */ 00664 typedef Value result_type; 00665 00666 /** \deprecated use argument_type 00667 */ 00668 typedef Value value_type; 00669 00670 /** the return type of the cost() function 00671 */ 00672 typedef Value cost_type; 00673 00674 /** Do nothing (since we need not update region statistics). 00675 */ 00676 void operator()(argument_type const &) const {} 00677 00678 /** Return argument (since cost is identical to feature value) 00679 */ 00680 cost_type const & cost(argument_type const & v) const 00681 { 00682 return v; 00683 } 00684 }; 00685 00686 //@} 00687 00688 } // namespace vigra 00689 00690 #endif // VIGRA_SEEDEDREGIONGROWING_HXX 00691
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|