[ 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 enum Transpose{major = 1, minor = 2}; 00346 00347 /** \brief Transpose an image over the major or minor diagonal. 00348 00349 The transposition direction refers to the axis, i.e. 00350 major transposition turns the upper right corner into the lower left one, 00351 whereas minor transposition changes the upper left corner into the lower right one. 00352 The directions are selected by the enum values 00353 <tt>vigra::major</tt> and <tt>vigra::minor</tt>. The two directions 00354 can also be "or"ed together to perform both reflections simultaneously 00355 (see example below) -- this is the same as a 180 degree rotation. 00356 00357 <b> Declarations:</b> 00358 00359 pass arguments explicitly: 00360 \code 00361 namespace vigra { 00362 template <class SrcIterator, class SrcAccessor, 00363 class DestIterator, class DestAccessor> 00364 void 00365 transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as, 00366 DestIterator id, DestAccessor ad, Transpose axis); 00367 } 00368 \endcode 00369 00370 use argument objects in conjunction with \ref ArgumentObjectFactories : 00371 \code 00372 namespace vigra { 00373 template <class SrcImageIterator, class SrcAccessor, 00374 class DestImageIterator, class DestAccessor> 00375 inline void 00376 transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00377 pair<DestImageIterator, DestAccessor> dest, Transpose axis); 00378 } 00379 \endcode 00380 00381 <b> Usage:</b> 00382 00383 <b>\#include</b> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><br> 00384 Namespace: vigra 00385 00386 \code 00387 Image dest(src.width(), src.height()); 00388 00389 vigra::transposeImage(srcImageRange(src), destImage(dest), vigra::major | vigra::minor); 00390 00391 \endcode 00392 00393 <b> Required Interface:</b> 00394 00395 \code 00396 SrcImageIterator src_upperleft, src_lowerright; 00397 DestImageIterator dest_upperleft; 00398 00399 SrcAccessor src_accessor; 00400 00401 dest_accessor.set(src_accessor(src_upperleft), dest_upperleft); 00402 00403 \endcode 00404 00405 <b> Preconditions:</b> 00406 00407 \code 00408 src_lowerright.x - src_upperleft.x > 1 00409 src_lowerright.y - src_upperleft.y > 1 00410 \endcode 00411 00412 */ 00413 doxygen_overloaded_function(template <...> void transposeImage) 00414 00415 template <class SrcIterator, class SrcAccessor, 00416 class DestIterator, class DestAccessor> 00417 void transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as, 00418 DestIterator id, DestAccessor ad, Transpose transpose) 00419 { 00420 int ws = end.x - is.x; 00421 int hs = end.y - is.y; 00422 00423 int x, y; 00424 00425 if(transpose == major) 00426 {//Die Funktion spiegelt das Bild um (0,0) (1,1) Diagonale 00427 for(x=0; x != ws; x++, is.x++, id.y++) 00428 { 00429 00430 typename SrcIterator::column_iterator cs = is.columnIterator(); 00431 typename DestIterator::row_iterator rd = id.rowIterator(); 00432 for(y=0; y != hs; y++, cs++, rd++) 00433 { 00434 ad.set(as(cs), rd); 00435 } 00436 } 00437 } 00438 else if(transpose == minor) 00439 {//Die Funktion spiegelt das Bild (1,0) (0,1) Diagonale 00440 end.x--; 00441 end.y--; 00442 for(x=0; x != ws; x++, --end.x, ++id.y) 00443 { 00444 00445 typename SrcIterator::column_iterator cs = end.columnIterator(); 00446 typename DestIterator::row_iterator rd = id.rowIterator(); 00447 for(y=0; y != hs; y++, --cs, ++rd) 00448 { 00449 ad.set(as(cs), rd); 00450 } 00451 } 00452 } 00453 else if(transpose == (major | minor)) 00454 {//flipFlopImage //??? 00455 end.x--; 00456 end.y--; 00457 for(x=0; x != ws; x++, end.x--, id.x++) 00458 { 00459 typename SrcIterator::column_iterator cs = end.columnIterator(); 00460 typename DestIterator::column_iterator cd = id.columnIterator(); 00461 for(y=0; y != hs; y++, cs--, cd++) 00462 { 00463 ad.set(as(cs), cd); 00464 } 00465 } 00466 00467 } 00468 else 00469 vigra_fail("transposeImage(): " 00470 "This function transposes major or minor," 00471 " 'and' is included"); 00472 00473 } 00474 00475 template <class SrcImageIterator, class SrcAccessor, 00476 class DestImageIterator, class DestAccessor> 00477 inline void 00478 transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00479 pair<DestImageIterator, DestAccessor> dest, Transpose transpose) 00480 { 00481 transposeImage(src.first, src.second, src.third, dest.first, dest.second, transpose); 00482 } 00483 00484 /********************************************************/ 00485 /* */ 00486 /* resampleLine */ 00487 /* */ 00488 /********************************************************/ 00489 00490 /* 00491 * Vergroessert eine Linie um einen Faktor. 00492 * Ist z.B. der Faktor = 4 so werden in der 00493 * neuen Linie(Destination) jedes Pixel genau 4 mal 00494 * vorkommen, also es findet auch keine Glaetung 00495 * statt (NoInterpolation). Als Parameter sollen 00496 * der Anfangs-, der Enditerator und der Accessor 00497 * der Ausgangslinie (Source line), der Anfangsiterator 00498 * und Accessor der Ziellinie (destination line) und 00499 * anschliessend der Faktor um den die Linie (Zeile) 00500 * vergroessert bzw. verkleinert werden soll. 00501 */ 00502 template <class SrcIterator, class SrcAccessor, 00503 class DestIterator, class DestAccessor> 00504 void resampleLine(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc, 00505 DestIterator dest_iter, DestAccessor dest_acc, double factor) 00506 { 00507 // The width of the src line. 00508 int src_width = src_iter_end - src_iter; 00509 00510 vigra_precondition(src_width > 0, 00511 "resampleLine(): input image too small."); 00512 vigra_precondition(factor > 0.0, 00513 "resampleLine(): factor must be positive."); 00514 00515 if (factor >= 1.0) 00516 { 00517 int int_factor = (int)factor; 00518 double dx = factor - int_factor; 00519 double saver = dx; 00520 for ( ; src_iter != src_iter_end ; ++src_iter, saver += dx) 00521 { 00522 if (saver >= 1.0) 00523 { 00524 saver = saver - (int)saver; 00525 dest_acc.set(src_acc(src_iter), dest_iter); 00526 ++dest_iter; 00527 } 00528 for(int i = 0 ; i < int_factor ; i++, ++dest_iter) 00529 { 00530 dest_acc.set(src_acc(src_iter), dest_iter); 00531 } 00532 } 00533 } 00534 else 00535 { 00536 DestIterator dest_end = dest_iter + (int)VIGRA_CSTD::ceil(src_width*factor); 00537 factor = 1.0/factor; 00538 int int_factor = (int)factor; 00539 double dx = factor - int_factor; 00540 double saver = dx; 00541 src_iter_end -= 1; 00542 for ( ; src_iter != src_iter_end && dest_iter != dest_end ; 00543 ++dest_iter, src_iter += int_factor, saver += dx) 00544 { 00545 if (saver >= 1.0) 00546 { 00547 saver = saver - (int)saver; 00548 ++src_iter; 00549 } 00550 dest_acc.set(src_acc(src_iter), dest_iter); 00551 } 00552 if (dest_iter != dest_end) 00553 { 00554 dest_acc.set(src_acc(src_iter_end), dest_iter); 00555 } 00556 } 00557 } 00558 00559 inline int sizeForResamplingFactor(int oldsize, double factor) 00560 { 00561 return (factor < 1.0) 00562 ? (int)VIGRA_CSTD::ceil(oldsize * factor) 00563 : (int)(oldsize * factor); 00564 } 00565 00566 00567 /********************************************************/ 00568 /* */ 00569 /* resampleImage */ 00570 /* */ 00571 /********************************************************/ 00572 00573 /** \brief Resample image by a given factor. 00574 00575 This algorithm is very fast and does not require any arithmetic on the pixel types. 00576 The input image must have a size of at 00577 least 2x2. Destiniation pixels are directly copied from the appropriate 00578 source pixels. The size of the result image is the product of <tt>factor</tt> 00579 and the original size, where we round up if <tt>factor < 1.0</tt> and down otherwise. 00580 This size calculation is the main difference to the convention used in the similar 00581 function \ref resizeImageNoInterpolation(): 00582 there, the result size is calculated as <tt>n*(old_width-1)+1</tt> and 00583 <tt>n*(old_height-1)+1</tt>. This is because \ref resizeImageNoInterpolation() 00584 does not replicate the last pixel in every row/column in order to make it compatible 00585 with the other functions of the <tt>resizeImage...</tt> family. 00586 00587 The function can be called with different resampling factors for x and y, or 00588 with a single factor to be used for both directions. 00589 00590 It should also be noted that resampleImage() is implemented so that an enlargement followed 00591 by the corresponding shrinking reproduces the original image. The function uses accessors. 00592 00593 <b> Declarations:</b> 00594 00595 pass arguments explicitly: 00596 \code 00597 namespace vigra { 00598 template <class SrcIterator, class SrcAccessor, 00599 class DestIterator, class DestAccessor> 00600 void 00601 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa, 00602 DestIterator id, DestAccessor ad, double factor); 00603 00604 template <class SrcIterator, class SrcAccessor, 00605 class DestIterator, class DestAccessor> 00606 void 00607 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa, 00608 DestIterator id, DestAccessor ad, double xfactor, double yfactor); 00609 } 00610 \endcode 00611 00612 use argument objects in conjunction with \ref ArgumentObjectFactories : 00613 \code 00614 namespace vigra { 00615 template <class SrcImageIterator, class SrcAccessor, 00616 class DestImageIterator, class DestAccessor> 00617 inline void 00618 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00619 pair<DestImageIterator, DestAccessor> dest, double factor); 00620 00621 template <class SrcImageIterator, class SrcAccessor, 00622 class DestImageIterator, class DestAccessor> 00623 inline void 00624 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00625 pair<DestImageIterator, DestAccessor> dest, double xfactor, double yfactor); 00626 } 00627 \endcode 00628 00629 <b> Usage:</b> 00630 00631 <b>\#include</b> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><br> 00632 Namespace: vigra 00633 00634 \code 00635 double factor = 2.0; 00636 Image dest((int)(factor*src.width()), (int)(factor*src.height())); 00637 00638 vigra::resampleImage(srcImageRange(src), destImage(dest), factor); 00639 00640 \endcode 00641 00642 <b> Required Interface:</b> 00643 00644 \code 00645 SrcImageIterator src_upperleft, src_lowerright; 00646 DestImageIterator dest_upperleft; 00647 00648 SrcAccessor src_accessor; 00649 00650 dest_accessor.set(src_accessor(src_upperleft), dest_upperleft); 00651 00652 \endcode 00653 00654 <b> Preconditions:</b> 00655 00656 \code 00657 src_lowerright.x - src_upperleft.x > 1 00658 src_lowerright.y - src_upperleft.y > 1 00659 \endcode 00660 00661 */ 00662 doxygen_overloaded_function(template <...> void resampleImage) 00663 00664 template <class SrcIterator, class SrcAccessor, 00665 class DestIterator, class DestAccessor> 00666 void 00667 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa, 00668 DestIterator id, DestAccessor ad, double xfactor, double yfactor) 00669 { 00670 int width_old = iend.x - is.x; 00671 int height_old = iend.y - is.y; 00672 00673 //Bei Verkleinerung muss das dest-Bild ceiling(src*factor), da z.B. 00674 //aus 6x6 grossem Bild wird eins 18x18 grosses gemacht bei Vergroesserungsfaktor 3.1 00675 //umgekehrt damit wir vom 18x18 zu 6x6 (und nicht 5x5) bei Vergroesserung von 1/3.1 00676 //muss das kleinste Integer das groesser als 18/3.1 ist genommen werden. 00677 int height_new = sizeForResamplingFactor(height_old, yfactor); 00678 int width_new = sizeForResamplingFactor(width_old, xfactor); 00679 00680 vigra_precondition((width_old > 1) && (height_old > 1), 00681 "resampleImage(): " 00682 "Source image to small.\n"); 00683 vigra_precondition((width_new > 1) && (height_new > 1), 00684 "resampleImage(): " 00685 "Destination image to small.\n"); 00686 00687 typedef typename SrcAccessor::value_type SRCVT; 00688 typedef BasicImage<SRCVT> TmpImage; 00689 typedef typename TmpImage::traverser TmpImageIterator; 00690 00691 BasicImage<SRCVT> tmp(width_old, height_new); 00692 00693 int x,y; 00694 00695 typename BasicImage<SRCVT>::Iterator yt = tmp.upperLeft(); 00696 00697 for(x=0; x<width_old; ++x, ++is.x, ++yt.x) 00698 { 00699 typename SrcIterator::column_iterator c1 = is.columnIterator(); 00700 typename TmpImageIterator::column_iterator ct = yt.columnIterator(); 00701 resampleLine(c1, c1 + height_old, sa, ct, tmp.accessor(), yfactor); 00702 } 00703 00704 yt = tmp.upperLeft(); 00705 00706 for(y=0; y < height_new; ++y, ++yt.y, ++id.y) 00707 { 00708 typename DestIterator::row_iterator rd = id.rowIterator(); 00709 typename TmpImageIterator::row_iterator rt = yt.rowIterator(); 00710 resampleLine(rt, rt + width_old, tmp.accessor(), rd, ad, xfactor); 00711 } 00712 00713 } 00714 00715 template <class SrcIterator, class SrcAccessor, 00716 class DestIterator, class DestAccessor> 00717 void 00718 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa, 00719 DestIterator id, DestAccessor ad, double factor) 00720 { 00721 resampleImage(is, iend, sa, id, ad, factor, factor); 00722 } 00723 00724 template <class SrcImageIterator, class SrcAccessor, 00725 class DestImageIterator, class DestAccessor> 00726 inline void 00727 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00728 pair<DestImageIterator, DestAccessor> dest, double factor) 00729 { 00730 resampleImage(src.first, src.second, src.third, dest.first, dest.second, factor); 00731 } 00732 00733 template <class SrcImageIterator, class SrcAccessor, 00734 class DestImageIterator, class DestAccessor> 00735 inline void 00736 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00737 pair<DestImageIterator, DestAccessor> dest, double xfactor, double yfactor) 00738 { 00739 resampleImage(src.first, src.second, src.third, dest.first, dest.second, xfactor, yfactor); 00740 } 00741 00742 //@} 00743 00744 } // namespace vigra 00745 00746 00747 #endif /* VIGRA_BASICGEOMETRY_HXX */
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|