[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
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) |
html generated using doxygen and Python
|