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

| vigra/symmetry.hxx |
--- | --- | ---

    00001 /************************************************************************/
    00002 /*                                                                      */
    00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
    00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
    00005 /*                                                                      */
    00006 /*    This file is part of the VIGRA computer vision library.           */
    00007 /*    ( Version 1.4.0, Dec 21 2005 )                                    */
    00008 /*    The VIGRA Website is                                              */
    00009 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
    00010 /*    Please direct questions, bug reports, and contributions to        */
    00011 /*        koethe@informatik.uni-hamburg.de          or                  */
    00012 /*        vigra@kogs1.informatik.uni-hamburg.de                         */
    00013 /*                                                                      */
    00014 /*    Permission is hereby granted, free of charge, to any person       */
    00015 /*    obtaining a copy of this software and associated documentation    */
    00016 /*    files (the "Software"), to deal in the Software without           */
    00017 /*    restriction, including without limitation the rights to use,      */
    00018 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
    00019 /*    sell copies of the Software, and to permit persons to whom the    */
    00020 /*    Software is furnished to do so, subject to the following          */
    00021 /*    conditions:                                                       */
    00022 /*                                                                      */
    00023 /*    The above copyright notice and this permission notice shall be    */
    00024 /*    included in all copies or substantial portions of the             */
    00025 /*    Software.                                                         */
    00026 /*                                                                      */
    00027 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
    00028 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
    00029 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
    00030 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
    00031 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
    00032 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
    00033 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
    00034 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
    00035 /*                                                                      */
    00036 /************************************************************************/
    00037
    00038 #ifndef VIGRA_SYMMETRY_HXX
    00039 #define VIGRA_SYMMETRY_HXX
    00040
    00041 #include <vigra/utilities.hxx>
    00042 #include <vigra/numerictraits.hxx>
    00043 #include <vigra/stdimage.hxx>
    00044 #include <vigra/convolution.hxx>
    00045
    00046 namespace vigra {
    00047
    00048 /** \addtogroup SymmetryDetection Symmetry Detection
    00049     Measure the local symmetry at each pixel.
    00050 */
    00051 //@{
    00052
    00053 /********************************************************/
    00054 /*                                                      */
    00055 /*                 radialSymmetryTransform              */
    00056 /*                                                      */
    00057 /********************************************************/
    00058
    00059 /** \brief Find centers of radial symmetry in an image.
    00060
    00061     This algorithm implements the Fast Radial Symmetry Transform according to
    00062     [G. Loy, A. Zelinsky: <em> "A Fast Radial Symmetry Transform for Detecting
    00063     Points of Interest"</em>, in: A. Heyden et al. (Eds.): Proc. of 7th European
    00064     Conf. on Computer Vision, Part 1, pp. 358-368, Springer LNCS 2350, 2002].
    00065     Minima of the algorithm response mark dark blobs, maxima correspond to light blobs.
    00066     The "radial strictness parameter" is fixed at <TT>alpha</tt> = 2.0, the
    00067     spatial spreading of the raw response is done by a Gaussian convolution
    00068     at <tt>0.25*scale</TT> (these values are recommendations from the paper).
    00069     Loy and Zelinsky additionally propose to add the operator response from several
    00070     scales (see usage example below).
    00071
    00072     <b> Declarations:</b>
    00073
    00074     pass arguments explicitly:
    00075     \code
    00076     namespace vigra {
    00077         template <class SrcIterator, class SrcAccessor,
    00078               class DestIterator, class DestAccessor>
    00079         void
    00080         radialSymmetryTransform(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00081                    DestIterator dul, DestAccessor ad,
    00082                    double scale)
    00083     }
    00084     \endcode
    00085
    00086     use argument objects in conjunction with \ref ArgumentObjectFactories:
    00087     \code
    00088     namespace vigra {
    00089         template <class SrcIterator, class SrcAccessor,
    00090               class DestIterator, class DestAccessor>
    00091         inline
    00092         void radialSymmetryTransform(
    00093                triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00094                pair<DestIterator, DestAccessor> dest,
    00095                double scale)
    00096     }
    00097     \endcode
    00098
    00099     <b> Usage:</b>
    00100
    00101         <b>\#include</b> "<a href="symmetry_8hxx-source.html">vigra/symmetry.hxx</a>"<br>
    00102     Namespace: vigra
    00103
    00104     \code
    00105     vigra::BImage src(w,h), centers(w,h);
    00106     vigra::FImage symmetry(w,h);
    00107
    00108     // empty result image
    00109     centers.init(128);
    00110     symmetry.init(0.0);
    00111
    00112     // input width of edge detection filter
    00113     for(double scale = 2.0; scale <= 8.0; scale *= 2.0)
    00114     {
    00115         vigra::FImage tmp(w,h);
    00116
    00117         // find centers of symmetry
    00118         radialSymmetryTransform(srcImageRange(src), destImage(tmp), scale);
    00119
    00120         combineTwoImages(srcImageRange(symmetry), srcImage(tmp), destImage(symmetry),
    00121                          std::plus<float>());
    00122     }
    00123
    00124     localMinima(srcImageRange(symmetry), destImage(centers), 0);
    00125     localMaxima(srcImageRange(symmetry), destImage(centers), 255);
    00126     \endcode
    00127
    00128     <b> Required Interface:</b>
    00129
    00130     \code
    00131     SrcImageIterator src_upperleft, src_lowerright;
    00132     DestImageIterator dest_upperleft;
    00133
    00134     SrcAccessor src_accessor;
    00135     DestAccessor dest_accessor;
    00136
    00137     // SrcAccessor::value_type must be a built-in type
    00138     SrcAccessor::value_type u = src_accessor(src_upperleft);
    00139
    00140     dest_accessor.set(u, dest_upperleft);
    00141     \endcode
    00142 */
    00143 template <class SrcIterator, class SrcAccessor,
    00144           class DestIterator, class DestAccessor>
    00145 void
    00146 radialSymmetryTransform(SrcIterator sul, SrcIterator slr, SrcAccessor as,
    00147                DestIterator dul, DestAccessor ad,
    00148         double scale)
    00149 {
    00150     vigra_precondition(scale > 0.0,
    00151                  "radialSymmetryTransform(): Scale must be > 0");
    00152
    00153     int w = slr.x - sul.x;
    00154     int h = slr.y - sul.y;
    00155
    00156     if(w <= 0 || h <= 0) return;
    00157
    00158     typedef typename
    00159         NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
    00160
    00161     typedef BasicImage<TmpType> TmpImage;
    00162     typedef typename TmpImage::Iterator TmpIterator;
    00163
    00164     TmpImage gx(w,h);
    00165     TmpImage gy(w,h);
    00166     IImage   orientationCounter(w,h);
    00167     TmpImage magnitudeAccumulator(w,h);
    00168
    00169     gaussianGradient(srcIterRange(sul, slr, as),
    00170                      destImage(gx), destImage(gy),
    00171                      scale);
    00172
    00173     orientationCounter.init(0);
    00174     magnitudeAccumulator.init(NumericTraits<TmpType>::zero());
    00175
    00176     TmpIterator gxi = gx.upperLeft();
    00177     TmpIterator gyi = gy.upperLeft();
    00178     int y;
    00179     for(y=0; y<h; ++y, ++gxi.y, ++gyi.y)
    00180     {
    00181         typename TmpIterator::row_iterator gxr = gxi.rowIterator();
    00182         typename TmpIterator::row_iterator gyr = gyi.rowIterator();
    00183
    00184         for(int x = 0; x<w; ++x, ++gxr, ++gyr)
    00185         {
    00186             double angle = VIGRA_CSTD::atan2(-*gyr, *gxr);
    00187             double magnitude = VIGRA_CSTD::sqrt(*gxr * *gxr + *gyr * *gyr);
    00188
    00189             if(magnitude < NumericTraits<TmpType>::epsilon()*10.0)
    00190                 continue;
    00191
    00192             int dx = NumericTraits<int>::fromRealPromote(scale * VIGRA_CSTD::cos(angle));
    00193             int dy = NumericTraits<int>::fromRealPromote(scale * VIGRA_CSTD::sin(angle));
    00194
    00195             int xx = x + dx;
    00196             int yy = y - dy;
    00197
    00198             if(xx >= 0 && xx < w && yy >= 0 && yy < h)
    00199             {
    00200                 orientationCounter(xx, yy) += 1;
    00201                 magnitudeAccumulator(xx, yy) += magnitude;
    00202             }
    00203
    00204             xx = x - dx;
    00205             yy = y + dy;
    00206
    00207             if(xx >= 0 && xx < w && yy >= 0 && yy < h)
    00208             {
    00209                 orientationCounter(xx, yy) -= 1;
    00210                 magnitudeAccumulator(xx, yy) -= magnitude;
    00211             }
    00212         }
    00213     }
    00214
    00215     int maxOrientation = 0;
    00216     TmpType maxMagnitude = NumericTraits<TmpType>::zero();
    00217
    00218     for(y=0; y<h; ++y)
    00219     {
    00220         for(int x = 0; x<w; ++x)
    00221         {
    00222             int o = VIGRA_CSTD::abs(orientationCounter(x,y));
    00223
    00224             if(o > maxOrientation)
    00225                 maxOrientation = o;
    00226
    00227             TmpType m = VIGRA_CSTD::abs(magnitudeAccumulator(x,y));
    00228
    00229             if(m > maxMagnitude)
    00230                 maxMagnitude = m;
    00231         }
    00232     }
    00233
    00234     for(y=0; y<h; ++y)
    00235     {
    00236         for(int x = 0; x<w; ++x)
    00237         {
    00238             double o = (double)orientationCounter(x, y) / maxOrientation;
    00239             magnitudeAccumulator(x, y) = o * o * magnitudeAccumulator(x, y) / maxMagnitude;
    00240         }
    00241     }
    00242
    00243     gaussianSmoothing(srcImageRange(magnitudeAccumulator), destIter(dul, ad), 0.25*scale);
    00244 }
    00245
    00246 template <class SrcIterator, class SrcAccessor,
    00247           class DestIterator, class DestAccessor>
    00248 inline
    00249 void radialSymmetryTransform(
    00250            triple<SrcIterator, SrcIterator, SrcAccessor> src,
    00251        pair<DestIterator, DestAccessor> dest,
    00252        double scale)
    00253 {
    00254     radialSymmetryTransform(src.first, src.second, src.third,
    00255                             dest.first, dest.second,
    00256                 scale);
    00257 }
    00258
    00259
    00260 //@}
    00261
    00262 } // namespace vigra
    00263
    00264
    00265 #endif /* VIGRA_SYMMETRY_HXX */

© Ullrich Köthe (koethe@informatik.uni-hamburg.de) Cognitive Systems Group, University of Hamburg, Germany | html generated using doxygen and Python VIGRA 1.4.0 (21 Dec 2005)