[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
vigra/basicgeometry.hxx | ![]() |
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2002 by Ullrich Koethe */ 00004 /* */ 00005 /* This file is part of the VIGRA computer vision library. */ 00006 /* The VIGRA Website is */ 00007 /* http://hci.iwr.uni-heidelberg.de/vigra/ */ 00008 /* Please direct questions, bug reports, and contributions to */ 00009 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00010 /* vigra@informatik.uni-hamburg.de */ 00011 /* */ 00012 /* Permission is hereby granted, free of charge, to any person */ 00013 /* obtaining a copy of this software and associated documentation */ 00014 /* files (the "Software"), to deal in the Software without */ 00015 /* restriction, including without limitation the rights to use, */ 00016 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00017 /* sell copies of the Software, and to permit persons to whom the */ 00018 /* Software is furnished to do so, subject to the following */ 00019 /* conditions: */ 00020 /* */ 00021 /* The above copyright notice and this permission notice shall be */ 00022 /* included in all copies or substantial portions of the */ 00023 /* Software. */ 00024 /* */ 00025 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00026 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00027 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00028 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00029 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00030 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00031 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00032 /* OTHER DEALINGS IN THE SOFTWARE. */ 00033 /* */ 00034 /************************************************************************/ 00035 00036 #ifndef VIGRA_BASICGEOMETRY_HXX 00037 #define VIGRA_BASICGEOMETRY_HXX 00038 00039 #include "error.hxx" 00040 #include "stdimage.hxx" 00041 #include "copyimage.hxx" 00042 #include <cmath> 00043 00044 namespace vigra { 00045 00046 /** \addtogroup GeometricTransformations Geometric Transformations 00047 */ 00048 //@{ 00049 00050 /********************************************************/ 00051 /* */ 00052 /* rotateImage */ 00053 /* */ 00054 /********************************************************/ 00055 00056 /** \brief Rotate image by a multiple of 90 degrees. 00057 00058 This algorithm just copies the pixels in the appropriate new order. It expects the 00059 destination image to have the correct shape for the desired rotation. 00060 00061 <b> Declarations:</b> 00062 00063 pass arguments explicitly: 00064 \code 00065 namespace vigra { 00066 template <class SrcIterator, class SrcAccessor, 00067 class DestIterator, class DestAccessor> 00068 void 00069 rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as, 00070 DestIterator id, DestAccessor ad, int rotation); 00071 } 00072 \endcode 00073 00074 use argument objects in conjunction with \ref ArgumentObjectFactories : 00075 \code 00076 namespace vigra { 00077 template <class SrcImageIterator, class SrcAccessor, 00078 class DestImageIterator, class DestAccessor> 00079 inline void 00080 rotateImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00081 pair<DestImageIterator, DestAccessor> dest, int rotation); 00082 } 00083 \endcode 00084 00085 <b> Usage:</b> 00086 00087 <b>\#include</b> <vigra/basicgeometry.hxx><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 inline 00206 Reflect operator|(Reflect l, Reflect r) 00207 { 00208 return Reflect((unsigned int)l | (unsigned int)r); 00209 } 00210 00211 /** \brief Reflect image horizontally or vertically. 00212 00213 The reflection direction refers to the reflection axis, i.e. 00214 horizontal reflection turns the image upside down, vertical reflection 00215 changes left for right. The directions are selected by the enum values 00216 <tt>vigra::horizontal</tt> and <tt>vigra::vertical</tt>. The two directions 00217 can also be "or"ed together to perform both reflections simultaneously 00218 (see example below) -- this is the same as a 180 degree rotation. 00219 00220 <b> Declarations:</b> 00221 00222 pass arguments explicitly: 00223 \code 00224 namespace vigra { 00225 template <class SrcIterator, class SrcAccessor, 00226 class DestIterator, class DestAccessor> 00227 void 00228 reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as, 00229 DestIterator id, DestAccessor ad, Reflect axis); 00230 } 00231 \endcode 00232 00233 use argument objects in conjunction with \ref ArgumentObjectFactories : 00234 \code 00235 namespace vigra { 00236 template <class SrcImageIterator, class SrcAccessor, 00237 class DestImageIterator, class DestAccessor> 00238 inline void 00239 reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00240 pair<DestImageIterator, DestAccessor> dest, Reflect axis); 00241 } 00242 \endcode 00243 00244 <b> Usage:</b> 00245 00246 <b>\#include</b> <vigra/basicgeometry.hxx><br> 00247 Namespace: vigra 00248 00249 \code 00250 Image dest(src.width(), src.height()); 00251 00252 vigra::reflectImage(srcImageRange(src), destImage(dest), vigra::horizontal | vigra::vertical); 00253 00254 \endcode 00255 00256 <b> Required Interface:</b> 00257 00258 \code 00259 SrcImageIterator src_upperleft, src_lowerright; 00260 DestImageIterator dest_upperleft; 00261 00262 SrcAccessor src_accessor; 00263 00264 dest_accessor.set(src_accessor(src_upperleft), dest_upperleft); 00265 00266 \endcode 00267 00268 <b> Preconditions:</b> 00269 00270 \code 00271 src_lowerright.x - src_upperleft.x > 1 00272 src_lowerright.y - src_upperleft.y > 1 00273 \endcode 00274 00275 */ 00276 doxygen_overloaded_function(template <...> void reflectImage) 00277 00278 template <class SrcIterator, class SrcAccessor, 00279 class DestIterator, class DestAccessor> 00280 void reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as, 00281 DestIterator id, DestAccessor ad, Reflect reflect) 00282 { 00283 00284 int ws = end.x - is.x; 00285 int hs = end.y - is.y; 00286 00287 int x, y; 00288 00289 if(reflect == horizontal) 00290 {//flipImage 00291 is.y += (hs-1); 00292 for(x=0; x<ws; ++x, ++is.x, ++id.x) 00293 { 00294 typename SrcIterator::column_iterator cs = is.columnIterator(); 00295 typename DestIterator::column_iterator cd = id.columnIterator(); 00296 for(y=0; y!=hs;y++, cs--, cd++) 00297 { 00298 ad.set(as(cs), cd); 00299 } 00300 } 00301 } 00302 else if(reflect == vertical) 00303 {//flopImage 00304 is.x += (ws-1); 00305 for(x=0; x < ws; ++x, --is.x, ++id.x) 00306 { 00307 00308 typename SrcIterator::column_iterator cs = is.columnIterator(); 00309 typename DestIterator::column_iterator cd = id.columnIterator(); 00310 for(y=0; y!=hs;y++, cs++, cd++) 00311 { 00312 ad.set(as(cs), cd); 00313 } 00314 } 00315 } 00316 else if(reflect == (horizontal | vertical)) 00317 {//flipFlopImage //??? 00318 end.x--; 00319 end.y--; 00320 for(x=0; x != ws; x++, end.x--, id.x++) 00321 { 00322 typename SrcIterator::column_iterator cs = end.columnIterator(); 00323 typename DestIterator::column_iterator cd = id.columnIterator(); 00324 for(y=0; y != hs; y++, cs--, cd++) 00325 { 00326 ad.set(as(cs), cd); 00327 } 00328 } 00329 } 00330 else 00331 vigra_fail("reflectImage(): " 00332 "This function reflects horizontal or vertical," 00333 " 'and' is included"); 00334 } 00335 00336 template <class SrcImageIterator, class SrcAccessor, 00337 class DestImageIterator, class DestAccessor> 00338 inline void 00339 reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00340 pair<DestImageIterator, DestAccessor> dest, Reflect reflect) 00341 { 00342 reflectImage(src.first, src.second, src.third, dest.first, dest.second, reflect); 00343 } 00344 00345 /********************************************************/ 00346 /* */ 00347 /* transposeImage */ 00348 /* */ 00349 /********************************************************/ 00350 00351 // names clash with sys/types.h on Mac OS / Darwin, see docs below 00352 enum Transpose{major = 1, minor = 2}; 00353 00354 /** \brief Transpose an image over the major or minor diagonal. 00355 00356 The transposition direction refers to the axis, i.e. 00357 major transposition turns the upper right corner into the lower left one, 00358 whereas minor transposition changes the upper left corner into the lower right one. 00359 The directions are selected by the enum values 00360 <tt>vigra::major</tt> and <tt>vigra::minor</tt>. The two directions 00361 can also be "or"ed together to perform both reflections simultaneously 00362 (see example below) -- this is the same as a 180 degree rotation. 00363 (Caution: When doing multi-platform development, you should be 00364 aware that some <sys/types.h> define major/minor, too. Do not omit 00365 the vigra namespace prefix.) 00366 00367 <b> Declarations:</b> 00368 00369 pass arguments explicitly: 00370 \code 00371 namespace vigra { 00372 template <class SrcIterator, class SrcAccessor, 00373 class DestIterator, class DestAccessor> 00374 void 00375 transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as, 00376 DestIterator id, DestAccessor ad, Transpose axis); 00377 } 00378 \endcode 00379 00380 use argument objects in conjunction with \ref ArgumentObjectFactories : 00381 \code 00382 namespace vigra { 00383 template <class SrcImageIterator, class SrcAccessor, 00384 class DestImageIterator, class DestAccessor> 00385 inline void 00386 transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00387 pair<DestImageIterator, DestAccessor> dest, Transpose axis); 00388 } 00389 \endcode 00390 00391 <b> Usage:</b> 00392 00393 <b>\#include</b> <vigra/basicgeometry.hxx><br> 00394 Namespace: vigra 00395 00396 \code 00397 Image dest(src.width(), src.height()); 00398 00399 vigra::transposeImage(srcImageRange(src), destImage(dest), vigra::major | vigra::minor); 00400 00401 \endcode 00402 00403 <b> Required Interface:</b> 00404 00405 \code 00406 SrcImageIterator src_upperleft, src_lowerright; 00407 DestImageIterator dest_upperleft; 00408 00409 SrcAccessor src_accessor; 00410 00411 dest_accessor.set(src_accessor(src_upperleft), dest_upperleft); 00412 00413 \endcode 00414 00415 <b> Preconditions:</b> 00416 00417 \code 00418 src_lowerright.x - src_upperleft.x > 1 00419 src_lowerright.y - src_upperleft.y > 1 00420 \endcode 00421 00422 */ 00423 doxygen_overloaded_function(template <...> void transposeImage) 00424 00425 template <class SrcIterator, class SrcAccessor, 00426 class DestIterator, class DestAccessor> 00427 void transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as, 00428 DestIterator id, DestAccessor ad, Transpose transpose) 00429 { 00430 int ws = end.x - is.x; 00431 int hs = end.y - is.y; 00432 00433 int x, y; 00434 00435 if(transpose == major) 00436 {//Die Funktion spiegelt das Bild um (0,0) (1,1) Diagonale 00437 for(x=0; x != ws; x++, is.x++, id.y++) 00438 { 00439 00440 typename SrcIterator::column_iterator cs = is.columnIterator(); 00441 typename DestIterator::row_iterator rd = id.rowIterator(); 00442 for(y=0; y != hs; y++, cs++, rd++) 00443 { 00444 ad.set(as(cs), rd); 00445 } 00446 } 00447 } 00448 else if(transpose == minor) 00449 {//Die Funktion spiegelt das Bild (1,0) (0,1) Diagonale 00450 end.x--; 00451 end.y--; 00452 for(x=0; x != ws; x++, --end.x, ++id.y) 00453 { 00454 00455 typename SrcIterator::column_iterator cs = end.columnIterator(); 00456 typename DestIterator::row_iterator rd = id.rowIterator(); 00457 for(y=0; y != hs; y++, --cs, ++rd) 00458 { 00459 ad.set(as(cs), rd); 00460 } 00461 } 00462 } 00463 else if(transpose == (major | minor)) 00464 {//flipFlopImage //??? 00465 end.x--; 00466 end.y--; 00467 for(x=0; x != ws; x++, end.x--, id.x++) 00468 { 00469 typename SrcIterator::column_iterator cs = end.columnIterator(); 00470 typename DestIterator::column_iterator cd = id.columnIterator(); 00471 for(y=0; y != hs; y++, cs--, cd++) 00472 { 00473 ad.set(as(cs), cd); 00474 } 00475 } 00476 00477 } 00478 else 00479 vigra_fail("transposeImage(): " 00480 "This function transposes major or minor," 00481 " 'and' is included"); 00482 00483 } 00484 00485 template <class SrcImageIterator, class SrcAccessor, 00486 class DestImageIterator, class DestAccessor> 00487 inline void 00488 transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00489 pair<DestImageIterator, DestAccessor> dest, Transpose transpose) 00490 { 00491 transposeImage(src.first, src.second, src.third, dest.first, dest.second, transpose); 00492 } 00493 00494 /********************************************************/ 00495 /* */ 00496 /* resampleLine */ 00497 /* */ 00498 /********************************************************/ 00499 00500 /* 00501 * Vergroessert eine Linie um einen Faktor. 00502 * Ist z.B. der Faktor = 4 so werden in der 00503 * neuen Linie(Destination) jedes Pixel genau 4 mal 00504 * vorkommen, also es findet auch keine Glaetung 00505 * statt (NoInterpolation). Als Parameter sollen 00506 * der Anfangs-, der Enditerator und der Accessor 00507 * der Ausgangslinie (Source line), der Anfangsiterator 00508 * und Accessor der Ziellinie (destination line) und 00509 * anschliessend der Faktor um den die Linie (Zeile) 00510 * vergroessert bzw. verkleinert werden soll. 00511 */ 00512 template <class SrcIterator, class SrcAccessor, 00513 class DestIterator, class DestAccessor> 00514 void resampleLine(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc, 00515 DestIterator dest_iter, DestAccessor dest_acc, double factor) 00516 { 00517 // The width of the src line. 00518 int src_width = src_iter_end - src_iter; 00519 00520 vigra_precondition(src_width > 0, 00521 "resampleLine(): input image too small."); 00522 vigra_precondition(factor > 0.0, 00523 "resampleLine(): factor must be positive."); 00524 00525 if (factor >= 1.0) 00526 { 00527 int int_factor = (int)factor; 00528 double dx = factor - int_factor; 00529 double saver = dx; 00530 for ( ; src_iter != src_iter_end ; ++src_iter, saver += dx) 00531 { 00532 if (saver >= 1.0) 00533 { 00534 saver = saver - (int)saver; 00535 dest_acc.set(src_acc(src_iter), dest_iter); 00536 ++dest_iter; 00537 } 00538 for(int i = 0 ; i < int_factor ; i++, ++dest_iter) 00539 { 00540 dest_acc.set(src_acc(src_iter), dest_iter); 00541 } 00542 } 00543 } 00544 else 00545 { 00546 DestIterator dest_end = dest_iter + (int)VIGRA_CSTD::ceil(src_width*factor); 00547 factor = 1.0/factor; 00548 int int_factor = (int)factor; 00549 double dx = factor - int_factor; 00550 double saver = dx; 00551 src_iter_end -= 1; 00552 for ( ; src_iter != src_iter_end && dest_iter != dest_end ; 00553 ++dest_iter, src_iter += int_factor, saver += dx) 00554 { 00555 if (saver >= 1.0) 00556 { 00557 saver = saver - (int)saver; 00558 ++src_iter; 00559 } 00560 dest_acc.set(src_acc(src_iter), dest_iter); 00561 } 00562 if (dest_iter != dest_end) 00563 { 00564 dest_acc.set(src_acc(src_iter_end), dest_iter); 00565 } 00566 } 00567 } 00568 00569 inline int sizeForResamplingFactor(int oldsize, double factor) 00570 { 00571 return (factor < 1.0) 00572 ? (int)VIGRA_CSTD::ceil(oldsize * factor) 00573 : (int)(oldsize * factor); 00574 } 00575 00576 00577 /********************************************************/ 00578 /* */ 00579 /* resampleImage */ 00580 /* */ 00581 /********************************************************/ 00582 00583 /** \brief Resample image by a given factor. 00584 00585 This algorithm is very fast and does not require any arithmetic on the pixel types. 00586 The input image must have a size of at 00587 least 2x2. Destiniation pixels are directly copied from the appropriate 00588 source pixels. The size of the result image is the product of <tt>factor</tt> 00589 and the original size, where we round up if <tt>factor < 1.0</tt> and down otherwise. 00590 This size calculation is the main difference to the convention used in the similar 00591 function \ref resizeImageNoInterpolation(): 00592 there, the result size is calculated as <tt>n*(old_width-1)+1</tt> and 00593 <tt>n*(old_height-1)+1</tt>. This is because \ref resizeImageNoInterpolation() 00594 does not replicate the last pixel in every row/column in order to make it compatible 00595 with the other functions of the <tt>resizeImage...</tt> family. 00596 00597 The function can be called with different resampling factors for x and y, or 00598 with a single factor to be used for both directions. 00599 00600 It should also be noted that resampleImage() is implemented so that an enlargement followed 00601 by the corresponding shrinking reproduces the original image. The function uses accessors. 00602 00603 <b> Declarations:</b> 00604 00605 pass arguments explicitly: 00606 \code 00607 namespace vigra { 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 factor); 00613 00614 template <class SrcIterator, class SrcAccessor, 00615 class DestIterator, class DestAccessor> 00616 void 00617 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa, 00618 DestIterator id, DestAccessor ad, double xfactor, double yfactor); 00619 } 00620 \endcode 00621 00622 use argument objects in conjunction with \ref ArgumentObjectFactories : 00623 \code 00624 namespace vigra { 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 factor); 00630 00631 template <class SrcImageIterator, class SrcAccessor, 00632 class DestImageIterator, class DestAccessor> 00633 inline void 00634 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00635 pair<DestImageIterator, DestAccessor> dest, double xfactor, double yfactor); 00636 } 00637 \endcode 00638 00639 <b> Usage:</b> 00640 00641 <b>\#include</b> <vigra/basicgeometry.hxx><br> 00642 Namespace: vigra 00643 00644 \code 00645 double factor = 2.0; 00646 Image dest((int)(factor*src.width()), (int)(factor*src.height())); 00647 00648 vigra::resampleImage(srcImageRange(src), destImage(dest), factor); 00649 00650 \endcode 00651 00652 <b> Required Interface:</b> 00653 00654 \code 00655 SrcImageIterator src_upperleft, src_lowerright; 00656 DestImageIterator dest_upperleft; 00657 00658 SrcAccessor src_accessor; 00659 00660 dest_accessor.set(src_accessor(src_upperleft), dest_upperleft); 00661 00662 \endcode 00663 00664 <b> Preconditions:</b> 00665 00666 \code 00667 src_lowerright.x - src_upperleft.x > 1 00668 src_lowerright.y - src_upperleft.y > 1 00669 \endcode 00670 00671 */ 00672 doxygen_overloaded_function(template <...> void resampleImage) 00673 00674 template <class SrcIterator, class SrcAccessor, 00675 class DestIterator, class DestAccessor> 00676 void 00677 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa, 00678 DestIterator id, DestAccessor ad, double xfactor, double yfactor) 00679 { 00680 int width_old = iend.x - is.x; 00681 int height_old = iend.y - is.y; 00682 00683 //Bei Verkleinerung muss das dest-Bild ceiling(src*factor), da z.B. 00684 //aus 6x6 grossem Bild wird eins 18x18 grosses gemacht bei Vergroesserungsfaktor 3.1 00685 //umgekehrt damit wir vom 18x18 zu 6x6 (und nicht 5x5) bei Vergroesserung von 1/3.1 00686 //muss das kleinste Integer das groesser als 18/3.1 ist genommen werden. 00687 int height_new = sizeForResamplingFactor(height_old, yfactor); 00688 int width_new = sizeForResamplingFactor(width_old, xfactor); 00689 00690 vigra_precondition((width_old > 1) && (height_old > 1), 00691 "resampleImage(): " 00692 "Source image too small.\n"); 00693 vigra_precondition((width_new > 1) && (height_new > 1), 00694 "resampleImage(): " 00695 "Destination image too small.\n"); 00696 00697 typedef typename SrcAccessor::value_type SRCVT; 00698 typedef BasicImage<SRCVT> TmpImage; 00699 typedef typename TmpImage::traverser TmpImageIterator; 00700 00701 BasicImage<SRCVT> tmp(width_old, height_new); 00702 00703 int x,y; 00704 00705 typename BasicImage<SRCVT>::Iterator yt = tmp.upperLeft(); 00706 00707 for(x=0; x<width_old; ++x, ++is.x, ++yt.x) 00708 { 00709 typename SrcIterator::column_iterator c1 = is.columnIterator(); 00710 typename TmpImageIterator::column_iterator ct = yt.columnIterator(); 00711 resampleLine(c1, c1 + height_old, sa, ct, tmp.accessor(), yfactor); 00712 } 00713 00714 yt = tmp.upperLeft(); 00715 00716 for(y=0; y < height_new; ++y, ++yt.y, ++id.y) 00717 { 00718 typename DestIterator::row_iterator rd = id.rowIterator(); 00719 typename TmpImageIterator::row_iterator rt = yt.rowIterator(); 00720 resampleLine(rt, rt + width_old, tmp.accessor(), rd, ad, xfactor); 00721 } 00722 00723 } 00724 00725 template <class SrcIterator, class SrcAccessor, 00726 class DestIterator, class DestAccessor> 00727 void 00728 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa, 00729 DestIterator id, DestAccessor ad, double factor) 00730 { 00731 resampleImage(is, iend, sa, id, ad, factor, factor); 00732 } 00733 00734 template <class SrcImageIterator, class SrcAccessor, 00735 class DestImageIterator, class DestAccessor> 00736 inline void 00737 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00738 pair<DestImageIterator, DestAccessor> dest, double factor) 00739 { 00740 resampleImage(src.first, src.second, src.third, dest.first, dest.second, factor); 00741 } 00742 00743 template <class SrcImageIterator, class SrcAccessor, 00744 class DestImageIterator, class DestAccessor> 00745 inline void 00746 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00747 pair<DestImageIterator, DestAccessor> dest, double xfactor, double yfactor) 00748 { 00749 resampleImage(src.first, src.second, src.third, dest.first, dest.second, xfactor, yfactor); 00750 } 00751 00752 //@} 00753 00754 } // namespace vigra 00755 00756 00757 #endif /* VIGRA_BASICGEOMETRY_HXX */
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|