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