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

vigra/basicgeometry.hxx |

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