[ 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 /* ( Version 1.6.0, Aug 13 2008 ) */ 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 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00012 /* vigra@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 "error.hxx" 00042 #include "stdimage.hxx" 00043 #include "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 doxygen_overloaded_function(template <...> void rotateImage) 00120 00121 template <class SrcIterator, class SrcAccessor, 00122 class DestIterator, class DestAccessor> 00123 void rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as, 00124 DestIterator id, DestAccessor ad, int rotation) 00125 { 00126 int x, y; 00127 int ws = end.x - is.x; 00128 int hs = end.y - is.y; 00129 00130 vigra_precondition(rotation % 90 == 0, 00131 "rotateImage(): " 00132 "This function rotates images only about multiples of 90 degree"); 00133 00134 rotation = rotation%360; 00135 if (rotation < 0) 00136 rotation += 360; 00137 00138 switch(rotation) 00139 { 00140 case 0: 00141 copyImage(is, end, as, id, ad); 00142 break; 00143 case 90: 00144 is.x += (ws-1); 00145 for(x=0; x != ws; x++, is.x--, id.y++) 00146 { 00147 typename SrcIterator::column_iterator cs = is.columnIterator(); 00148 typename DestIterator::row_iterator rd = id.rowIterator(); 00149 for(y=0; y != hs; y++, cs++, rd++) 00150 { 00151 ad.set(as(cs), rd); 00152 } 00153 00154 } 00155 break; 00156 00157 case 180: 00158 end.x--; 00159 end.y--; 00160 for(x=0; x != ws; x++, end.x--, id.x++) 00161 { 00162 typename SrcIterator::column_iterator cs = end.columnIterator(); 00163 typename DestIterator::column_iterator cd = id.columnIterator(); 00164 for(y=0; y != hs; y++, cs--, cd++) 00165 { 00166 ad.set(as(cs), cd); 00167 } 00168 00169 } 00170 break; 00171 00172 case 270: 00173 is.y += (hs-1); 00174 for(x=0; x != ws; x++, is.x++, id.y++) 00175 { 00176 typename SrcIterator::column_iterator cs = is.columnIterator(); 00177 typename DestIterator::row_iterator rd = id.rowIterator(); 00178 for(y=0; y != hs; y++, cs--, rd++) 00179 { 00180 ad.set(as(cs), rd); 00181 } 00182 00183 } 00184 break; 00185 default: //not needful, because of the exception handig in if-statement 00186 vigra_fail("internal error"); 00187 } 00188 } 00189 00190 template <class SrcImageIterator, class SrcAccessor, 00191 class DestImageIterator, class DestAccessor> 00192 inline void 00193 rotateImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00194 pair<DestImageIterator, DestAccessor> dest, int rotation) 00195 { 00196 rotateImage(src.first, src.second, src.third, dest.first, dest.second, rotation); 00197 } 00198 00199 /********************************************************/ 00200 /* */ 00201 /* reflectImage */ 00202 /* */ 00203 /********************************************************/ 00204 00205 enum Reflect{horizontal = 1, vertical = 2}; 00206 00207 /** \brief Reflect image horizontally or vertically. 00208 00209 The reflection direction refers to the reflection axis, i.e. 00210 horizontal reflection turns the image upside down, vertical reflection 00211 changes left for right. The directions are selected by the enum values 00212 <tt>vigra::horizontal</tt> and <tt>vigra::vertical</tt>. The two directions 00213 can also be "or"ed together to perform both reflections simultaneously 00214 (see example below) -- this is the same as a 180 degree rotation. 00215 00216 <b> Declarations:</b> 00217 00218 pass arguments explicitly: 00219 \code 00220 namespace vigra { 00221 template <class SrcIterator, class SrcAccessor, 00222 class DestIterator, class DestAccessor> 00223 void 00224 reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as, 00225 DestIterator id, DestAccessor ad, Reflect axis); 00226 } 00227 \endcode 00228 00229 use argument objects in conjunction with \ref ArgumentObjectFactories : 00230 \code 00231 namespace vigra { 00232 template <class SrcImageIterator, class SrcAccessor, 00233 class DestImageIterator, class DestAccessor> 00234 inline void 00235 reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00236 pair<DestImageIterator, DestAccessor> dest, Reflect axis); 00237 } 00238 \endcode 00239 00240 <b> Usage:</b> 00241 00242 <b>\#include</b> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><br> 00243 Namespace: vigra 00244 00245 \code 00246 Image dest(src.width(), src.height()); 00247 00248 vigra::reflectImage(srcImageRange(src), destImage(dest), vigra::horizontal | vigra::vertical); 00249 00250 \endcode 00251 00252 <b> Required Interface:</b> 00253 00254 \code 00255 SrcImageIterator src_upperleft, src_lowerright; 00256 DestImageIterator dest_upperleft; 00257 00258 SrcAccessor src_accessor; 00259 00260 dest_accessor.set(src_accessor(src_upperleft), dest_upperleft); 00261 00262 \endcode 00263 00264 <b> Preconditions:</b> 00265 00266 \code 00267 src_lowerright.x - src_upperleft.x > 1 00268 src_lowerright.y - src_upperleft.y > 1 00269 \endcode 00270 00271 */ 00272 doxygen_overloaded_function(template <...> void reflectImage) 00273 00274 template <class SrcIterator, class SrcAccessor, 00275 class DestIterator, class DestAccessor> 00276 void reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as, 00277 DestIterator id, DestAccessor ad, Reflect reflect) 00278 { 00279 00280 int ws = end.x - is.x; 00281 int hs = end.y - is.y; 00282 00283 int x, y; 00284 00285 if(reflect == horizontal) 00286 {//flipImage 00287 is.y += (hs-1); 00288 for(x=0; x<ws; ++x, ++is.x, ++id.x) 00289 { 00290 typename SrcIterator::column_iterator cs = is.columnIterator(); 00291 typename DestIterator::column_iterator cd = id.columnIterator(); 00292 for(y=0; y!=hs;y++, cs--, cd++) 00293 { 00294 ad.set(as(cs), cd); 00295 } 00296 } 00297 } 00298 else if(reflect == vertical) 00299 {//flopImage 00300 is.x += (ws-1); 00301 for(x=0; x < ws; ++x, --is.x, ++id.x) 00302 { 00303 00304 typename SrcIterator::column_iterator cs = is.columnIterator(); 00305 typename DestIterator::column_iterator cd = id.columnIterator(); 00306 for(y=0; y!=hs;y++, cs++, cd++) 00307 { 00308 ad.set(as(cs), cd); 00309 } 00310 } 00311 } 00312 else if(reflect == (horizontal | vertical)) 00313 {//flipFlopImage //??? 00314 end.x--; 00315 end.y--; 00316 for(x=0; x != ws; x++, end.x--, id.x++) 00317 { 00318 typename SrcIterator::column_iterator cs = end.columnIterator(); 00319 typename DestIterator::column_iterator cd = id.columnIterator(); 00320 for(y=0; y != hs; y++, cs--, cd++) 00321 { 00322 ad.set(as(cs), cd); 00323 } 00324 } 00325 } 00326 else 00327 vigra_fail("reflectImage(): " 00328 "This function reflects horizontal or vertical," 00329 " 'and' is included"); 00330 } 00331 00332 template <class SrcImageIterator, class SrcAccessor, 00333 class DestImageIterator, class DestAccessor> 00334 inline void 00335 reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00336 pair<DestImageIterator, DestAccessor> dest, Reflect reflect) 00337 { 00338 reflectImage(src.first, src.second, src.third, dest.first, dest.second, reflect); 00339 } 00340 00341 /********************************************************/ 00342 /* */ 00343 /* transposeImage */ 00344 /* */ 00345 /********************************************************/ 00346 00347 enum Transpose{major = 1, minor = 2}; 00348 00349 /** \brief Transpose an image over the major or minor diagonal. 00350 00351 The transposition direction refers to the axis, i.e. 00352 major transposition turns the upper right corner into the lower left one, 00353 whereas minor transposition changes the upper left corner into the lower right one. 00354 The directions are selected by the enum values 00355 <tt>vigra::major</tt> and <tt>vigra::minor</tt>. The two directions 00356 can also be "or"ed together to perform both reflections simultaneously 00357 (see example below) -- this is the same as a 180 degree rotation. 00358 00359 <b> Declarations:</b> 00360 00361 pass arguments explicitly: 00362 \code 00363 namespace vigra { 00364 template <class SrcIterator, class SrcAccessor, 00365 class DestIterator, class DestAccessor> 00366 void 00367 transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as, 00368 DestIterator id, DestAccessor ad, Transpose axis); 00369 } 00370 \endcode 00371 00372 use argument objects in conjunction with \ref ArgumentObjectFactories : 00373 \code 00374 namespace vigra { 00375 template <class SrcImageIterator, class SrcAccessor, 00376 class DestImageIterator, class DestAccessor> 00377 inline void 00378 transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00379 pair<DestImageIterator, DestAccessor> dest, Transpose axis); 00380 } 00381 \endcode 00382 00383 <b> Usage:</b> 00384 00385 <b>\#include</b> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><br> 00386 Namespace: vigra 00387 00388 \code 00389 Image dest(src.width(), src.height()); 00390 00391 vigra::transposeImage(srcImageRange(src), destImage(dest), vigra::major | vigra::minor); 00392 00393 \endcode 00394 00395 <b> Required Interface:</b> 00396 00397 \code 00398 SrcImageIterator src_upperleft, src_lowerright; 00399 DestImageIterator dest_upperleft; 00400 00401 SrcAccessor src_accessor; 00402 00403 dest_accessor.set(src_accessor(src_upperleft), dest_upperleft); 00404 00405 \endcode 00406 00407 <b> Preconditions:</b> 00408 00409 \code 00410 src_lowerright.x - src_upperleft.x > 1 00411 src_lowerright.y - src_upperleft.y > 1 00412 \endcode 00413 00414 */ 00415 doxygen_overloaded_function(template <...> void transposeImage) 00416 00417 template <class SrcIterator, class SrcAccessor, 00418 class DestIterator, class DestAccessor> 00419 void transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as, 00420 DestIterator id, DestAccessor ad, Transpose transpose) 00421 { 00422 int ws = end.x - is.x; 00423 int hs = end.y - is.y; 00424 00425 int x, y; 00426 00427 if(transpose == major) 00428 {//Die Funktion spiegelt das Bild um (0,0) (1,1) Diagonale 00429 for(x=0; x != ws; x++, is.x++, id.y++) 00430 { 00431 00432 typename SrcIterator::column_iterator cs = is.columnIterator(); 00433 typename DestIterator::row_iterator rd = id.rowIterator(); 00434 for(y=0; y != hs; y++, cs++, rd++) 00435 { 00436 ad.set(as(cs), rd); 00437 } 00438 } 00439 } 00440 else if(transpose == minor) 00441 {//Die Funktion spiegelt das Bild (1,0) (0,1) Diagonale 00442 end.x--; 00443 end.y--; 00444 for(x=0; x != ws; x++, --end.x, ++id.y) 00445 { 00446 00447 typename SrcIterator::column_iterator cs = end.columnIterator(); 00448 typename DestIterator::row_iterator rd = id.rowIterator(); 00449 for(y=0; y != hs; y++, --cs, ++rd) 00450 { 00451 ad.set(as(cs), rd); 00452 } 00453 } 00454 } 00455 else if(transpose == (major | minor)) 00456 {//flipFlopImage //??? 00457 end.x--; 00458 end.y--; 00459 for(x=0; x != ws; x++, end.x--, id.x++) 00460 { 00461 typename SrcIterator::column_iterator cs = end.columnIterator(); 00462 typename DestIterator::column_iterator cd = id.columnIterator(); 00463 for(y=0; y != hs; y++, cs--, cd++) 00464 { 00465 ad.set(as(cs), cd); 00466 } 00467 } 00468 00469 } 00470 else 00471 vigra_fail("transposeImage(): " 00472 "This function transposes major or minor," 00473 " 'and' is included"); 00474 00475 } 00476 00477 template <class SrcImageIterator, class SrcAccessor, 00478 class DestImageIterator, class DestAccessor> 00479 inline void 00480 transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00481 pair<DestImageIterator, DestAccessor> dest, Transpose transpose) 00482 { 00483 transposeImage(src.first, src.second, src.third, dest.first, dest.second, transpose); 00484 } 00485 00486 /********************************************************/ 00487 /* */ 00488 /* resampleLine */ 00489 /* */ 00490 /********************************************************/ 00491 00492 /* 00493 * Vergroessert eine Linie um einen Faktor. 00494 * Ist z.B. der Faktor = 4 so werden in der 00495 * neuen Linie(Destination) jedes Pixel genau 4 mal 00496 * vorkommen, also es findet auch keine Glaetung 00497 * statt (NoInterpolation). Als Parameter sollen 00498 * der Anfangs-, der Enditerator und der Accessor 00499 * der Ausgangslinie (Source line), der Anfangsiterator 00500 * und Accessor der Ziellinie (destination line) und 00501 * anschliessend der Faktor um den die Linie (Zeile) 00502 * vergroessert bzw. verkleinert werden soll. 00503 */ 00504 template <class SrcIterator, class SrcAccessor, 00505 class DestIterator, class DestAccessor> 00506 void resampleLine(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc, 00507 DestIterator dest_iter, DestAccessor dest_acc, double factor) 00508 { 00509 // The width of the src line. 00510 int src_width = src_iter_end - src_iter; 00511 00512 vigra_precondition(src_width > 0, 00513 "resampleLine(): input image too small."); 00514 vigra_precondition(factor > 0.0, 00515 "resampleLine(): factor must be positive."); 00516 00517 if (factor >= 1.0) 00518 { 00519 int int_factor = (int)factor; 00520 double dx = factor - int_factor; 00521 double saver = dx; 00522 for ( ; src_iter != src_iter_end ; ++src_iter, saver += dx) 00523 { 00524 if (saver >= 1.0) 00525 { 00526 saver = saver - (int)saver; 00527 dest_acc.set(src_acc(src_iter), dest_iter); 00528 ++dest_iter; 00529 } 00530 for(int i = 0 ; i < int_factor ; i++, ++dest_iter) 00531 { 00532 dest_acc.set(src_acc(src_iter), dest_iter); 00533 } 00534 } 00535 } 00536 else 00537 { 00538 DestIterator dest_end = dest_iter + (int)VIGRA_CSTD::ceil(src_width*factor); 00539 factor = 1.0/factor; 00540 int int_factor = (int)factor; 00541 double dx = factor - int_factor; 00542 double saver = dx; 00543 src_iter_end -= 1; 00544 for ( ; src_iter != src_iter_end && dest_iter != dest_end ; 00545 ++dest_iter, src_iter += int_factor, saver += dx) 00546 { 00547 if (saver >= 1.0) 00548 { 00549 saver = saver - (int)saver; 00550 ++src_iter; 00551 } 00552 dest_acc.set(src_acc(src_iter), dest_iter); 00553 } 00554 if (dest_iter != dest_end) 00555 { 00556 dest_acc.set(src_acc(src_iter_end), dest_iter); 00557 } 00558 } 00559 } 00560 00561 inline int sizeForResamplingFactor(int oldsize, double factor) 00562 { 00563 return (factor < 1.0) 00564 ? (int)VIGRA_CSTD::ceil(oldsize * factor) 00565 : (int)(oldsize * factor); 00566 } 00567 00568 00569 /********************************************************/ 00570 /* */ 00571 /* resampleImage */ 00572 /* */ 00573 /********************************************************/ 00574 00575 /** \brief Resample image by a given factor. 00576 00577 This algorithm is very fast and does not require any arithmetic on the pixel types. 00578 The input image must have a size of at 00579 least 2x2. Destiniation pixels are directly copied from the appropriate 00580 source pixels. The size of the result image is the product of <tt>factor</tt> 00581 and the original size, where we round up if <tt>factor < 1.0</tt> and down otherwise. 00582 This size calculation is the main difference to the convention used in the similar 00583 function \ref resizeImageNoInterpolation(): 00584 there, the result size is calculated as <tt>n*(old_width-1)+1</tt> and 00585 <tt>n*(old_height-1)+1</tt>. This is because \ref resizeImageNoInterpolation() 00586 does not replicate the last pixel in every row/column in order to make it compatible 00587 with the other functions of the <tt>resizeImage...</tt> family. 00588 00589 It should also be noted that resampleImage() is implemented so that an enlargement followed 00590 by the corresponding shrinking reproduces the original image. The function uses accessors. 00591 00592 <b> Declarations:</b> 00593 00594 pass arguments explicitly: 00595 \code 00596 namespace vigra { 00597 template <class SrcIterator, class SrcAccessor, 00598 class DestIterator, class DestAccessor> 00599 void 00600 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa, 00601 DestIterator id, DestAccessor ad, double factor); 00602 } 00603 \endcode 00604 00605 use argument objects in conjunction with \ref ArgumentObjectFactories : 00606 \code 00607 namespace vigra { 00608 template <class SrcImageIterator, class SrcAccessor, 00609 class DestImageIterator, class DestAccessor> 00610 inline void 00611 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00612 pair<DestImageIterator, DestAccessor> dest, double factor); 00613 } 00614 \endcode 00615 00616 <b> Usage:</b> 00617 00618 <b>\#include</b> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><br> 00619 Namespace: vigra 00620 00621 \code 00622 double factor = 2.0; 00623 Image dest((int)(factor*src.width()), (int)(factor*src.height())); 00624 00625 vigra::resampleImage(srcImageRange(src), destImage(dest), factor); 00626 00627 \endcode 00628 00629 <b> Required Interface:</b> 00630 00631 \code 00632 SrcImageIterator src_upperleft, src_lowerright; 00633 DestImageIterator dest_upperleft; 00634 00635 SrcAccessor src_accessor; 00636 00637 dest_accessor.set(src_accessor(src_upperleft), dest_upperleft); 00638 00639 \endcode 00640 00641 <b> Preconditions:</b> 00642 00643 \code 00644 src_lowerright.x - src_upperleft.x > 1 00645 src_lowerright.y - src_upperleft.y > 1 00646 \endcode 00647 00648 */ 00649 doxygen_overloaded_function(template <...> void resampleImage) 00650 00651 template <class SrcIterator, class SrcAccessor, 00652 class DestIterator, class DestAccessor> 00653 void 00654 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa, 00655 DestIterator id, DestAccessor ad, double factor) 00656 { 00657 int width_old = iend.x - is.x; 00658 int height_old = iend.y - is.y; 00659 00660 //Bei Verkleinerung muss das dest-Bild ceiling(src*factor), da z.B. 00661 //aus 6x6 grossem Bild wird eins 18x18 grosses gemacht bei Vergroesserungsfaktor 3.1 00662 //umgekehrt damit wir vom 18x18 zu 6x6 (und nicht 5x5) bei Vergroesserung von 1/3.1 00663 //muss das kleinste Integer das groesser als 18/3.1 ist genommen werden. 00664 int height_new = sizeForResamplingFactor(height_old, factor); 00665 int width_new = sizeForResamplingFactor(width_old, factor); 00666 00667 vigra_precondition((width_old > 1) && (height_old > 1), 00668 "resampleImage(): " 00669 "Source image to small.\n"); 00670 vigra_precondition((width_new > 1) && (height_new > 1), 00671 "resampleImage(): " 00672 "Destination image to small.\n"); 00673 00674 typedef typename SrcAccessor::value_type SRCVT; 00675 typedef BasicImage<SRCVT> TmpImage; 00676 typedef typename TmpImage::traverser TmpImageIterator; 00677 00678 BasicImage<SRCVT> tmp(width_old, height_new); 00679 00680 int x,y; 00681 00682 typename BasicImage<SRCVT>::Iterator yt = tmp.upperLeft(); 00683 00684 for(x=0; x<width_old; ++x, ++is.x, ++yt.x) 00685 { 00686 typename SrcIterator::column_iterator c1 = is.columnIterator(); 00687 typename TmpImageIterator::column_iterator ct = yt.columnIterator(); 00688 resampleLine(c1, c1 + height_old, sa, ct, tmp.accessor(), factor); 00689 } 00690 00691 yt = tmp.upperLeft(); 00692 00693 for(y=0; y < height_new; ++y, ++yt.y, ++id.y) 00694 { 00695 typename DestIterator::row_iterator rd = id.rowIterator(); 00696 typename TmpImageIterator::row_iterator rt = yt.rowIterator(); 00697 resampleLine(rt, rt + width_old, tmp.accessor(), rd, ad, factor); 00698 } 00699 00700 } 00701 00702 template <class SrcImageIterator, class SrcAccessor, 00703 class DestImageIterator, class DestAccessor> 00704 inline void 00705 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, 00706 pair<DestImageIterator, DestAccessor> dest, double factor) 00707 { 00708 resampleImage(src.first, src.second, src.third, dest.first, dest.second, factor); 00709 } 00710 00711 //@} 00712 00713 } // namespace vigra 00714 00715 00716 #endif /* VIGRA_BASICGEOMETRY_HXX */
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|