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

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