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

© Ullrich Köthe (koethe@informatik.uni-hamburg.de)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.5.0 (7 Dec 2006)