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

details vigra/basicgeometry.hxx VIGRA

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)