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