[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

vigra/localminmax.hxx VIGRA

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)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.9.0 (Tue Nov 6 2012)