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