VIGRA - VIGRA: vigra/basicgeometry.hxx Source File

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

# vigra/basicgeometry.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.6.0, Aug 13 2008 )                                    */
    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 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
    00012 /*        vigra@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_BASICGEOMETRY_HXX
    00039 #define VIGRA_BASICGEOMETRY_HXX
    00040
    00041 #include "error.hxx"
    00042 #include "stdimage.hxx"
    00043 #include "copyimage.hxx"
    00044 #include <cmath>
    00045
    00046 namespace vigra {
    00047
    00048 /** \addtogroup GeometricTransformations Geometric Transformations
    00049 */
    00050 //@{
    00051
    00052 /********************************************************/
    00053 /*                                                      */
    00054 /*                      rotateImage                     */
    00055 /*                                                      */
    00056 /********************************************************/
    00057
    00058 /** \brief Rotate image by a multiple of 90 degrees.
    00059
    00060     This algorithm just copies the pixels in the appropriate new order. It expects the
    00061     destination image to have the correct shape for the desired rotation.
    00062
    00063     <b> Declarations:</b>
    00064
    00065     pass arguments explicitly:
    00066     \code
    00067     namespace vigra {
    00068         template <class SrcIterator, class SrcAccessor,
    00069                   class DestIterator, class DestAccessor>
    00070         void
    00071         rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as,
    00072                     DestIterator id, DestAccessor ad, int rotation);
    00073     }
    00074     \endcode
    00075
    00076     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00077     \code
    00078     namespace vigra {
    00079         template <class SrcImageIterator, class SrcAccessor,
    00080               class DestImageIterator, class DestAccessor>
    00081         inline void
    00082         rotateImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00083                     pair<DestImageIterator, DestAccessor> dest, int rotation);
    00084     }
    00085     \endcode
    00086
    00087     <b> Usage:</b>
    00088
    00089         <b>\#include</b> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><br>
    00090         Namespace: vigra
    00091
    00092     \code
    00093     Image dest(src.height(), src.width()); // note that width and height are exchanged
    00094
    00095     vigra::rotateImage(srcImageRange(src), destImage(dest), 90);
    00096
    00097     \endcode
    00098
    00099     <b> Required Interface:</b>
    00100
    00101     \code
    00102     SrcImageIterator src_upperleft, src_lowerright;
    00103     DestImageIterator dest_upperleft;
    00104
    00105     SrcAccessor src_accessor;
    00106
    00107     dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
    00108
    00109     \endcode
    00110
    00111     <b> Preconditions:</b>
    00112
    00113     \code
    00114     src_lowerright.x - src_upperleft.x > 1
    00115     src_lowerright.y - src_upperleft.y > 1
    00116     \endcode
    00117
    00118 */
    00119 doxygen_overloaded_function(template <...> void rotateImage)
    00120
    00121 template <class SrcIterator, class SrcAccessor,
    00122           class DestIterator, class DestAccessor>
    00123 void rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as,
    00124                            DestIterator id, DestAccessor ad, int rotation)
    00125 {
    00126     int x, y;
    00127     int ws = end.x - is.x;
    00128     int hs = end.y - is.y;
    00129
    00130     vigra_precondition(rotation % 90 == 0,
    00131                 "rotateImage(): "
    00132                 "This function rotates images only about multiples of 90 degree");
    00133
    00134     rotation = rotation%360;
    00135     if (rotation < 0)
    00136         rotation += 360;
    00137
    00138     switch(rotation)
    00139     {
    00140         case 0:
    00141             copyImage(is, end, as, id, ad);
    00142             break;
    00143         case 90:
    00144             is.x += (ws-1);
    00145             for(x=0; x != ws; x++, is.x--, id.y++)
    00146             {
    00147                 typename SrcIterator::column_iterator cs = is.columnIterator();
    00148                 typename DestIterator::row_iterator rd = id.rowIterator();
    00149                 for(y=0; y != hs; y++, cs++, rd++)
    00150                 {
    00151                     ad.set(as(cs), rd);
    00152                 }
    00153
    00154             }
    00155             break;
    00156
    00157         case 180:
    00158             end.x--;
    00159             end.y--;
    00160             for(x=0; x != ws; x++, end.x--, id.x++)
    00161             {
    00162                 typename SrcIterator::column_iterator cs = end.columnIterator();
    00163                 typename DestIterator::column_iterator cd = id.columnIterator();
    00164                 for(y=0; y != hs; y++, cs--, cd++)
    00165                 {
    00166                     ad.set(as(cs), cd);
    00167                 }
    00168
    00169             }
    00170             break;
    00171
    00172         case 270:
    00173             is.y += (hs-1);
    00174             for(x=0; x != ws; x++, is.x++, id.y++)
    00175             {
    00176                 typename SrcIterator::column_iterator cs = is.columnIterator();
    00177                 typename DestIterator::row_iterator rd = id.rowIterator();
    00178                 for(y=0; y != hs; y++, cs--, rd++)
    00179                 {
    00180                     ad.set(as(cs), rd);
    00181                 }
    00182
    00183             }
    00184             break;
    00185         default: //not needful, because of the exception handig in if-statement
    00186             vigra_fail("internal error");
    00187     }
    00188 }
    00189
    00190 template <class SrcImageIterator, class SrcAccessor,
    00191           class DestImageIterator, class DestAccessor>
    00192 inline void
    00193 rotateImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00194               pair<DestImageIterator, DestAccessor> dest, int rotation)
    00195 {
    00196     rotateImage(src.first, src.second, src.third, dest.first, dest.second, rotation);
    00197 }
    00198
    00199 /********************************************************/
    00200 /*                                                      */
    00201 /*                     reflectImage                     */
    00202 /*                                                      */
    00203 /********************************************************/
    00204
    00205 enum Reflect{horizontal = 1, vertical = 2};
    00206
    00207 /** \brief Reflect image horizontally or vertically.
    00208
    00209     The reflection direction refers to the reflection axis, i.e.
    00210     horizontal reflection turns the image upside down, vertical reflection
    00211     changes left for right. The directions are selected by the enum values
    00212     <tt>vigra::horizontal</tt> and <tt>vigra::vertical</tt>. The two directions
    00213     can also be "or"ed together to perform both reflections simultaneously
    00214     (see example below) -- this is the same as a 180 degree rotation.
    00215
    00216     <b> Declarations:</b>
    00217
    00218     pass arguments explicitly:
    00219     \code
    00220     namespace vigra {
    00221         template <class SrcIterator, class SrcAccessor,
    00222                   class DestIterator, class DestAccessor>
    00223         void
    00224         reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
    00225                      DestIterator id, DestAccessor ad, Reflect axis);
    00226     }
    00227     \endcode
    00228
    00229     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00230     \code
    00231     namespace vigra {
    00232         template <class SrcImageIterator, class SrcAccessor,
    00233               class DestImageIterator, class DestAccessor>
    00234         inline void
    00235         reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00236                      pair<DestImageIterator, DestAccessor> dest, Reflect axis);
    00237     }
    00238     \endcode
    00239
    00240     <b> Usage:</b>
    00241
    00242         <b>\#include</b> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><br>
    00243         Namespace: vigra
    00244
    00245     \code
    00246     Image dest(src.width(), src.height());
    00247
    00248     vigra::reflectImage(srcImageRange(src), destImage(dest), vigra::horizontal | vigra::vertical);
    00249
    00250     \endcode
    00251
    00252     <b> Required Interface:</b>
    00253
    00254     \code
    00255     SrcImageIterator src_upperleft, src_lowerright;
    00256     DestImageIterator dest_upperleft;
    00257
    00258     SrcAccessor src_accessor;
    00259
    00260     dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
    00261
    00262     \endcode
    00263
    00264     <b> Preconditions:</b>
    00265
    00266     \code
    00267     src_lowerright.x - src_upperleft.x > 1
    00268     src_lowerright.y - src_upperleft.y > 1
    00269     \endcode
    00270
    00271 */
    00272 doxygen_overloaded_function(template <...> void reflectImage)
    00273
    00274 template <class SrcIterator, class SrcAccessor,
    00275           class DestIterator, class DestAccessor>
    00276 void reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
    00277                   DestIterator id, DestAccessor ad, Reflect reflect)
    00278 {
    00279
    00280     int ws = end.x - is.x;
    00281     int hs = end.y - is.y;
    00282
    00283     int x, y;
    00284
    00285     if(reflect == horizontal)
    00286     {//flipImage
    00287         is.y += (hs-1);
    00288         for(x=0; x<ws; ++x, ++is.x, ++id.x)
    00289         {
    00290             typename SrcIterator::column_iterator  cs = is.columnIterator();
    00291             typename DestIterator::column_iterator cd = id.columnIterator();
    00292             for(y=0; y!=hs;y++, cs--, cd++)
    00293             {
    00294                 ad.set(as(cs), cd);
    00295             }
    00296         }
    00297     }
    00298     else if(reflect == vertical)
    00299     {//flopImage
    00300         is.x += (ws-1);
    00301         for(x=0; x < ws; ++x, --is.x, ++id.x)
    00302         {
    00303
    00304             typename SrcIterator::column_iterator cs = is.columnIterator();
    00305             typename DestIterator::column_iterator cd = id.columnIterator();
    00306             for(y=0; y!=hs;y++, cs++, cd++)
    00307             {
    00308                 ad.set(as(cs), cd);
    00309             }
    00310         }
    00311     }
    00312     else if(reflect == (horizontal | vertical))
    00313     {//flipFlopImage   //???
    00314         end.x--;
    00315         end.y--;
    00316         for(x=0; x != ws; x++, end.x--, id.x++)
    00317         {
    00318             typename SrcIterator::column_iterator cs = end.columnIterator();
    00319             typename DestIterator::column_iterator cd = id.columnIterator();
    00320             for(y=0; y != hs; y++, cs--, cd++)
    00321             {
    00322                 ad.set(as(cs), cd);
    00323             }
    00324         }
    00325     }
    00326     else
    00327         vigra_fail("reflectImage(): "
    00328                    "This function reflects horizontal or vertical,"
    00329                    "   'and' is included");
    00330 }
    00331
    00332 template <class SrcImageIterator, class SrcAccessor,
    00333           class DestImageIterator, class DestAccessor>
    00334 inline void
    00335 reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00336               pair<DestImageIterator, DestAccessor> dest, Reflect reflect)
    00337 {
    00338     reflectImage(src.first, src.second, src.third, dest.first, dest.second, reflect);
    00339 }
    00340
    00341 /********************************************************/
    00342 /*                                                      */
    00343 /*                    transposeImage                   */
    00344 /*                                                      */
    00345 /********************************************************/
    00346
    00347 enum Transpose{major = 1, minor = 2};
    00348
    00349 /** \brief Transpose an image over the major or minor diagonal.
    00350
    00351     The transposition direction refers to the axis, i.e.
    00352     major transposition turns the upper right corner into the lower left one,
    00353     whereas minor transposition changes the upper left corner into the lower right one.
    00354     The directions are selected by the enum values
    00355     <tt>vigra::major</tt> and <tt>vigra::minor</tt>. The two directions
    00356     can also be "or"ed together to perform both reflections simultaneously
    00357     (see example below) -- this is the same as a 180 degree rotation.
    00358
    00359     <b> Declarations:</b>
    00360
    00361     pass arguments explicitly:
    00362     \code
    00363     namespace vigra {
    00364         template <class SrcIterator, class SrcAccessor,
    00365                   class DestIterator, class DestAccessor>
    00366         void
    00367         transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
    00368                        DestIterator id, DestAccessor ad, Transpose axis);
    00369     }
    00370     \endcode
    00371
    00372     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00373     \code
    00374     namespace vigra {
    00375         template <class SrcImageIterator, class SrcAccessor,
    00376               class DestImageIterator, class DestAccessor>
    00377         inline void
    00378         transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00379                        pair<DestImageIterator, DestAccessor> dest, Transpose axis);
    00380     }
    00381     \endcode
    00382
    00383     <b> Usage:</b>
    00384
    00385         <b>\#include</b> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><br>
    00386         Namespace: vigra
    00387
    00388     \code
    00389     Image dest(src.width(), src.height());
    00390
    00391     vigra::transposeImage(srcImageRange(src), destImage(dest), vigra::major | vigra::minor);
    00392
    00393     \endcode
    00394
    00395     <b> Required Interface:</b>
    00396
    00397     \code
    00398     SrcImageIterator src_upperleft, src_lowerright;
    00399     DestImageIterator dest_upperleft;
    00400
    00401     SrcAccessor src_accessor;
    00402
    00403     dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
    00404
    00405     \endcode
    00406
    00407     <b> Preconditions:</b>
    00408
    00409     \code
    00410     src_lowerright.x - src_upperleft.x > 1
    00411     src_lowerright.y - src_upperleft.y > 1
    00412     \endcode
    00413
    00414 */
    00415 doxygen_overloaded_function(template <...> void transposeImage)
    00416
    00417 template <class SrcIterator, class SrcAccessor,
    00418           class DestIterator, class DestAccessor>
    00419 void transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
    00420                     DestIterator id, DestAccessor ad, Transpose transpose)
    00421 {
    00422     int ws = end.x - is.x;
    00423     int hs = end.y - is.y;
    00424
    00425     int x, y;
    00426
    00427     if(transpose == major)
    00428     {//Die Funktion spiegelt das Bild um (0,0) (1,1) Diagonale
    00429         for(x=0; x != ws; x++, is.x++, id.y++)
    00430         {
    00431
    00432             typename SrcIterator::column_iterator cs = is.columnIterator();
    00433             typename DestIterator::row_iterator rd = id.rowIterator();
    00434             for(y=0; y != hs; y++, cs++, rd++)
    00435             {
    00436                 ad.set(as(cs), rd);
    00437             }
    00438         }
    00439     }
    00440     else if(transpose == minor)
    00441     {//Die Funktion spiegelt das Bild (1,0) (0,1) Diagonale
    00442         end.x--;
    00443         end.y--;
    00444         for(x=0; x != ws; x++, --end.x, ++id.y)
    00445         {
    00446
    00447             typename SrcIterator::column_iterator cs = end.columnIterator();
    00448             typename DestIterator::row_iterator rd = id.rowIterator();
    00449             for(y=0; y != hs; y++, --cs, ++rd)
    00450             {
    00451                 ad.set(as(cs), rd);
    00452             }
    00453         }
    00454     }
    00455     else if(transpose == (major | minor))
    00456     {//flipFlopImage  //???
    00457         end.x--;
    00458         end.y--;
    00459         for(x=0; x != ws; x++, end.x--, id.x++)
    00460         {
    00461             typename SrcIterator::column_iterator cs = end.columnIterator();
    00462             typename DestIterator::column_iterator cd = id.columnIterator();
    00463             for(y=0; y != hs; y++, cs--, cd++)
    00464             {
    00465                 ad.set(as(cs), cd);
    00466             }
    00467         }
    00468
    00469     }
    00470     else
    00471         vigra_fail("transposeImage(): "
    00472                    "This function transposes major or minor,"
    00473                    "   'and' is included");
    00474
    00475 }
    00476
    00477 template <class SrcImageIterator, class SrcAccessor,
    00478           class DestImageIterator, class DestAccessor>
    00479 inline void
    00480 transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00481               pair<DestImageIterator, DestAccessor> dest, Transpose transpose)
    00482 {
    00483     transposeImage(src.first, src.second, src.third, dest.first, dest.second, transpose);
    00484 }
    00485
    00486 /********************************************************/
    00487 /*                                                      */
    00488 /*                        resampleLine                  */
    00489 /*                                                      */
    00490 /********************************************************/
    00491
    00492 /*
    00493 * Vergroessert eine Linie um einen Faktor.
    00494 * Ist z.B. der Faktor = 4 so werden in der
    00495 * neuen Linie(Destination) jedes Pixel genau 4 mal
    00496 * vorkommen, also es findet auch keine Glaetung
    00497 * statt (NoInterpolation). Als Parameter sollen
    00498 * der Anfangs-, der Enditerator und der Accessor
    00499 * der Ausgangslinie (Source line), der Anfangsiterator
    00500 * und Accessor der Ziellinie (destination line) und
    00501 * anschliessend der Faktor um den die Linie (Zeile)
    00502 * vergroessert bzw. verkleinert werden soll.
    00503 */
    00504 template <class SrcIterator, class SrcAccessor,
    00505           class DestIterator, class DestAccessor>
    00506 void resampleLine(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
    00507                   DestIterator dest_iter, DestAccessor dest_acc, double factor)
    00508 {
    00509     // The width of the src line.
    00510     int src_width = src_iter_end - src_iter;
    00511
    00512     vigra_precondition(src_width > 0,
    00513                        "resampleLine(): input image too small.");
    00514     vigra_precondition(factor > 0.0,
    00515                        "resampleLine(): factor must be positive.");
    00516
    00517     if (factor >= 1.0)
    00518     {
    00519         int int_factor = (int)factor;
    00520         double dx = factor - int_factor;
    00521         double saver = dx;
    00522         for ( ; src_iter != src_iter_end ; ++src_iter, saver += dx)
    00523         {
    00524             if (saver >= 1.0)
    00525             {
    00526                 saver = saver - (int)saver;
    00527                 dest_acc.set(src_acc(src_iter), dest_iter);
    00528                 ++dest_iter;
    00529             }
    00530             for(int i = 0 ; i < int_factor ; i++, ++dest_iter)
    00531             {
    00532                 dest_acc.set(src_acc(src_iter), dest_iter);
    00533             }
    00534         }
    00535     }
    00536     else
    00537     {
    00538         DestIterator dest_end = dest_iter + (int)VIGRA_CSTD::ceil(src_width*factor);
    00539         factor = 1.0/factor;
    00540         int int_factor = (int)factor;
    00541         double dx = factor - int_factor;
    00542         double saver = dx;
    00543         src_iter_end -= 1;
    00544         for ( ; src_iter != src_iter_end && dest_iter != dest_end ;
    00545               ++dest_iter, src_iter += int_factor, saver += dx)
    00546         {
    00547             if (saver >= 1.0)
    00548             {
    00549                 saver = saver - (int)saver;
    00550                 ++src_iter;
    00551             }
    00552             dest_acc.set(src_acc(src_iter), dest_iter);
    00553         }
    00554         if (dest_iter != dest_end)
    00555         {
    00556             dest_acc.set(src_acc(src_iter_end), dest_iter);
    00557         }
    00558     }
    00559 }
    00560
    00561 inline int sizeForResamplingFactor(int oldsize, double factor)
    00562 {
    00563     return (factor < 1.0)
    00564         ? (int)VIGRA_CSTD::ceil(oldsize * factor)
    00565         : (int)(oldsize * factor);
    00566 }
    00567
    00568
    00569 /********************************************************/
    00570 /*                                                      */
    00571 /*                     resampleImage                    */
    00572 /*                                                      */
    00573 /********************************************************/
    00574
    00575 /** \brief Resample image by a given factor.
    00576
    00577     This algorithm is very fast and does not require any arithmetic on the pixel types.
    00578     The input image must have a size of at
    00579     least 2x2. Destiniation pixels are directly copied from the appropriate
    00580     source pixels. The size of the result image is the product of <tt>factor</tt>
    00581     and the original size, where we round up if <tt>factor < 1.0</tt> and down otherwise.
    00582     This size calculation is the main difference to the convention used in the similar
    00583     function \ref resizeImageNoInterpolation():
    00584     there, the result size is calculated as <tt>n*(old_width-1)+1</tt> and
    00585     <tt>n*(old_height-1)+1</tt>. This is because \ref resizeImageNoInterpolation()
    00586     does not replicate the last pixel in every row/column in order to make it compatible
    00587     with the other functions of the <tt>resizeImage...</tt> family.
    00588
    00589     It should also be noted that resampleImage() is implemented so that an enlargement followed
    00590     by the corresponding shrinking reproduces the original image. The function uses accessors.
    00591
    00592     <b> Declarations:</b>
    00593
    00594     pass arguments explicitly:
    00595     \code
    00596     namespace vigra {
    00597         template <class SrcIterator, class SrcAccessor,
    00598                   class DestIterator, class DestAccessor>
    00599         void
    00600         resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
    00601                       DestIterator id, DestAccessor ad, double factor);
    00602     }
    00603     \endcode
    00604
    00605     use argument objects in conjunction with \ref ArgumentObjectFactories :
    00606     \code
    00607     namespace vigra {
    00608         template <class SrcImageIterator, class SrcAccessor,
    00609               class DestImageIterator, class DestAccessor>
    00610         inline void
    00611         resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00612                       pair<DestImageIterator, DestAccessor> dest, double factor);
    00613     }
    00614     \endcode
    00615
    00616     <b> Usage:</b>
    00617
    00618         <b>\#include</b> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><br>
    00619         Namespace: vigra
    00620
    00621     \code
    00622     double factor = 2.0;
    00623     Image dest((int)(factor*src.width()), (int)(factor*src.height()));
    00624
    00625     vigra::resampleImage(srcImageRange(src), destImage(dest), factor);
    00626
    00627     \endcode
    00628
    00629     <b> Required Interface:</b>
    00630
    00631     \code
    00632     SrcImageIterator src_upperleft, src_lowerright;
    00633     DestImageIterator dest_upperleft;
    00634
    00635     SrcAccessor src_accessor;
    00636
    00637     dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
    00638
    00639     \endcode
    00640
    00641     <b> Preconditions:</b>
    00642
    00643     \code
    00644     src_lowerright.x - src_upperleft.x > 1
    00645     src_lowerright.y - src_upperleft.y > 1
    00646     \endcode
    00647
    00648 */
    00649 doxygen_overloaded_function(template <...> void resampleImage)
    00650
    00651 template <class SrcIterator, class SrcAccessor,
    00652           class DestIterator, class DestAccessor>
    00653 void
    00654 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
    00655               DestIterator id, DestAccessor ad, double factor)
    00656 {
    00657     int width_old = iend.x - is.x;
    00658     int height_old = iend.y - is.y;
    00659
    00660     //Bei Verkleinerung muss das dest-Bild ceiling(src*factor), da z.B.
    00661     //aus 6x6 grossem Bild wird eins 18x18 grosses gemacht bei Vergroesserungsfaktor 3.1
    00662     //umgekehrt damit wir vom 18x18 zu 6x6 (und nicht 5x5) bei Vergroesserung von 1/3.1
    00663     //muss das kleinste Integer das groesser als 18/3.1 ist genommen werden.
    00664     int height_new = sizeForResamplingFactor(height_old, factor);
    00665     int width_new = sizeForResamplingFactor(width_old, factor);
    00666
    00667     vigra_precondition((width_old > 1) && (height_old > 1),
    00668                  "resampleImage(): "
    00669                  "Source image to small.\n");
    00670     vigra_precondition((width_new > 1) && (height_new > 1),
    00671                  "resampleImage(): "
    00672                  "Destination image to small.\n");
    00673
    00674     typedef typename SrcAccessor::value_type SRCVT;
    00675     typedef BasicImage<SRCVT> TmpImage;
    00676     typedef typename TmpImage::traverser TmpImageIterator;
    00677
    00678     BasicImage<SRCVT> tmp(width_old, height_new);
    00679
    00680     int x,y;
    00681
    00682     typename BasicImage<SRCVT>::Iterator yt = tmp.upperLeft();
    00683
    00684     for(x=0; x<width_old; ++x, ++is.x, ++yt.x)
    00685     {
    00686         typename SrcIterator::column_iterator c1 = is.columnIterator();
    00687         typename TmpImageIterator::column_iterator ct = yt.columnIterator();
    00688         resampleLine(c1, c1 + height_old, sa, ct, tmp.accessor(), factor);
    00689     }
    00690
    00691     yt = tmp.upperLeft();
    00692
    00693     for(y=0; y < height_new; ++y, ++yt.y, ++id.y)
    00694     {
    00695         typename DestIterator::row_iterator rd = id.rowIterator();
    00696         typename TmpImageIterator::row_iterator rt = yt.rowIterator();
    00697         resampleLine(rt, rt + width_old, tmp.accessor(), rd, ad, factor);
    00698     }
    00699
    00700 }
    00701
    00702 template <class SrcImageIterator, class SrcAccessor,
    00703           class DestImageIterator, class DestAccessor>
    00704 inline void
    00705 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
    00706               pair<DestImageIterator, DestAccessor> dest, double factor)
    00707 {
    00708     resampleImage(src.first, src.second, src.third, dest.first, dest.second, factor);
    00709 }
    00710
    00711 //@}
    00712
    00713 } // namespace vigra
    00714
    00715
    00716 #endif /* VIGRA_BASICGEOMETRY_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.6.0 (13 Aug 2008)