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