[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
vigra/localminmax.hxx | ![]() |
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2010 by Ullrich Koethe */ 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_LOCALMINMAX_HXX 00037 #define VIGRA_LOCALMINMAX_HXX 00038 00039 #include <vector> 00040 #include <functional> 00041 #include "utilities.hxx" 00042 #include "stdimage.hxx" 00043 #include "initimage.hxx" 00044 #include "labelimage.hxx" 00045 #include "labelvolume.hxx" 00046 #include "pixelneighborhood.hxx" 00047 #include "voxelneighborhood.hxx" 00048 00049 namespace vigra 00050 { 00051 00052 /** \addtogroup LocalMinMax Local Minima and Maxima 00053 00054 Detect local minima and maxima in a gray level image, 00055 including extremal plateaus larger than 1 pixel 00056 */ 00057 //@{ 00058 00059 namespace detail { 00060 00061 template <class SrcIterator, class SrcAccessor, 00062 class Neighborhood, 00063 class Compare> 00064 inline bool 00065 isLocalExtremum(SrcIterator is, SrcAccessor sa, Neighborhood, 00066 typename SrcAccessor::value_type threshold, 00067 Compare compare, AtImageBorder atBorder) 00068 { 00069 typename SrcAccessor::value_type v = sa(is); 00070 00071 if(!compare(v, threshold)) 00072 return false; 00073 00074 int directionCount = Neighborhood::nearBorderDirectionCount(atBorder); 00075 RestrictedNeighborhoodCirculator<SrcIterator, Neighborhood> sc(is, atBorder); 00076 for(int i = 0; i < directionCount; ++i, ++sc) 00077 { 00078 if(!compare(v, sa(sc))) 00079 return false; 00080 } 00081 return true; 00082 } 00083 00084 template <class SrcIterator, class SrcAccessor, 00085 class DestIterator, class DestAccessor, 00086 class DestValue, class Neighborhood, 00087 class Compare> 00088 void 00089 localMinMax(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 00090 DestIterator dul, DestAccessor da, 00091 DestValue marker, Neighborhood neighborhood, 00092 typename SrcAccessor::value_type threshold, 00093 Compare compare, 00094 bool allowExtremaAtBorder = false) 00095 { 00096 int w = slr.x - sul.x; 00097 int h = slr.y - sul.y; 00098 00099 int x, y; 00100 00101 if(allowExtremaAtBorder) 00102 { 00103 SrcIterator is = sul; 00104 DestIterator id = dul; 00105 00106 for(x=0; x<w; ++x, ++is.x, ++id.x) 00107 { 00108 if(isLocalExtremum(is, sa, neighborhood, threshold, compare, 00109 isAtImageBorder(x, 0, w, h))) 00110 da.set(marker, id); 00111 } 00112 00113 is = sul + Diff2D(0,1); 00114 id = dul + Diff2D(0,1); 00115 00116 for(y=1; y<h-1; ++y, ++is.y, ++id.y) 00117 { 00118 if(isLocalExtremum(is, sa, neighborhood, threshold, compare, 00119 isAtImageBorder(0, y, w, h))) 00120 da.set(marker, id); 00121 } 00122 00123 is = sul + Diff2D(w-1,1); 00124 id = dul + Diff2D(w-1,1); 00125 00126 for(y=1; y<h-1; ++y, ++is.y, ++id.y) 00127 { 00128 if(isLocalExtremum(is, sa, neighborhood, threshold, compare, 00129 isAtImageBorder(w-1, y, w, h))) 00130 da.set(marker, id); 00131 } 00132 00133 is = sul + Diff2D(0,h-1); 00134 id = dul + Diff2D(0,h-1); 00135 00136 for(x=0; x<w; ++x, ++is.x, ++id.x) 00137 { 00138 if(isLocalExtremum(is, sa, neighborhood, threshold, compare, 00139 isAtImageBorder(x, h-1, w, h))) 00140 da.set(marker, id); 00141 } 00142 } 00143 00144 w -= 2; 00145 h -= 2; 00146 sul += Diff2D(1,1); 00147 dul += Diff2D(1,1); 00148 00149 for(y=0; y<h; ++y, ++sul.y, ++dul.y) 00150 { 00151 SrcIterator sx = sul; 00152 DestIterator dx = dul; 00153 00154 for(x=0; x<w; ++x, ++sx.x, ++dx.x) 00155 { 00156 typename SrcAccessor::value_type v = sa(sx); 00157 00158 if(!compare(v, threshold)) 00159 continue; 00160 00161 int i; 00162 NeighborhoodCirculator<SrcIterator, Neighborhood> sc(sx); 00163 for(i = 0; i < Neighborhood::DirectionCount; ++i, ++sc) 00164 { 00165 if(!compare(v, sa(sc))) 00166 break; 00167 } 00168 00169 if(i == Neighborhood::DirectionCount) 00170 da.set(marker, dx); 00171 } 00172 } 00173 } 00174 00175 template<class SrcIterator, class SrcShape, class SrcAccessor, 00176 class DestIterator, class DestAccessor, class DestValue, 00177 class Neighborhood, class Compare> 00178 void 00179 localMinMax3D(SrcIterator sul, SrcShape shp, SrcAccessor sa, 00180 DestIterator dul, DestAccessor da, 00181 DestValue marker, 00182 Neighborhood neighborhood, 00183 typename SrcAccessor::value_type threshold, 00184 Compare compare, 00185 bool allowExtremaAtBorder = false) 00186 { 00187 int w = shp[0]; 00188 int h = shp[1]; 00189 int d = shp[2]; 00190 00191 int x, y, z; 00192 00193 if (allowExtremaAtBorder) 00194 { 00195 throw std::runtime_error("not implemented!"); 00196 /* 00197 SrcIterator is = sul; 00198 DestIterator id = dul; 00199 00200 for(x=0; x<w; ++x, ++is.x, ++id.x) 00201 { 00202 if(isLocalExtremum(is, sa, neighborhood, threshold, compare, 00203 isAtImageBorder(x, 0, w, h))) 00204 da.set(marker, id); 00205 } 00206 00207 is = sul + Diff2D(0,1); 00208 id = dul + Diff2D(0,1); 00209 00210 for(y=1; y<h-1; ++y, ++is.y, ++id.y) 00211 { 00212 if(isLocalExtremum(is, sa, neighborhood, threshold, compare, 00213 isAtImageBorder(0, y, w, h))) 00214 da.set(marker, id); 00215 } 00216 00217 is = sul + Diff2D(w-1,1); 00218 id = dul + Diff2D(w-1,1); 00219 00220 for(y=1; y<h-1; ++y, ++is.y, ++id.y) 00221 { 00222 if(isLocalExtremum(is, sa, neighborhood, threshold, compare, 00223 isAtImageBorder(w-1, y, w, h))) 00224 da.set(marker, id); 00225 } 00226 00227 is = sul + Diff2D(0,h-1); 00228 id = dul + Diff2D(0,h-1); 00229 00230 for(x=0; x<w; ++x, ++is.x, ++id.x) 00231 { 00232 if(isLocalExtremum(is, sa, neighborhood, threshold, compare, 00233 isAtImageBorder(x, h-1, w, h))) 00234 da.set(marker, id); 00235 } 00236 */ 00237 } 00238 00239 w -= 2; 00240 h -= 2; 00241 d -= 2; 00242 sul.dim0() += 1; 00243 sul.dim1() += 1; 00244 sul.dim2() += 1; 00245 dul += Diff3D(1, 1, 1); 00246 00247 SrcIterator zs = sul; 00248 DestIterator zd = dul; 00249 00250 for (z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2()) 00251 { 00252 SrcIterator ys(zs); 00253 DestIterator yd(zd); 00254 00255 for (y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1()) 00256 { 00257 SrcIterator xs(ys); 00258 DestIterator xd(yd); 00259 00260 for (x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0()) 00261 { 00262 00263 typename SrcAccessor::value_type v = sa(xs); 00264 if (!compare(v, threshold)) 00265 continue; 00266 00267 int i; 00268 NeighborhoodCirculator<SrcIterator, Neighborhood> sc(xs); 00269 for (i = 0; i < Neighborhood::DirectionCount; ++i, ++sc) 00270 { 00271 if(!compare(v, sa(sc))) 00272 break; 00273 } 00274 00275 if(i == Neighborhood::DirectionCount) 00276 da.set(marker, xd); 00277 } 00278 } 00279 } 00280 } 00281 00282 template <class SrcIterator, class SrcAccessor, 00283 class DestIterator, class DestAccessor, class DestValue, 00284 class Neighborhood, class Compare, class Equal> 00285 void 00286 extendedLocalMinMax(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 00287 DestIterator dul, DestAccessor da, DestValue marker, 00288 Neighborhood /*neighborhood*/, 00289 Compare compare, Equal equal, 00290 typename SrcAccessor::value_type threshold, 00291 bool allowExtremaAtBorder = false) 00292 { 00293 typedef typename SrcAccessor::value_type SrcType; 00294 00295 int w = slr.x - sul.x; 00296 int h = slr.y - sul.y; 00297 00298 int i,x,y; 00299 00300 BasicImage<int> labels(w,h); 00301 00302 int number_of_regions = 00303 labelImage(sul, slr, sa, labels.upperLeft(), labels.accessor(), 00304 (Neighborhood::DirectionCount == 8), equal); 00305 00306 // assume that a region is a extremum until the opposite is proved 00307 std::vector<unsigned char> isExtremum(number_of_regions+1, (unsigned char)1); 00308 00309 BasicImage<int>::traverser ly = labels.upperLeft(); 00310 00311 for(y=0; y<h; ++y, ++sul.y, ++ly.y) 00312 { 00313 SrcIterator sx = sul; 00314 BasicImage<int>::traverser lx(ly); 00315 00316 for(x=0; x<w; ++x, ++sx.x, ++lx.x) 00317 { 00318 int lab = *lx; 00319 SrcType v = sa(sx); 00320 00321 if(isExtremum[lab] == 0) 00322 continue; 00323 00324 if(!compare(v, threshold)) 00325 { 00326 // mark all regions that don't exceed the threshold as non-extremum 00327 isExtremum[lab] = 0; 00328 continue; 00329 } 00330 00331 AtImageBorder atBorder = isAtImageBorder(x, y, w, h); 00332 if(atBorder == NotAtBorder) 00333 { 00334 NeighborhoodCirculator<SrcIterator, Neighborhood> sc(sx); 00335 NeighborhoodCirculator<BasicImage<int>::traverser, Neighborhood> lc(lx); 00336 for(i=0; i<Neighborhood::DirectionCount; ++i, ++sc, ++lc) 00337 { 00338 if(lab != *lc && compare(sa(sc),v)) 00339 { 00340 isExtremum[lab] = 0; 00341 break; 00342 } 00343 } 00344 } 00345 else 00346 { 00347 if(allowExtremaAtBorder) 00348 { 00349 RestrictedNeighborhoodCirculator<SrcIterator, Neighborhood> 00350 sc(sx, atBorder), scend(sc); 00351 do 00352 { 00353 if(lab != *(lx+sc.diff()) && compare(sa(sc),v)) 00354 { 00355 isExtremum[lab] = 0; 00356 break; 00357 } 00358 } 00359 while(++sc != scend); 00360 } 00361 else 00362 { 00363 isExtremum[lab] = 0; 00364 } 00365 } 00366 } 00367 } 00368 00369 ly = labels.upperLeft(); 00370 for(y=0; y<h; ++y, ++dul.y, ++ly.y) 00371 { 00372 DestIterator xd = dul; 00373 BasicImage<int>::Iterator lx(ly); 00374 00375 for(x=0; x<w; ++x, ++xd.x, ++lx.x) 00376 { 00377 if(isExtremum[*lx]) 00378 da.set(marker, xd); 00379 } 00380 } 00381 } 00382 00383 template<class SrcIterator, class SrcShape, class SrcAccessor, 00384 class DestIterator, class DestAccessor, class DestValue, 00385 class Neighborhood, class Compare, class Equal> 00386 void 00387 extendedLocalMinMax3D(SrcIterator sul, SrcShape shp, SrcAccessor sa, 00388 DestIterator dul, DestAccessor da, 00389 DestValue marker, 00390 Neighborhood neighbourhood, 00391 Compare compare, 00392 Equal equal, 00393 typename SrcAccessor::value_type threshold, 00394 bool allowExtremaAtBorder = false) 00395 { 00396 typedef typename SrcAccessor::value_type SrcType; 00397 00398 int w = shp[0]; 00399 int h = shp[1]; 00400 int d = shp[2]; 00401 00402 int i, x, y, z; 00403 00404 MultiArray<3, int> labels(shp); 00405 00406 int number_of_regions = 00407 labelVolume(sul, shp, sa, labels.traverser_begin(), 00408 typename AccessorTraits<int>::default_accessor(), 00409 neighbourhood); 00410 00411 MultiArray<3, int>::traverser zl(labels.traverser_begin()); 00412 00413 SrcIterator zs = sul; 00414 DestIterator zd = dul; 00415 00416 // assume that a region is a extremum until the opposite is proved 00417 std::vector<unsigned char> isExtremum(number_of_regions + 1, (unsigned char)1); 00418 00419 for (z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2(), ++zl.dim2()) 00420 { 00421 SrcIterator ys(zs); 00422 DestIterator yd(zd); 00423 MultiArray<3, int>::traverser yl(zl); 00424 00425 for (y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1(), ++yl.dim1()) 00426 { 00427 SrcIterator xs(ys); 00428 DestIterator xd(yd); 00429 MultiArray<3, int>::traverser xl(yl); 00430 00431 for (x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0(), ++xl.dim0()) 00432 { 00433 00434 int lab = *xl; 00435 SrcType v = sa(xs); 00436 00437 if (isExtremum[lab] == 0) 00438 continue; 00439 00440 if (!compare(v, threshold)) 00441 { 00442 // mark all regions that don't exceed the threshold as non-extremum 00443 isExtremum[lab] = 0; 00444 continue; 00445 } 00446 00447 AtVolumeBorder atBorder = isAtVolumeBorder(x, y, z, w, h, d); 00448 if (atBorder == NotAtBorder) 00449 { 00450 NeighborhoodCirculator<SrcIterator, Neighborhood> sc(xs); 00451 NeighborhoodCirculator<MultiArray<3, int>::traverser, Neighborhood> lc(xl); 00452 for (i = 0; i < Neighborhood::DirectionCount; ++i, ++sc, ++lc) 00453 { 00454 if (lab != *lc && compare(sa(sc), v)) 00455 { 00456 00457 isExtremum[lab] = 0; 00458 break; 00459 } 00460 } 00461 } 00462 else 00463 { 00464 if (allowExtremaAtBorder) 00465 { 00466 RestrictedNeighborhoodCirculator<SrcIterator, Neighborhood> 00467 sc(xs, atBorder), scend(sc); 00468 do 00469 { 00470 if (lab != *(xl + sc.diff()) && compare(sa(sc), v)) 00471 { 00472 isExtremum[lab] = 0; 00473 break; 00474 } 00475 } 00476 while (++sc != scend); 00477 } 00478 else 00479 { 00480 isExtremum[lab] = 0; 00481 } 00482 } 00483 } 00484 } 00485 } 00486 00487 zl = labels.traverser_begin(); 00488 zs = sul; 00489 zd = dul; 00490 00491 for (z = 0; z != d; ++z, ++zs.dim2(), ++zd.dim2(), ++zl.dim2()) 00492 { 00493 SrcIterator ys(zs); 00494 DestIterator yd(zd); 00495 MultiArray<3, int>::traverser yl(zl); 00496 00497 for (y = 0; y != h; ++y, ++ys.dim1(), ++yd.dim1(), ++yl.dim1()) 00498 { 00499 SrcIterator xs(ys); 00500 DestIterator xd(yd); 00501 MultiArray<3, int>::traverser xl(yl); 00502 00503 for (x = 0; x != w; ++x, ++xs.dim0(), ++xd.dim0(), ++xl.dim0()) 00504 { 00505 if(isExtremum[*xl]) 00506 da.set(marker, xd); 00507 } 00508 } 00509 } 00510 } 00511 00512 template <class SrcIterator, class SrcAccessor, 00513 class DestIterator, class DestAccessor, class DestValue, 00514 class Neighborhood, class Compare, class Equal> 00515 void 00516 extendedLocalMinMaxOld(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 00517 DestIterator dul, DestAccessor da, DestValue marker, 00518 Neighborhood /*neighborhood*/, 00519 Compare compare, Equal equal, 00520 typename SrcAccessor::value_type threshold, 00521 bool allowExtremaAtBorder = false) 00522 { 00523 typedef typename SrcAccessor::value_type SrcType; 00524 00525 int w = slr.x - sul.x; 00526 int h = slr.y - sul.y; 00527 00528 int i,x,y; 00529 00530 BasicImage<int> labels(w,h); 00531 00532 int number_of_regions = 00533 labelImage(sul, slr, sa, labels.upperLeft(), labels.accessor(), 00534 (Neighborhood::DirectionCount == 8), equal); 00535 00536 // assume that a region is a extremum until the opposite is proved 00537 std::vector<unsigned char> isExtremum(number_of_regions+1, (unsigned char)1); 00538 00539 BasicImage<int>::traverser ly = labels.upperLeft(); 00540 00541 for(y=0; y<h; ++y, ++sul.y, ++ly.y) 00542 { 00543 SrcIterator sx = sul; 00544 BasicImage<int>::traverser lx(ly); 00545 00546 for(x=0; x<w; ++x, ++sx.x, ++lx.x) 00547 { 00548 int lab = *lx; 00549 SrcType v = sa(sx); 00550 if(x == 0 || y == 0 || x == w-1 || y == h-1 || !compare(v, threshold)) 00551 { 00552 // mark all regions that touch the image border as non-extremum 00553 // likewise for all pixels that don't exceed the threshold 00554 isExtremum[lab] = 0; 00555 continue; 00556 } 00557 00558 NeighborhoodCirculator<SrcIterator, Neighborhood> sc(sx); 00559 NeighborhoodCirculator<BasicImage<int>::traverser, Neighborhood> lc(lx); 00560 for(i=0; i<Neighborhood::DirectionCount; ++i, ++sc, ++lc) 00561 { 00562 if(lab != *lc && compare(sa(sc),v)) 00563 isExtremum[lab] = 0; 00564 } 00565 00566 } 00567 } 00568 00569 ly = labels.upperLeft(); 00570 for(y=0; y<h; ++y, ++dul.y, ++ly.y) 00571 { 00572 DestIterator xd = dul; 00573 BasicImage<int>::Iterator lx(ly); 00574 00575 for(x=0; x<w; ++x, ++xd.x, ++lx.x) 00576 { 00577 if(isExtremum[*lx]) 00578 da.set(marker, xd); 00579 } 00580 } 00581 } 00582 00583 } // namespace detail 00584 00585 00586 /** \brief Options object for localMinima() and localMaxima(). 00587 00588 <b> Usage:</b> 00589 00590 <b>\#include</b> <vigra/localminmax.hxx><br> 00591 Namespace: vigra 00592 00593 \code 00594 vigra::BImage src(w,h), minima(w,h); 00595 ... // fill src 00596 00597 // use 4-neighborhood, allow minima at the image border, 00598 // and discard those where the gray value is not below 5 00599 vigra::localMinima(srcImageRange(src), destImage(minima), 00600 vigra::LocalMinmaxOptions().neighborhood(4).allowAtBorder().threshold(5)); 00601 00602 \endcode 00603 */ 00604 class LocalMinmaxOptions 00605 { 00606 public: 00607 double marker, thresh; 00608 int neigh; 00609 bool use_threshold, allow_at_border, allow_plateaus; 00610 00611 /**\brief Construct default options object. 00612 * 00613 Defaults are: marker value '1', no threshold, indirect neighborhood, 00614 don't allow extrema at border and extremal plateaus. 00615 */ 00616 LocalMinmaxOptions() 00617 : marker(1.0), 00618 thresh(0.0), 00619 neigh(1), 00620 use_threshold(false), 00621 allow_at_border(false), 00622 allow_plateaus(false) 00623 {} 00624 00625 /**\brief Use the given neighborhood. 00626 00627 The value '0' indicates direct neighborhood (i.e. 4-neighborhood 00628 in 2D, 6-neighborhood in 3D, 2*N neighborhood in N-D), the value '1' 00629 indicates indirect neighborhood (i.e. 8-neighborhood in 2D, 00630 26-neighborhood in 3D, 3<sup>N</sup>-1 neighborhood in N-D). The specific number 00631 of neighbors for the desired dimension can also be used. 00632 00633 Default: 1 (indirect neighborhood) 00634 */ 00635 LocalMinmaxOptions & neighborhood(unsigned int n) 00636 { 00637 neigh = n; 00638 return *this; 00639 } 00640 00641 /**\brief Mark extrema in the destination image with the given value. 00642 00643 Default: 1 00644 */ 00645 LocalMinmaxOptions & markWith(double m) 00646 { 00647 marker = m; 00648 return *this; 00649 } 00650 00651 /**\brief Threshold the extrema. 00652 00653 Discard minima whose gray value is not below the threshold. 00654 and maxima whose gray level is not above the threshold. 00655 00656 Default: don't threshold (i.e. return all extrema) 00657 */ 00658 LocalMinmaxOptions & threshold(double t) 00659 { 00660 use_threshold = true; 00661 thresh = t; 00662 return *this; 00663 } 00664 00665 /**\brief Detect extrema at the image border. 00666 00667 Default: false 00668 */ 00669 LocalMinmaxOptions & allowAtBorder(bool f = true) 00670 { 00671 allow_at_border = f; 00672 return *this; 00673 } 00674 00675 /**\brief Allow extremal plateaus. 00676 00677 That is regions of constant gray value whose neighbors are all 00678 higher (minima) or lower than the value of the region. 00679 00680 Default: false 00681 */ 00682 LocalMinmaxOptions & allowPlateaus(bool f = true) 00683 { 00684 allow_plateaus = f; 00685 return *this; 00686 } 00687 }; 00688 00689 00690 /********************************************************/ 00691 /* */ 00692 /* localMinima */ 00693 /* */ 00694 /********************************************************/ 00695 00696 /** \brief Find local minima in an image or multi-dimensional array. 00697 00698 Note: the function is not yet implemented for arbitrary dimensional 00699 arrays, but see \ref localMinima3D() for 3D. 00700 00701 By default, minima are defined as points which are not 00702 at the array border and whose value is lower than the value 00703 of all indirect neighbors (i.e. 8-neighbors in 2D, 00704 26-neighbors in 3D, 3<sup>N</sup>-1 neighbors in N-D). 00705 The detected points will be marked 00706 with the default value 1 in the destination array. 00707 00708 The defaults can be overridden in various ways by providing 00709 \ref LocalMinmaxOptions : you can switch to the direct neighborhood 00710 (i.e. 4-neighborhood in 2D, 6-neighborhood in 3D, 2*N neighborhood 00711 in N-D), allow minima at the border, discard minima where the function 00712 value is not below a given threshold, allow extended minima 00713 (i.e. minima that form minimal plateaus rather than isolated pixels -- 00714 note that this option is only supported for 2D images), 00715 and change the marker in the destination image. See usage examples below 00716 for details. 00717 00718 There are also variants of the localMinima() function where parameters 00719 are passed explicitly rather than via an option object. These versions 00720 of the function are deprecated, but will be kept for compatibility. 00721 00722 <b> Declarations:</b> 00723 00724 use arbitrary-dimensional arrays: 00725 \code 00726 namespace vigra { 00727 template <unsigned int N, class T1, class C1, class T2, class C2> 00728 void 00729 localMinima(MultiArrayView<N, T1, C1> src, 00730 MultiArrayView<N, T2, C2> dest, 00731 LocalMinmaxOptions const & options = LocalMinmaxOptions()); 00732 } 00733 \endcode 00734 00735 pass image iterators explicitly: 00736 \code 00737 namespace vigra { 00738 template <class SrcIterator, class SrcAccessor, 00739 class DestIterator, class DestAccessor> 00740 void 00741 localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 00742 DestIterator dul, DestAccessor da, 00743 LocalMinmaxOptions const & options = LocalMinmaxOptions()); 00744 } 00745 \endcode 00746 00747 use argument objects in conjunction with \ref ArgumentObjectFactories : 00748 \code 00749 namespace vigra { 00750 template <class SrcIterator, class SrcAccessor, 00751 class DestIterator, class DestAccessor> 00752 void 00753 localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00754 pair<DestIterator, DestAccessor> dest, 00755 LocalMinmaxOptions const & options = LocalMinmaxOptions()); 00756 } 00757 \endcode 00758 00759 <b> Usage:</b> 00760 00761 <b>\#include</b> <vigra/localminmax.hxx><br> 00762 <b>\#include</b> <vigra/multi_localminmax.hxx><br> 00763 Namespace: vigra 00764 00765 \code 00766 // 3D examples using MultiArray 00767 vigra::MultiArrayShape<3>::type shape(w,h,d); 00768 vigra::MultiArray<3, unsigned char> src(shape), minima(shape); 00769 ... // fill src 00770 00771 // use default parameterisation 00772 vigra::localMinima(src, minima); 00773 00774 // reset destination image 00775 minima = 0; 00776 00777 // use 6-neighborhood and allow minima at the image border 00778 vigra::localMinima(src, minima, 00779 vigra::LocalMinmaxOptions().neighborhood(6).allowAtBorder()); 00780 \endcode 00781 00782 \code 00783 // 2D examples using BasicImage 00784 vigra::BImage src(w,h), minima(w,h); 00785 ... // fill src 00786 00787 // use default parameterisation 00788 vigra::localMinima(srcImageRange(src), destImage(minima)); 00789 00790 // reset destination image 00791 minima = 0; 00792 00793 // use 4-neighborhood and allow minima at the image border 00794 vigra::localMinima(srcImageRange(src), destImage(minima), 00795 vigra::LocalMinmaxOptions().neighborhood(4).allowAtBorder()); 00796 00797 // reset destination image 00798 minima = 0; 00799 00800 // allow extended minima (minimal plateaus) and use value '255' as a marker 00801 vigra::localMinima(srcImageRange(src), destImage(minima), 00802 vigra::LocalMinmaxOptions().allowPlateaus().markWith(255)); 00803 \endcode 00804 00805 <b> Required Interface:</b> 00806 00807 \code 00808 SrcIterator src_upperleft, src_lowerright; 00809 DestIterator dest_upperleft; 00810 00811 SrcAccessor src_accessor; 00812 DestAccessor dest_accessor; 00813 00814 SrcAccessor::value_type u = src_accessor(src_upperleft); 00815 00816 u < u 00817 \endcode 00818 */ 00819 doxygen_overloaded_function(template <...> void localMinima) 00820 00821 template <class SrcIterator, class SrcAccessor, 00822 class DestIterator, class DestAccessor> 00823 inline void 00824 localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 00825 DestIterator dul, DestAccessor da, 00826 LocalMinmaxOptions const & options = LocalMinmaxOptions()) 00827 { 00828 typedef typename SrcAccessor::value_type SrcType; 00829 typedef typename DestAccessor::value_type DestType; 00830 00831 SrcType threshold = options.use_threshold 00832 ? std::min(NumericTraits<SrcType>::max(), (SrcType)options.thresh) 00833 : NumericTraits<SrcType>::max(); 00834 DestType marker = (DestType)options.marker; 00835 00836 if(options.allow_plateaus) 00837 { 00838 if(options.neigh == 0 || options.neigh == 4) 00839 { 00840 detail::extendedLocalMinMax(sul, slr, sa, dul, da, marker, FourNeighborCode(), 00841 std::less<SrcType>(), std::equal_to<SrcType>(), 00842 threshold, options.allow_at_border); 00843 } 00844 else if(options.neigh == 1 || options.neigh == 8) 00845 { 00846 detail::extendedLocalMinMax(sul, slr, sa, dul, da, marker, EightNeighborCode(), 00847 std::less<SrcType>(), std::equal_to<SrcType>(), 00848 threshold, options.allow_at_border); 00849 } 00850 else 00851 vigra_precondition(false, "localMinima(): neighborhood must be 4 or 8."); 00852 00853 } 00854 else 00855 { 00856 if(options.neigh == 0 || options.neigh == 4) 00857 { 00858 detail::localMinMax(sul, slr, sa, dul, da, marker, FourNeighborCode(), 00859 threshold, std::less<SrcType>(), options.allow_at_border); 00860 } 00861 else if(options.neigh == 1 || options.neigh == 8) 00862 { 00863 detail::localMinMax(sul, slr, sa, dul, da, marker, EightNeighborCode(), 00864 threshold, std::less<SrcType>(), options.allow_at_border); 00865 } 00866 else 00867 vigra_precondition(false, "localMinima(): neighborhood must be 4 or 8."); 00868 } 00869 } 00870 00871 template <class SrcIterator, class SrcAccessor, 00872 class DestIterator, class DestAccessor, 00873 class DestValue> 00874 inline void 00875 localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 00876 DestIterator dul, DestAccessor da, 00877 DestValue marker, FourNeighborCode neighborhood) 00878 { 00879 detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood, 00880 NumericTraits<typename SrcAccessor::value_type>::max(), 00881 std::less<typename SrcAccessor::value_type>()); 00882 } 00883 00884 template <class SrcIterator, class SrcAccessor, 00885 class DestIterator, class DestAccessor, 00886 class DestValue> 00887 inline void 00888 localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 00889 DestIterator dul, DestAccessor da, 00890 DestValue marker, EightNeighborCode neighborhood) 00891 { 00892 detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood, 00893 NumericTraits<typename SrcAccessor::value_type>::max(), 00894 std::less<typename SrcAccessor::value_type>()); 00895 } 00896 00897 template <class SrcIterator, class SrcAccessor, 00898 class DestIterator, class DestAccessor, class DestValue> 00899 inline void 00900 localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 00901 DestIterator dul, DestAccessor da, 00902 DestValue marker) 00903 { 00904 localMinima(sul, slr, sa, dul, da, marker, EightNeighborCode()); 00905 } 00906 00907 template <class SrcIterator, class SrcAccessor, 00908 class DestIterator, class DestAccessor, 00909 class DestValue> 00910 inline void 00911 localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00912 pair<DestIterator, DestAccessor> dest, 00913 DestValue marker, FourNeighborCode neighborhood) 00914 { 00915 localMinima(src.first, src.second, src.third, 00916 dest.first, dest.second, marker, neighborhood); 00917 } 00918 00919 template <class SrcIterator, class SrcAccessor, 00920 class DestIterator, class DestAccessor, 00921 class DestValue> 00922 inline void 00923 localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00924 pair<DestIterator, DestAccessor> dest, 00925 DestValue marker, EightNeighborCode neighborhood) 00926 { 00927 localMinima(src.first, src.second, src.third, 00928 dest.first, dest.second, marker, neighborhood); 00929 } 00930 00931 template <class SrcIterator, class SrcAccessor, 00932 class DestIterator, class DestAccessor, class DestValue> 00933 inline void 00934 localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00935 pair<DestIterator, DestAccessor> dest, 00936 DestValue marker) 00937 { 00938 localMinima(src.first, src.second, src.third, 00939 dest.first, dest.second, marker, EightNeighborCode()); 00940 } 00941 00942 template <class SrcIterator, class SrcAccessor, 00943 class DestIterator, class DestAccessor> 00944 inline void 00945 localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 00946 pair<DestIterator, DestAccessor> dest, 00947 LocalMinmaxOptions const & options = LocalMinmaxOptions()) 00948 { 00949 localMinima(src.first, src.second, src.third, 00950 dest.first, dest.second, options); 00951 } 00952 00953 /**************************************************************************/ 00954 00955 /********************************************************/ 00956 /* */ 00957 /* localMinima3D */ 00958 /* */ 00959 /********************************************************/ 00960 00961 /** \brief Find local minima in a 3D multi array. 00962 00963 By default, minima are defined as points which are not 00964 at the array border and whose value is lower than the value 00965 of all indirect neighbors. 00966 The detected points will be marked. See localMinima() for more details. 00967 00968 */ 00969 doxygen_overloaded_function(template <...> void localMinima3D) 00970 00971 template<class SrcIterator, class SrcAccessor, class SrcShape, 00972 class DestIterator, class DestAccessor, class DestValue> 00973 inline void 00974 localMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa, 00975 DestIterator dul, DestAccessor da, 00976 DestValue marker, 00977 NeighborCode3DTwentySix neighborhood) 00978 { 00979 detail::localMinMax3D(sul, slr, sa, dul, da, marker, neighborhood, 00980 NumericTraits<typename SrcAccessor::value_type>::max(), 00981 std::less<typename SrcAccessor::value_type>()); 00982 } 00983 00984 template<class SrcIterator, class SrcAccessor, class SrcShape, 00985 class DestIterator, class DestAccessor, class DestValue> 00986 inline void 00987 localMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa, 00988 DestIterator dul, DestAccessor da, 00989 DestValue marker, 00990 NeighborCode3DSix neighborhood) 00991 { 00992 detail::localMinMax3D(sul, slr, sa, dul, da, marker, neighborhood, 00993 NumericTraits<typename SrcAccessor::value_type>::max(), 00994 std::less<typename SrcAccessor::value_type>()); 00995 } 00996 00997 template<class SrcIterator, class SrcShape, class SrcAccessor, 00998 class DestIterator, class DestAccessor, class DestValue> 00999 inline void 01000 localMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa, 01001 DestIterator dul, DestAccessor da, 01002 DestValue marker) 01003 { 01004 localMinima3D(sul, slr, sa, dul, da, marker, NeighborCode3DSix()); 01005 } 01006 01007 template<class SrcIterator, class SrcShape, class SrcAccessor, 01008 class DestIterator, class DestAccessor, class DestValue> 01009 inline void 01010 localMinima3D(triple<SrcIterator, SrcShape, SrcAccessor> src, 01011 pair<DestIterator, DestAccessor> dest, 01012 DestValue marker, 01013 NeighborCode3DSix neighborhood) 01014 { 01015 localMinima3D(src.first, src.second, src.third, dest.first, dest.second, 01016 marker, neighborhood); 01017 } 01018 01019 template<class SrcIterator, class SrcShape, class SrcAccessor, 01020 class DestIterator, class DestAccessor, class DestValue> 01021 inline void 01022 localMinima3D(triple<SrcIterator, SrcShape, SrcAccessor> src, 01023 pair<DestIterator, DestAccessor> dest, 01024 DestValue marker, 01025 NeighborCode3DTwentySix neighborhood) 01026 { 01027 localMinima3D(src.first, src.second, src.third, dest.first, dest.second, 01028 marker, neighborhood); 01029 } 01030 01031 /**************************************************************************/ 01032 01033 /********************************************************/ 01034 /* */ 01035 /* localMaxima */ 01036 /* */ 01037 /********************************************************/ 01038 01039 /** \brief Find local maxima in an image or multi-dimensional array. 01040 01041 Note: the function is not yet implemented for arbitrary dimensional 01042 arrays, but see \ref localMaxima3D() for 3D. 01043 01044 By default, maxima are defined as points which are not 01045 at the array border and whose value is higher than the value 01046 of all indirect neighbors (i.e. 8-neighbors in 2D, 01047 26-neighbors in 3D, 3<sup>N</sup>-1 neighbors in N-D). 01048 The detected points will be marked 01049 with the default value 1 in the destination array. 01050 01051 The defaults can be overridden in various ways by providing 01052 \ref LocalMinmaxOptions : you can switch to the direct neighborhood 01053 (i.e. 4-neighborhood in 2D, 6-neighborhood in 3D, 2*N neighborhood 01054 in N-D), allow maxima at the border, discard maxima where the function 01055 value is not above a given threshold, allow extended maxima 01056 (i.e. maxima that form maximal plateaus rather than isolated pixels -- 01057 note that this option is only supported for 2D images), 01058 and change the marker in the destination image. See usage examples below 01059 for details. 01060 01061 There are also variants of the localMaxima() function where parameters 01062 are passed explicitly rather than via an option object. These versions 01063 of the function are deprecated, but will be kept for compatibility. 01064 01065 <b> Declarations:</b> 01066 01067 use arbitrary-dimensional arrays: 01068 \code 01069 namespace vigra { 01070 template <unsigned int N, class T1, class C1, class T2, class C2> 01071 void 01072 localMaxima(MultiArrayView<N, T1, C1> src, 01073 MultiArrayView<N, T2, C2> dest, 01074 LocalMinmaxOptions const & options = LocalMinmaxOptions()); 01075 } 01076 \endcode 01077 01078 pass image iterators explicitly: 01079 \code 01080 namespace vigra { 01081 template <class SrcIterator, class SrcAccessor, 01082 class DestIterator, class DestAccessor> 01083 void 01084 localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01085 DestIterator dul, DestAccessor da, 01086 LocalMinmaxOptions const & options = LocalMinmaxOptions()); 01087 } 01088 \endcode 01089 01090 use argument objects in conjunction with \ref ArgumentObjectFactories : 01091 \code 01092 namespace vigra { 01093 template <class SrcIterator, class SrcAccessor, 01094 class DestIterator, class DestAccessor> 01095 void 01096 localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01097 pair<DestIterator, DestAccessor> dest, 01098 LocalMinmaxOptions const & options = LocalMinmaxOptions()); 01099 } 01100 \endcode 01101 01102 <b> Usage:</b> 01103 01104 <b>\#include</b> <vigra/localminmax.hxx><br> 01105 <b>\#include</b> <vigra/multi_localminmax.hxx><br> 01106 Namespace: vigra 01107 01108 \code 01109 // 3D examples using MultiArray 01110 vigra::MultiArrayShape<3>::type shape(w,h,d); 01111 vigra::MultiArray<3, unsigned char> src(shape), maxima(shape); 01112 ... // fill src 01113 01114 // use default parameterisation 01115 vigra::localMaxima(src, maxima); 01116 01117 // reset destination image 01118 maxima = 0; 01119 01120 // use 6-neighborhood and allow maxima at the image border 01121 vigra::localMaxima(src, maxima, 01122 vigra::LocalMinmaxOptions().neighborhood(6).allowAtBorder()); 01123 \endcode 01124 01125 \code 01126 // 2D examples using BasicImage 01127 vigra::BImage src(w,h), maxima(w,h); 01128 ... // fill src 01129 01130 // use default parameterisation 01131 vigra::localMaxima(srcImageRange(src), destImage(maxima)); 01132 01133 // reset destination image 01134 maxima = 0; 01135 01136 // use 4-neighborhood and allow maxima at the image border 01137 vigra::localMaxima(srcImageRange(src), destImage(maxima), 01138 vigra::LocalMinmaxOptions().neighborhood(4).allowAtBorder()); 01139 01140 // reset destination image 01141 maxima = 0; 01142 01143 // allow extended maxima (maximal plateaus) and use value '255' as a marker 01144 vigra::localMaxima(srcImageRange(src), destImage(maxima), 01145 vigra::LocalMinmaxOptions().allowPlateaus().markWith(255)); 01146 \endcode 01147 01148 <b> Required Interface:</b> 01149 01150 \code 01151 SrcIterator src_upperleft, src_lowerright; 01152 DestIterator dest_upperleft; 01153 01154 SrcAccessor src_accessor; 01155 DestAccessor dest_accessor; 01156 01157 SrcAccessor::value_type u = src_accessor(src_upperleft); 01158 01159 u < u 01160 \endcode 01161 */ 01162 doxygen_overloaded_function(template <...> void localMaxima) 01163 01164 template <class SrcIterator, class SrcAccessor, 01165 class DestIterator, class DestAccessor> 01166 inline void 01167 localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01168 DestIterator dul, DestAccessor da, 01169 LocalMinmaxOptions const & options = LocalMinmaxOptions()) 01170 { 01171 typedef typename SrcAccessor::value_type SrcType; 01172 typedef typename DestAccessor::value_type DestType; 01173 01174 SrcType threshold = options.use_threshold 01175 ? std::max(NumericTraits<SrcType>::min(), (SrcType)options.thresh) 01176 : NumericTraits<SrcType>::min(); 01177 DestType marker = (DestType)options.marker; 01178 01179 if(options.allow_plateaus) 01180 { 01181 if(options.neigh == 0 || options.neigh == 4) 01182 { 01183 detail::extendedLocalMinMax(sul, slr, sa, dul, da, marker, FourNeighborCode(), 01184 std::greater<SrcType>(), std::equal_to<SrcType>(), 01185 threshold, options.allow_at_border); 01186 } 01187 else if(options.neigh == 1 || options.neigh == 8) 01188 { 01189 detail::extendedLocalMinMax(sul, slr, sa, dul, da, marker, EightNeighborCode(), 01190 std::greater<SrcType>(), std::equal_to<SrcType>(), 01191 threshold, options.allow_at_border); 01192 } 01193 else 01194 vigra_precondition(false, "localMaxima(): neighborhood must be 4 or 8."); 01195 } 01196 else 01197 { 01198 if(options.neigh == 0 || options.neigh == 4) 01199 { 01200 detail::localMinMax(sul, slr, sa, dul, da, marker, FourNeighborCode(), 01201 threshold, std::greater<SrcType>(), options.allow_at_border); 01202 } 01203 else if(options.neigh == 1 || options.neigh == 8) 01204 { 01205 detail::localMinMax(sul, slr, sa, dul, da, marker, EightNeighborCode(), 01206 threshold, std::greater<SrcType>(), options.allow_at_border); 01207 } 01208 else 01209 vigra_precondition(false, "localMaxima(): neighborhood must be 4 or 8."); 01210 } 01211 } 01212 01213 template <class SrcIterator, class SrcAccessor, 01214 class DestIterator, class DestAccessor, 01215 class DestValue> 01216 inline void 01217 localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01218 DestIterator dul, DestAccessor da, 01219 DestValue marker, FourNeighborCode neighborhood) 01220 { 01221 detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood, 01222 NumericTraits<typename SrcAccessor::value_type>::min(), 01223 std::greater<typename SrcAccessor::value_type>()); 01224 } 01225 01226 template <class SrcIterator, class SrcAccessor, 01227 class DestIterator, class DestAccessor, 01228 class DestValue> 01229 inline void 01230 localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01231 DestIterator dul, DestAccessor da, 01232 DestValue marker, EightNeighborCode neighborhood) 01233 { 01234 detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood, 01235 NumericTraits<typename SrcAccessor::value_type>::min(), 01236 std::greater<typename SrcAccessor::value_type>()); 01237 } 01238 01239 template <class SrcIterator, class SrcAccessor, 01240 class DestIterator, class DestAccessor, class DestValue> 01241 inline void 01242 localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01243 DestIterator dul, DestAccessor da, 01244 DestValue marker) 01245 { 01246 localMaxima(sul, slr, sa, dul, da, marker, EightNeighborCode()); 01247 } 01248 01249 template <class SrcIterator, class SrcAccessor, 01250 class DestIterator, class DestAccessor, 01251 class DestValue> 01252 inline void 01253 localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01254 pair<DestIterator, DestAccessor> dest, 01255 DestValue marker, FourNeighborCode neighborhood) 01256 { 01257 localMaxima(src.first, src.second, src.third, 01258 dest.first, dest.second, marker, neighborhood); 01259 } 01260 01261 template <class SrcIterator, class SrcAccessor, 01262 class DestIterator, class DestAccessor, 01263 class DestValue> 01264 inline void 01265 localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01266 pair<DestIterator, DestAccessor> dest, 01267 DestValue marker, EightNeighborCode neighborhood) 01268 { 01269 localMaxima(src.first, src.second, src.third, 01270 dest.first, dest.second, marker, neighborhood); 01271 } 01272 01273 template <class SrcIterator, class SrcAccessor, 01274 class DestIterator, class DestAccessor, class DestValue> 01275 inline void 01276 localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01277 pair<DestIterator, DestAccessor> dest, 01278 DestValue marker) 01279 { 01280 localMaxima(src.first, src.second, src.third, 01281 dest.first, dest.second, marker, EightNeighborCode()); 01282 } 01283 01284 template <class SrcIterator, class SrcAccessor, 01285 class DestIterator, class DestAccessor> 01286 inline void 01287 localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01288 pair<DestIterator, DestAccessor> dest, 01289 LocalMinmaxOptions const & options = LocalMinmaxOptions()) 01290 { 01291 localMaxima(src.first, src.second, src.third, 01292 dest.first, dest.second, options); 01293 } 01294 01295 /**************************************************************************/ 01296 01297 /********************************************************/ 01298 /* */ 01299 /* localMaxima3D */ 01300 /* */ 01301 /********************************************************/ 01302 01303 /** \brief Find local maxima in a 3D multi array. 01304 01305 By default, maxima are defined as points which are not 01306 at the array border and whose value is higher than the value 01307 of all indirect neighbors. 01308 The detected points will be marked as specified. See localMaxima() for mor details. 01309 */ 01310 doxygen_overloaded_function(template <...> void localMaxima3D) 01311 01312 template<class SrcIterator, class SrcShape, class SrcAccessor, 01313 class DestIterator, class DestAccessor, class DestValue> 01314 inline void 01315 localMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa, 01316 DestIterator dul, DestAccessor da, 01317 DestValue marker, 01318 NeighborCode3DSix neighborhood) 01319 { 01320 detail::localMinMax3D(sul, slr, sa, dul, da, marker, neighborhood, 01321 NumericTraits<typename SrcAccessor::value_type>::min(), 01322 std::greater<typename SrcAccessor::value_type>()); 01323 } 01324 01325 template<class SrcIterator, class SrcShape, class SrcAccessor, 01326 class DestIterator, class DestAccessor, class DestValue> 01327 inline void 01328 localMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa, 01329 DestIterator dul, DestAccessor da, 01330 DestValue marker, 01331 NeighborCode3DTwentySix neighborhood) 01332 { 01333 detail::localMinMax3D(sul, slr, sa, dul, da, marker, neighborhood, 01334 NumericTraits<typename SrcAccessor::value_type>::min(), 01335 std::greater<typename SrcAccessor::value_type>()); 01336 } 01337 01338 template<class SrcIterator, class SrcShape, class SrcAccessor, 01339 class DestIterator, class DestAccessor, class DestValue> 01340 inline void 01341 localMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src, 01342 pair<DestIterator, DestAccessor> dest, 01343 DestValue marker, 01344 NeighborCode3DTwentySix neighborhood) 01345 { 01346 localMaxima3D(src.first, src.second, src.third, dest.first, dest.second, 01347 marker, neighborhood); 01348 } 01349 01350 template<class SrcIterator, class SrcShape, class SrcAccessor, 01351 class DestIterator, class DestAccessor, class DestValue> 01352 inline void 01353 localMaxima3D(vigra::triple<SrcIterator, SrcShape, SrcAccessor> src, 01354 std::pair<DestIterator, DestAccessor> dest, 01355 DestValue marker) 01356 { 01357 localMaxima3D(src.first, src.second, src.third, dest.first, dest.second, 01358 marker, NeighborCode3DSix()); 01359 } 01360 01361 template<class SrcIterator, class SrcShape, class SrcAccessor, 01362 class DestIterator, class DestAccessor, class DestValue> 01363 inline void 01364 localMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src, 01365 pair<DestIterator, DestAccessor> dest, 01366 DestValue marker, 01367 NeighborCode3DSix neighborhood) 01368 { 01369 localMaxima3D(src.first, src.second, src.third, dest.first, dest.second, 01370 marker, neighborhood); 01371 } 01372 01373 /**************************************************************************/ 01374 01375 /********************************************************/ 01376 /* */ 01377 /* extendedLocalMinima */ 01378 /* */ 01379 /********************************************************/ 01380 01381 /** \brief Find local minimal regions in an image or volume. 01382 01383 Note: the function is not yet implemented for arbitrary dimensional 01384 arrays, but see \ref extendedLocalMinima3D() for 3D. 01385 01386 This function finds regions of uniform pixel value 01387 whose neighboring regions are all have smaller values 01388 (minimal plateaus of arbitrary size). By default, the pixels 01389 in a plateau have exactly identical values. By passing an <tt>EqualityFunctor</tt> 01390 with tolerance, one can allow for plateaus that are not quite constant 01391 (this is often necessary with float pixel values). Pass 01392 \ref vigra::EightNeighborCode or \ref vigra::FourNeighborCode 01393 to determine the neighborhood where pixel values are compared. 01394 01395 Minimal regions are 01396 marked in the destination image with the given marker value 01397 (default is 1), all other destination pixels remain unchanged. 01398 <TT>SrcAccessor::value_type</TT> must be equality-comparable and 01399 less-comparable. A pixel or region touching the image border will 01400 never be marked as minimum or minimal plateau. Use localMinima() with the 01401 appropriate options if you need that functionality. Likewise if you want to 01402 apply a threshold onl the fly. In fact, all functionality 01403 except for 'equality with tolerance' can be accessed via that function in 01404 a more readable way, so localMinima() should be preferred. 01405 The function uses accessors. 01406 01407 <b> Declarations:</b> 01408 01409 use 3-dimensional arrays: 01410 \code 01411 namespace vigra { 01412 template <class T1, class C1, class T2, class C2, 01413 class Neighborhood> 01414 void 01415 extendedLocalMinima(MultiArrayView<3, T1, C1> src, 01416 MultiArrayView<3, T2, C2> dest, 01417 LocalMinmaxOptions const & options = LocalMinmaxOptions()); 01418 \endcode 01419 01420 pass image iterators explicitly: 01421 \code 01422 namespace vigra { 01423 template <class SrcIterator, class SrcAccessor, 01424 class DestIterator, class DestAccessor, 01425 class DestValue = DestAccessor::value_type, 01426 class Neighborhood = EightNeighborCode, 01427 class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> > 01428 void 01429 extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01430 DestIterator dul, DestAccessor da, 01431 DestValue marker = NumericTraits<DestValue>::one(), 01432 Neighborhood neighborhood = EightNeighborCode(), 01433 EqualityFunctor equal = EqualityFunctor()); 01434 } 01435 \endcode 01436 01437 use argument objects in conjunction with \ref ArgumentObjectFactories : 01438 \code 01439 namespace vigra { 01440 template <class SrcIterator, class SrcAccessor, 01441 class DestIterator, class DestAccessor, 01442 class DestValue = DestAccessor::value_type, 01443 class Neighborhood = EightNeighborCode, 01444 class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> > 01445 void 01446 extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01447 pair<DestIterator, DestAccessor> dest, 01448 DestValue marker = NumericTraits<DestValue>::one(), 01449 Neighborhood neighborhood = EightNeighborCode(), 01450 EqualityFunctor equal = EqualityFunctor()); 01451 } 01452 \endcode 01453 01454 <b> Usage:</b> 01455 01456 <b>\#include</b> <vigra/localminmax.hxx><br> 01457 Namespace: vigra 01458 01459 \code 01460 01461 // optional: define an equality functor 01462 template <class T> 01463 struct EqualWithToleranceFunctor 01464 { 01465 EqualWithToleranceFunctor(T tolerance) 01466 : t(tolerance) 01467 {} 01468 01469 bool operator()(T l, T r) const 01470 { 01471 return vigra::abs(l-r) <= t; 01472 } 01473 01474 T t; 01475 }; 01476 01477 vigra::BImage src(w,h), minima(w,h); 01478 01479 // init destiniation image 01480 minima.init(0); 01481 01482 vigra::extendedLocalMinima(srcImageRange(src), destImage(minima)); 01483 01484 // allow plateaus with tolerance 01485 minima.init(0); 01486 vigra::extendedLocalMinima(srcImageRange(src), destImage(minima), 1.0, 01487 EqualWithToleranceFunctor<unsigned char>(1)); 01488 \endcode 01489 01490 <b> Required Interface:</b> 01491 01492 \code 01493 SrcImageIterator src_upperleft, src_lowerright; 01494 DestImageIterator dest_upperleft; 01495 01496 SrcAccessor src_accessor; 01497 DestAccessor dest_accessor; 01498 01499 SrcAccessor::value_type u = src_accessor(src_upperleft); 01500 01501 EqualityFunctor equal; 01502 u == u 01503 equal(u, u); 01504 u < u 01505 01506 DestValue marker; 01507 dest_accessor.set(marker, dest_upperleft); 01508 \endcode 01509 01510 */ 01511 doxygen_overloaded_function(template <...> void extendedLocalMinima) 01512 01513 template <class SrcIterator, class SrcAccessor, 01514 class DestIterator, class DestAccessor, 01515 class Neighborhood, class EqualityFunctor> 01516 inline void 01517 extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01518 DestIterator dul, DestAccessor da, 01519 typename DestAccessor::value_type marker, 01520 Neighborhood neighborhood, EqualityFunctor equal) 01521 { 01522 typedef typename SrcAccessor::value_type SrcType; 01523 01524 detail::extendedLocalMinMax(sul, slr, sa, dul, da, 01525 marker, neighborhood, 01526 std::less<SrcType>(), equal, 01527 NumericTraits<typename SrcAccessor::value_type>::max()); 01528 } 01529 01530 template <class SrcIterator, class SrcAccessor, 01531 class DestIterator, class DestAccessor, 01532 class Neighborhood> 01533 inline void 01534 extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01535 DestIterator dul, DestAccessor da, 01536 typename DestAccessor::value_type marker, 01537 Neighborhood neighborhood) 01538 { 01539 typedef typename SrcAccessor::value_type SrcType; 01540 01541 extendedLocalMinima(sul, slr, sa, dul, da, 01542 marker, neighborhood, std::equal_to<SrcType>()); 01543 } 01544 01545 template <class SrcIterator, class SrcAccessor, 01546 class DestIterator, class DestAccessor> 01547 inline void 01548 extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01549 DestIterator dul, DestAccessor da, 01550 typename DestAccessor::value_type marker) 01551 { 01552 typedef typename SrcAccessor::value_type SrcType; 01553 01554 extendedLocalMinima(sul, slr, sa, dul, da, 01555 marker, EightNeighborCode()); 01556 } 01557 01558 template <class SrcIterator, class SrcAccessor, 01559 class DestIterator, class DestAccessor> 01560 inline void 01561 extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01562 DestIterator dul, DestAccessor da) 01563 { 01564 extendedLocalMinima(sul, slr, sa, dul, da, 01565 NumericTraits<typename DestAccessor::value_type>::one()); 01566 } 01567 01568 template <class SrcIterator, class SrcAccessor, 01569 class DestIterator, class DestAccessor, 01570 class Neighborhood, class EqualityFunctor> 01571 inline void 01572 extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01573 pair<DestIterator, DestAccessor> dest, 01574 typename DestAccessor::value_type marker, Neighborhood neighborhood, 01575 EqualityFunctor equal) 01576 { 01577 extendedLocalMinima(src.first, src.second, src.third, 01578 dest.first, dest.second, marker, neighborhood, equal); 01579 } 01580 01581 template <class SrcIterator, class SrcAccessor, 01582 class DestIterator, class DestAccessor, 01583 class Neighborhood> 01584 inline void 01585 extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01586 pair<DestIterator, DestAccessor> dest, 01587 typename DestAccessor::value_type marker, Neighborhood neighborhood) 01588 { 01589 extendedLocalMinima(src.first, src.second, src.third, 01590 dest.first, dest.second, marker, neighborhood); 01591 } 01592 01593 template <class SrcIterator, class SrcAccessor, 01594 class DestIterator, class DestAccessor> 01595 inline void 01596 extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01597 pair<DestIterator, DestAccessor> dest, 01598 typename DestAccessor::value_type marker) 01599 { 01600 extendedLocalMinima(src.first, src.second, src.third, 01601 dest.first, dest.second, marker, EightNeighborCode()); 01602 } 01603 01604 template <class SrcIterator, class SrcAccessor, 01605 class DestIterator, class DestAccessor> 01606 inline void 01607 extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01608 pair<DestIterator, DestAccessor> dest) 01609 { 01610 extendedLocalMinima(src.first, src.second, src.third, 01611 dest.first, dest.second); 01612 } 01613 01614 /**************************************************************************/ 01615 01616 /********************************************************/ 01617 /* */ 01618 /* extendedLocalMinima3D */ 01619 /* */ 01620 /********************************************************/ 01621 01622 /** \brief Find local minimal regions in a volume. 01623 01624 This function finds regions of uniform pixel value 01625 whose neighboring regions are all have smaller values 01626 (minimal plateaus of arbitrary size). By default, the pixels 01627 in a plateau have exactly identical values. By passing an <tt>EqualityFunctor</tt> 01628 with tolerance, one can allow for plateaus that are not quite constant 01629 (this is often necessary with float pixel values). Pass the neighborhood 01630 where pixel values are compared. See extendedLocalMinima() for more details. 01631 01632 */ 01633 doxygen_overloaded_function(template <...> void extendedLocalMinima3D) 01634 01635 template<class SrcIterator, class SrcShape, class SrcAccessor, 01636 class DestIterator, class DestAccessor, class Neighborhood, 01637 class EqualityFunctor> 01638 inline void 01639 extendedLocalMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa, 01640 DestIterator dul, DestAccessor da, 01641 typename DestAccessor::value_type marker, 01642 Neighborhood neighborhood, 01643 EqualityFunctor equal) 01644 { 01645 typedef typename SrcAccessor::value_type SrcType; 01646 01647 detail::extendedLocalMinMax3D(sul, slr, sa, dul, da, marker, neighborhood, 01648 std::less<SrcType>(), equal, 01649 NumericTraits<typename SrcAccessor::value_type>::max()); 01650 } 01651 01652 template<class SrcIterator, class SrcShape, class SrcAccessor, 01653 class DestIterator, class DestAccessor, class Neighborhood> 01654 inline void 01655 extendedLocalMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa, 01656 DestIterator dul, DestAccessor da, 01657 typename DestAccessor::value_type marker, 01658 Neighborhood neighborhood) 01659 { 01660 typedef typename SrcAccessor::value_type SrcType; 01661 01662 extendedLocalMinima3D(sul, slr, sa, dul, da, marker, neighborhood, 01663 std::equal_to<SrcType>()); 01664 } 01665 01666 template<class SrcIterator, class SrcShape, class SrcAccessor, 01667 class DestIterator, class DestAccessor> 01668 inline void 01669 extendedLocalMinima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa, 01670 DestIterator dul, DestAccessor da) 01671 { 01672 extendedLocalMinima3D(sul, slr, sa, dul, da, 01673 NumericTraits<typename DestAccessor::value_type>::one(), 01674 NeighborCode3DSix()); 01675 } 01676 01677 template<class SrcIterator, class SrcAccessor, class SrcShape, 01678 class DestIterator, class DestAccessor, class Neighborhood> 01679 inline void 01680 extendedLocalMinima3D(triple<SrcIterator, SrcShape, SrcAccessor> src, 01681 pair<DestIterator, DestAccessor> dest, 01682 typename DestAccessor::value_type marker, 01683 Neighborhood neighborhood) 01684 { 01685 extendedLocalMinima3D(src.first, src.second, src.third, 01686 dest.first, dest.second, 01687 marker, neighborhood); 01688 } 01689 01690 /**************************************************************************/ 01691 01692 /********************************************************/ 01693 /* */ 01694 /* extendedLocalMaxima */ 01695 /* */ 01696 /********************************************************/ 01697 01698 /** \brief Find local maximal regions in an image or volume. 01699 01700 Note: the function is not yet implemented for arbitrary dimensional 01701 arrays, but see \ref extendedLocalMaxima3D() for 3D. 01702 01703 This function finds regions of uniform pixel value 01704 whose neighboring regions are all have smaller values 01705 (maximal plateaus of arbitrary size). By default, the pixels 01706 in a plateau have exactly identical values. By passing an <tt>EqualityFunctor</tt> 01707 with tolerance, one can allow for plateaus that are not quite constant 01708 (this is often necessary with float pixel values). Pass 01709 \ref vigra::EightNeighborCode or \ref vigra::FourNeighborCode 01710 to determine the neighborhood where pixel values are compared. 01711 01712 Maximal regions are 01713 marked in the destination image with the given marker value 01714 (default is 1), all other destination pixels remain unchanged. 01715 <TT>SrcAccessor::value_type</TT> must be equality-comparable and 01716 less-comparable. A pixel or region touching the image border will 01717 never be marked as maximum or maximal plateau. Use localMaxima() with the 01718 appropriate options if you need that functionality. Likewise if you want to 01719 apply a threshold onl the fly. In fact, all functionality 01720 except for 'equality with tolerance' can be accessed via that function in 01721 a more readable way, so localMaxima() should be preferred. 01722 The function uses accessors. 01723 01724 <b> Declarations:</b> 01725 01726 use 3-dimensional arrays: 01727 \code 01728 namespace vigra { 01729 template <class T1, class C1, class T2, class C2, 01730 class Neighborhood> 01731 void 01732 extendedLocalMaxima(MultiArrayView<3, T1, C1> src, 01733 MultiArrayView<3, T2, C2> dest, 01734 LocalMinmaxOptions const & options = LocalMinmaxOptions()); 01735 \endcode 01736 01737 pass image iterators explicitly: 01738 \code 01739 namespace vigra { 01740 template <class SrcIterator, class SrcAccessor, 01741 class DestIterator, class DestAccessor, 01742 class DestValue = DestAccessor::value_type, 01743 class Neighborhood = EightNeighborCode, 01744 class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> > 01745 void 01746 extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01747 DestIterator dul, DestAccessor da, 01748 DestValue marker = NumericTraits<DestValue>::one(), 01749 Neighborhood neighborhood = EightNeighborCode(), 01750 EqualityFunctor equal = EqualityFunctor()) 01751 } 01752 \endcode 01753 01754 use argument objects in conjunction with \ref ArgumentObjectFactories : 01755 \code 01756 namespace vigra { 01757 template <class SrcIterator, class SrcAccessor, 01758 class DestIterator, class DestAccessor, 01759 class DestValue = DestAccessor::value_type, 01760 class Neighborhood = EightNeighborCode, 01761 class EqualityFunctor = std::equal_to<typename SrcAssessor::value_type> > 01762 void 01763 extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01764 pair<DestIterator, DestAccessor> dest, 01765 DestValue marker = NumericTraits<DestValue>::one(), 01766 Neighborhood neighborhood = EightNeighborCode(), 01767 EqualityFunctor equal = EqualityFunctor()) 01768 } 01769 \endcode 01770 01771 <b> Usage:</b> 01772 01773 <b>\#include</b> <vigra/localminmax.hxx><br> 01774 Namespace: vigra 01775 01776 \code 01777 01778 // optional: define an equality functor 01779 template <class T> 01780 struct EqualWithToleranceFunctor 01781 { 01782 EqualWithToleranceFunctor(T tolerance) 01783 : t(tolerance) 01784 {} 01785 01786 bool operator()(T l, T r) const 01787 { 01788 return vigra::abs(l-r) <= t; 01789 } 01790 01791 T t; 01792 }; 01793 01794 vigra::BImage src(w,h), maxima(w,h); 01795 01796 // init destiniation image 01797 maxima.init(0); 01798 01799 vigra::extendedLocalMaxima(srcImageRange(src), destImage(maxima)); 01800 01801 // allow plateaus with tolerance 01802 maxima.init(0); 01803 vigra::extendedLocalMaxima(srcImageRange(src), destImage(maxima), 1.0, 01804 EqualWithToleranceFunctor<unsigned char>(1)); 01805 \endcode 01806 01807 <b> Required Interface:</b> 01808 01809 \code 01810 SrcImageIterator src_upperleft, src_lowerright; 01811 DestImageIterator dest_upperleft; 01812 01813 SrcAccessor src_accessor; 01814 DestAccessor dest_accessor; 01815 01816 SrcAccessor::value_type u = src_accessor(src_upperleft); 01817 01818 EqualityFunctor equal; 01819 u == u 01820 equal(u, u); 01821 u < u 01822 01823 DestValue marker; 01824 dest_accessor.set(marker, dest_upperleft); 01825 \endcode 01826 01827 */ 01828 doxygen_overloaded_function(template <...> void extendedLocalMaxima) 01829 01830 template <class SrcIterator, class SrcAccessor, 01831 class DestIterator, class DestAccessor, 01832 class Neighborhood, class EqualityFunctor> 01833 inline void 01834 extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01835 DestIterator dul, DestAccessor da, 01836 typename DestAccessor::value_type marker, 01837 Neighborhood neighborhood, EqualityFunctor equal) 01838 { 01839 typedef typename SrcAccessor::value_type SrcType; 01840 01841 detail::extendedLocalMinMax(sul, slr, sa, dul, da, 01842 marker, neighborhood, 01843 std::greater<SrcType>(), equal, 01844 NumericTraits<typename SrcAccessor::value_type>::min()); 01845 } 01846 01847 template <class SrcIterator, class SrcAccessor, 01848 class DestIterator, class DestAccessor, 01849 class Neighborhood> 01850 inline void 01851 extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01852 DestIterator dul, DestAccessor da, 01853 typename DestAccessor::value_type marker, 01854 Neighborhood neighborhood) 01855 { 01856 typedef typename SrcAccessor::value_type SrcType; 01857 01858 extendedLocalMaxima(sul, slr, sa, dul, da, 01859 marker, neighborhood, std::equal_to<SrcType>()); 01860 } 01861 01862 template <class SrcIterator, class SrcAccessor, 01863 class DestIterator, class DestAccessor> 01864 inline void 01865 extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01866 DestIterator dul, DestAccessor da, 01867 typename DestAccessor::value_type marker) 01868 { 01869 typedef typename SrcAccessor::value_type SrcType; 01870 01871 extendedLocalMaxima(sul, slr, sa, dul, da, 01872 marker, EightNeighborCode()); 01873 } 01874 01875 template <class SrcIterator, class SrcAccessor, 01876 class DestIterator, class DestAccessor> 01877 inline void 01878 extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, 01879 DestIterator dul, DestAccessor da) 01880 { 01881 extendedLocalMaxima(sul, slr, sa, dul, da, 01882 NumericTraits<typename DestAccessor::value_type>::one()); 01883 } 01884 01885 template <class SrcIterator, class SrcAccessor, 01886 class DestIterator, class DestAccessor, 01887 class Neighborhood, class EqualityFunctor> 01888 inline void 01889 extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01890 pair<DestIterator, DestAccessor> dest, 01891 typename DestAccessor::value_type marker, Neighborhood neighborhood, 01892 EqualityFunctor equal) 01893 { 01894 extendedLocalMaxima(src.first, src.second, src.third, 01895 dest.first, dest.second, marker, neighborhood, equal); 01896 } 01897 01898 template <class SrcIterator, class SrcAccessor, 01899 class DestIterator, class DestAccessor, 01900 class Neighborhood> 01901 inline void 01902 extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01903 pair<DestIterator, DestAccessor> dest, 01904 typename DestAccessor::value_type marker, Neighborhood neighborhood) 01905 { 01906 extendedLocalMaxima(src.first, src.second, src.third, 01907 dest.first, dest.second, marker, neighborhood); 01908 } 01909 01910 template <class SrcIterator, class SrcAccessor, 01911 class DestIterator, class DestAccessor> 01912 inline void 01913 extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01914 pair<DestIterator, DestAccessor> dest, 01915 typename DestAccessor::value_type marker) 01916 { 01917 extendedLocalMaxima(src.first, src.second, src.third, 01918 dest.first, dest.second, marker, EightNeighborCode()); 01919 } 01920 01921 template <class SrcIterator, class SrcAccessor, 01922 class DestIterator, class DestAccessor> 01923 inline void 01924 extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, 01925 pair<DestIterator, DestAccessor> dest) 01926 { 01927 extendedLocalMaxima(src.first, src.second, src.third, 01928 dest.first, dest.second); 01929 } 01930 01931 /********************************************************/ 01932 /* */ 01933 /* extendedLocalMaxima3D */ 01934 /* */ 01935 /********************************************************/ 01936 01937 /** \brief Find local maximal regions in 3D multi array. 01938 01939 This function finds regions of uniform pixel value 01940 whose neighboring regions are all have smaller values 01941 (maximal plateaus of arbitrary size). By default, the pixels 01942 in a plateau have exactly identical values. By passing an <tt>EqualityFunctor</tt> 01943 with tolerance, one can allow for plateaus that are not quite constant 01944 (this is often necessary with float pixel values). Pass 01945 the neighborhood where pixel values are compared. See extendedLocalMaxima() for more details. 01946 */ 01947 01948 doxygen_overloaded_function(template <...> void extendedLocalMaxima3D) 01949 01950 template<class SrcIterator, class SrcShape, class SrcAccessor, 01951 class DestIterator, class DestAccessor, class Neighborhood, 01952 class EqualityFunctor> 01953 inline void 01954 extendedLocalMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa, 01955 DestIterator dul, DestAccessor da, 01956 typename DestAccessor::value_type marker, 01957 Neighborhood neighborhood, 01958 EqualityFunctor equal) 01959 { 01960 typedef typename SrcAccessor::value_type SrcType; 01961 01962 detail::extendedLocalMinMax3D(sul, slr, sa, dul, da, marker, neighborhood, 01963 std::greater<SrcType>(), equal, 01964 NumericTraits<typename SrcAccessor::value_type>::min()); 01965 } 01966 01967 template<class SrcIterator, class SrcShape, class SrcAccessor, 01968 class DestIterator, class DestAccessor, class Neighborhood> 01969 inline void 01970 extendedLocalMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa, 01971 DestIterator dul, DestAccessor da, 01972 typename DestAccessor::value_type marker, 01973 Neighborhood neighborhood) 01974 { 01975 typedef typename SrcAccessor::value_type SrcType; 01976 01977 extendedLocalMaxima3D(sul, slr, sa, dul, da, 01978 marker, neighborhood, 01979 std::equal_to<SrcType>()); 01980 } 01981 01982 template<class SrcIterator, class SrcShape, class SrcAccessor, 01983 class DestIterator, class DestAccessor> 01984 inline void 01985 extendedLocalMaxima3D(SrcIterator sul, SrcShape slr, SrcAccessor sa, 01986 DestIterator dul, DestAccessor da) 01987 { 01988 extendedLocalMaxima3D(sul, slr, sa, dul, da, 01989 NumericTraits<typename DestAccessor::value_type>::one(), 01990 NeighborCode3DSix()); 01991 } 01992 01993 template<class SrcIterator, class SrcShape, class SrcAccessor, 01994 class DestIterator, class DestAccessor, class Neighborhood> 01995 inline void 01996 extendedLocalMaxima3D(triple<SrcIterator, SrcShape, SrcAccessor> src, 01997 pair<DestIterator, DestAccessor> dest, 01998 typename DestAccessor::value_type marker, 01999 Neighborhood neighborhood) 02000 { 02001 extendedLocalMaxima3D(src.first, src.second, src.third, 02002 dest.first, dest.second, 02003 marker, neighborhood); 02004 } 02005 02006 //@} 02007 02008 } // namespace vigra 02009 02010 #endif // VIGRA_LOCALMINMAX_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|