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