[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

basicgeometry.hxx
1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2002 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 #ifndef VIGRA_BASICGEOMETRY_HXX
37 #define VIGRA_BASICGEOMETRY_HXX
38 
39 #include "error.hxx"
40 #include "stdimage.hxx"
41 #include "copyimage.hxx"
42 #include <cmath>
43 
44 namespace vigra {
45 
46 /** \addtogroup GeometricTransformations Geometric Transformations
47 */
48 //@{
49 
50 /********************************************************/
51 /* */
52 /* rotateImage */
53 /* */
54 /********************************************************/
55 
56 /** \brief Rotate image by a multiple of 90 degrees.
57 
58  This algorithm just copies the pixels in the appropriate new order. It expects the
59  destination image to have the correct shape for the desired rotation.
60 
61  <b> Declarations:</b>
62 
63  pass arguments explicitly:
64  \code
65  namespace vigra {
66  template <class SrcIterator, class SrcAccessor,
67  class DestIterator, class DestAccessor>
68  void
69  rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as,
70  DestIterator id, DestAccessor ad, int rotation);
71  }
72  \endcode
73 
74  use argument objects in conjunction with \ref ArgumentObjectFactories :
75  \code
76  namespace vigra {
77  template <class SrcImageIterator, class SrcAccessor,
78  class DestImageIterator, class DestAccessor>
79  inline void
80  rotateImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
81  pair<DestImageIterator, DestAccessor> dest, int rotation);
82  }
83  \endcode
84 
85  <b> Usage:</b>
86 
87  <b>\#include</b> <vigra/basicgeometry.hxx><br>
88  Namespace: vigra
89 
90  \code
91  Image dest(src.height(), src.width()); // note that width and height are exchanged
92 
93  vigra::rotateImage(srcImageRange(src), destImage(dest), 90);
94 
95  \endcode
96 
97  <b> Required Interface:</b>
98 
99  \code
100  SrcImageIterator src_upperleft, src_lowerright;
101  DestImageIterator dest_upperleft;
102 
103  SrcAccessor src_accessor;
104 
105  dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
106 
107  \endcode
108 
109  <b> Preconditions:</b>
110 
111  \code
112  src_lowerright.x - src_upperleft.x > 1
113  src_lowerright.y - src_upperleft.y > 1
114  \endcode
115 
116 */
117 doxygen_overloaded_function(template <...> void rotateImage)
118 
119 template <class SrcIterator, class SrcAccessor,
120  class DestIterator, class DestAccessor>
121 void rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as,
122  DestIterator id, DestAccessor ad, int rotation)
123 {
124  int x, y;
125  int ws = end.x - is.x;
126  int hs = end.y - is.y;
127 
128  vigra_precondition(rotation % 90 == 0,
129  "rotateImage(): "
130  "This function rotates images only about multiples of 90 degree");
131 
132  rotation = rotation%360;
133  if (rotation < 0)
134  rotation += 360;
135 
136  switch(rotation)
137  {
138  case 0:
139  copyImage(is, end, as, id, ad);
140  break;
141  case 90:
142  is.x += (ws-1);
143  for(x=0; x != ws; x++, is.x--, id.y++)
144  {
145  typename SrcIterator::column_iterator cs = is.columnIterator();
146  typename DestIterator::row_iterator rd = id.rowIterator();
147  for(y=0; y != hs; y++, cs++, rd++)
148  {
149  ad.set(as(cs), rd);
150  }
151 
152  }
153  break;
154 
155  case 180:
156  end.x--;
157  end.y--;
158  for(x=0; x != ws; x++, end.x--, id.x++)
159  {
160  typename SrcIterator::column_iterator cs = end.columnIterator();
161  typename DestIterator::column_iterator cd = id.columnIterator();
162  for(y=0; y != hs; y++, cs--, cd++)
163  {
164  ad.set(as(cs), cd);
165  }
166 
167  }
168  break;
169 
170  case 270:
171  is.y += (hs-1);
172  for(x=0; x != ws; x++, is.x++, id.y++)
173  {
174  typename SrcIterator::column_iterator cs = is.columnIterator();
175  typename DestIterator::row_iterator rd = id.rowIterator();
176  for(y=0; y != hs; y++, cs--, rd++)
177  {
178  ad.set(as(cs), rd);
179  }
180 
181  }
182  break;
183  default: //not needful, because of the exception handig in if-statement
184  vigra_fail("internal error");
185  }
186 }
187 
188 template <class SrcImageIterator, class SrcAccessor,
189  class DestImageIterator, class DestAccessor>
190 inline void
191 rotateImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
192  pair<DestImageIterator, DestAccessor> dest, int rotation)
193 {
194  rotateImage(src.first, src.second, src.third, dest.first, dest.second, rotation);
195 }
196 
197 /********************************************************/
198 /* */
199 /* reflectImage */
200 /* */
201 /********************************************************/
202 
203 enum Reflect {horizontal = 1, vertical = 2};
204 
205 inline
206 Reflect operator|(Reflect l, Reflect r)
207 {
208  return Reflect((unsigned int)l | (unsigned int)r);
209 }
210 
211 /** \brief Reflect image horizontally or vertically.
212 
213  The reflection direction refers to the reflection axis, i.e.
214  horizontal reflection turns the image upside down, vertical reflection
215  changes left for right. The directions are selected by the enum values
216  <tt>vigra::horizontal</tt> and <tt>vigra::vertical</tt>. The two directions
217  can also be "or"ed together to perform both reflections simultaneously
218  (see example below) -- this is the same as a 180 degree rotation.
219 
220  <b> Declarations:</b>
221 
222  pass arguments explicitly:
223  \code
224  namespace vigra {
225  template <class SrcIterator, class SrcAccessor,
226  class DestIterator, class DestAccessor>
227  void
228  reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
229  DestIterator id, DestAccessor ad, Reflect axis);
230  }
231  \endcode
232 
233  use argument objects in conjunction with \ref ArgumentObjectFactories :
234  \code
235  namespace vigra {
236  template <class SrcImageIterator, class SrcAccessor,
237  class DestImageIterator, class DestAccessor>
238  inline void
239  reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
240  pair<DestImageIterator, DestAccessor> dest, Reflect axis);
241  }
242  \endcode
243 
244  <b> Usage:</b>
245 
246  <b>\#include</b> <vigra/basicgeometry.hxx><br>
247  Namespace: vigra
248 
249  \code
250  Image dest(src.width(), src.height());
251 
252  vigra::reflectImage(srcImageRange(src), destImage(dest), vigra::horizontal | vigra::vertical);
253 
254  \endcode
255 
256  <b> Required Interface:</b>
257 
258  \code
259  SrcImageIterator src_upperleft, src_lowerright;
260  DestImageIterator dest_upperleft;
261 
262  SrcAccessor src_accessor;
263 
264  dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
265 
266  \endcode
267 
268  <b> Preconditions:</b>
269 
270  \code
271  src_lowerright.x - src_upperleft.x > 1
272  src_lowerright.y - src_upperleft.y > 1
273  \endcode
274 
275 */
276 doxygen_overloaded_function(template <...> void reflectImage)
277 
278 template <class SrcIterator, class SrcAccessor,
279  class DestIterator, class DestAccessor>
280 void reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
281  DestIterator id, DestAccessor ad, Reflect reflect)
282 {
283 
284  int ws = end.x - is.x;
285  int hs = end.y - is.y;
286 
287  int x, y;
288 
289  if(reflect == horizontal)
290  {//flipImage
291  is.y += (hs-1);
292  for(x=0; x<ws; ++x, ++is.x, ++id.x)
293  {
294  typename SrcIterator::column_iterator cs = is.columnIterator();
295  typename DestIterator::column_iterator cd = id.columnIterator();
296  for(y=0; y!=hs;y++, cs--, cd++)
297  {
298  ad.set(as(cs), cd);
299  }
300  }
301  }
302  else if(reflect == vertical)
303  {//flopImage
304  is.x += (ws-1);
305  for(x=0; x < ws; ++x, --is.x, ++id.x)
306  {
307 
308  typename SrcIterator::column_iterator cs = is.columnIterator();
309  typename DestIterator::column_iterator cd = id.columnIterator();
310  for(y=0; y!=hs;y++, cs++, cd++)
311  {
312  ad.set(as(cs), cd);
313  }
314  }
315  }
316  else if(reflect == (horizontal | vertical))
317  {//flipFlopImage //???
318  end.x--;
319  end.y--;
320  for(x=0; x != ws; x++, end.x--, id.x++)
321  {
322  typename SrcIterator::column_iterator cs = end.columnIterator();
323  typename DestIterator::column_iterator cd = id.columnIterator();
324  for(y=0; y != hs; y++, cs--, cd++)
325  {
326  ad.set(as(cs), cd);
327  }
328  }
329  }
330  else
331  vigra_fail("reflectImage(): "
332  "This function reflects horizontal or vertical,"
333  " 'and' is included");
334 }
335 
336 template <class SrcImageIterator, class SrcAccessor,
337  class DestImageIterator, class DestAccessor>
338 inline void
339 reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
340  pair<DestImageIterator, DestAccessor> dest, Reflect reflect)
341 {
342  reflectImage(src.first, src.second, src.third, dest.first, dest.second, reflect);
343 }
344 
345 /********************************************************/
346 /* */
347 /* transposeImage */
348 /* */
349 /********************************************************/
350 
351 // names clash with sys/types.h on Mac OS / Darwin, see docs below
352 enum Transpose{major = 1, minor = 2};
353 
354 /** \brief Transpose an image over the major or minor diagonal.
355 
356  The transposition direction refers to the axis, i.e.
357  major transposition turns the upper right corner into the lower left one,
358  whereas minor transposition changes the upper left corner into the lower right one.
359  The directions are selected by the enum values
360  <tt>vigra::major</tt> and <tt>vigra::minor</tt>. The two directions
361  can also be "or"ed together to perform both reflections simultaneously
362  (see example below) -- this is the same as a 180 degree rotation.
363  (Caution: When doing multi-platform development, you should be
364  aware that some <sys/types.h> define major/minor, too. Do not omit
365  the vigra namespace prefix.)
366 
367  <b> Declarations:</b>
368 
369  pass arguments explicitly:
370  \code
371  namespace vigra {
372  template <class SrcIterator, class SrcAccessor,
373  class DestIterator, class DestAccessor>
374  void
375  transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
376  DestIterator id, DestAccessor ad, Transpose axis);
377  }
378  \endcode
379 
380  use argument objects in conjunction with \ref ArgumentObjectFactories :
381  \code
382  namespace vigra {
383  template <class SrcImageIterator, class SrcAccessor,
384  class DestImageIterator, class DestAccessor>
385  inline void
386  transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
387  pair<DestImageIterator, DestAccessor> dest, Transpose axis);
388  }
389  \endcode
390 
391  <b> Usage:</b>
392 
393  <b>\#include</b> <vigra/basicgeometry.hxx><br>
394  Namespace: vigra
395 
396  \code
397  Image dest(src.width(), src.height());
398 
399  vigra::transposeImage(srcImageRange(src), destImage(dest), vigra::major | vigra::minor);
400 
401  \endcode
402 
403  <b> Required Interface:</b>
404 
405  \code
406  SrcImageIterator src_upperleft, src_lowerright;
407  DestImageIterator dest_upperleft;
408 
409  SrcAccessor src_accessor;
410 
411  dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
412 
413  \endcode
414 
415  <b> Preconditions:</b>
416 
417  \code
418  src_lowerright.x - src_upperleft.x > 1
419  src_lowerright.y - src_upperleft.y > 1
420  \endcode
421 
422 */
423 doxygen_overloaded_function(template <...> void transposeImage)
424 
425 template <class SrcIterator, class SrcAccessor,
426  class DestIterator, class DestAccessor>
427 void transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
428  DestIterator id, DestAccessor ad, Transpose transpose)
429 {
430  int ws = end.x - is.x;
431  int hs = end.y - is.y;
432 
433  int x, y;
434 
435  if(transpose == major)
436  {//Die Funktion spiegelt das Bild um (0,0) (1,1) Diagonale
437  for(x=0; x != ws; x++, is.x++, id.y++)
438  {
439 
440  typename SrcIterator::column_iterator cs = is.columnIterator();
441  typename DestIterator::row_iterator rd = id.rowIterator();
442  for(y=0; y != hs; y++, cs++, rd++)
443  {
444  ad.set(as(cs), rd);
445  }
446  }
447  }
448  else if(transpose == minor)
449  {//Die Funktion spiegelt das Bild (1,0) (0,1) Diagonale
450  end.x--;
451  end.y--;
452  for(x=0; x != ws; x++, --end.x, ++id.y)
453  {
454 
455  typename SrcIterator::column_iterator cs = end.columnIterator();
456  typename DestIterator::row_iterator rd = id.rowIterator();
457  for(y=0; y != hs; y++, --cs, ++rd)
458  {
459  ad.set(as(cs), rd);
460  }
461  }
462  }
463  else if(transpose == (major | minor))
464  {//flipFlopImage //???
465  end.x--;
466  end.y--;
467  for(x=0; x != ws; x++, end.x--, id.x++)
468  {
469  typename SrcIterator::column_iterator cs = end.columnIterator();
470  typename DestIterator::column_iterator cd = id.columnIterator();
471  for(y=0; y != hs; y++, cs--, cd++)
472  {
473  ad.set(as(cs), cd);
474  }
475  }
476 
477  }
478  else
479  vigra_fail("transposeImage(): "
480  "This function transposes major or minor,"
481  " 'and' is included");
482 
483 }
484 
485 template <class SrcImageIterator, class SrcAccessor,
486  class DestImageIterator, class DestAccessor>
487 inline void
488 transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
489  pair<DestImageIterator, DestAccessor> dest, Transpose transpose)
490 {
491  transposeImage(src.first, src.second, src.third, dest.first, dest.second, transpose);
492 }
493 
494 /********************************************************/
495 /* */
496 /* resampleLine */
497 /* */
498 /********************************************************/
499 
500 /*
501 * Vergroessert eine Linie um einen Faktor.
502 * Ist z.B. der Faktor = 4 so werden in der
503 * neuen Linie(Destination) jedes Pixel genau 4 mal
504 * vorkommen, also es findet auch keine Glaetung
505 * statt (NoInterpolation). Als Parameter sollen
506 * der Anfangs-, der Enditerator und der Accessor
507 * der Ausgangslinie (Source line), der Anfangsiterator
508 * und Accessor der Ziellinie (destination line) und
509 * anschliessend der Faktor um den die Linie (Zeile)
510 * vergroessert bzw. verkleinert werden soll.
511 */
512 template <class SrcIterator, class SrcAccessor,
513  class DestIterator, class DestAccessor>
514 void resampleLine(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
515  DestIterator dest_iter, DestAccessor dest_acc, double factor)
516 {
517  // The width of the src line.
518  int src_width = src_iter_end - src_iter;
519 
520  vigra_precondition(src_width > 0,
521  "resampleLine(): input image too small.");
522  vigra_precondition(factor > 0.0,
523  "resampleLine(): factor must be positive.");
524 
525  if (factor >= 1.0)
526  {
527  int int_factor = (int)factor;
528  double dx = factor - int_factor;
529  double saver = dx;
530  for ( ; src_iter != src_iter_end ; ++src_iter, saver += dx)
531  {
532  if (saver >= 1.0)
533  {
534  saver = saver - (int)saver;
535  dest_acc.set(src_acc(src_iter), dest_iter);
536  ++dest_iter;
537  }
538  for(int i = 0 ; i < int_factor ; i++, ++dest_iter)
539  {
540  dest_acc.set(src_acc(src_iter), dest_iter);
541  }
542  }
543  }
544  else
545  {
546  DestIterator dest_end = dest_iter + (int)VIGRA_CSTD::ceil(src_width*factor);
547  factor = 1.0/factor;
548  int int_factor = (int)factor;
549  double dx = factor - int_factor;
550  double saver = dx;
551  src_iter_end -= 1;
552  for ( ; src_iter != src_iter_end && dest_iter != dest_end ;
553  ++dest_iter, src_iter += int_factor, saver += dx)
554  {
555  if (saver >= 1.0)
556  {
557  saver = saver - (int)saver;
558  ++src_iter;
559  }
560  dest_acc.set(src_acc(src_iter), dest_iter);
561  }
562  if (dest_iter != dest_end)
563  {
564  dest_acc.set(src_acc(src_iter_end), dest_iter);
565  }
566  }
567 }
568 
569 inline int sizeForResamplingFactor(int oldsize, double factor)
570 {
571  return (factor < 1.0)
572  ? (int)VIGRA_CSTD::ceil(oldsize * factor)
573  : (int)(oldsize * factor);
574 }
575 
576 
577 /********************************************************/
578 /* */
579 /* resampleImage */
580 /* */
581 /********************************************************/
582 
583 /** \brief Resample image by a given factor.
584 
585  This algorithm is very fast and does not require any arithmetic on the pixel types.
586  The input image must have a size of at
587  least 2x2. Destiniation pixels are directly copied from the appropriate
588  source pixels. The size of the result image is the product of <tt>factor</tt>
589  and the original size, where we round up if <tt>factor < 1.0</tt> and down otherwise.
590  This size calculation is the main difference to the convention used in the similar
591  function \ref resizeImageNoInterpolation():
592  there, the result size is calculated as <tt>n*(old_width-1)+1</tt> and
593  <tt>n*(old_height-1)+1</tt>. This is because \ref resizeImageNoInterpolation()
594  does not replicate the last pixel in every row/column in order to make it compatible
595  with the other functions of the <tt>resizeImage...</tt> family.
596 
597  The function can be called with different resampling factors for x and y, or
598  with a single factor to be used for both directions.
599 
600  It should also be noted that resampleImage() is implemented so that an enlargement followed
601  by the corresponding shrinking reproduces the original image. The function uses accessors.
602 
603  <b> Declarations:</b>
604 
605  pass arguments explicitly:
606  \code
607  namespace vigra {
608  template <class SrcIterator, class SrcAccessor,
609  class DestIterator, class DestAccessor>
610  void
611  resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
612  DestIterator id, DestAccessor ad, double factor);
613 
614  template <class SrcIterator, class SrcAccessor,
615  class DestIterator, class DestAccessor>
616  void
617  resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
618  DestIterator id, DestAccessor ad, double xfactor, double yfactor);
619  }
620  \endcode
621 
622  use argument objects in conjunction with \ref ArgumentObjectFactories :
623  \code
624  namespace vigra {
625  template <class SrcImageIterator, class SrcAccessor,
626  class DestImageIterator, class DestAccessor>
627  inline void
628  resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
629  pair<DestImageIterator, DestAccessor> dest, double factor);
630 
631  template <class SrcImageIterator, class SrcAccessor,
632  class DestImageIterator, class DestAccessor>
633  inline void
634  resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
635  pair<DestImageIterator, DestAccessor> dest, double xfactor, double yfactor);
636  }
637  \endcode
638 
639  <b> Usage:</b>
640 
641  <b>\#include</b> <vigra/basicgeometry.hxx><br>
642  Namespace: vigra
643 
644  \code
645  double factor = 2.0;
646  Image dest((int)(factor*src.width()), (int)(factor*src.height()));
647 
648  vigra::resampleImage(srcImageRange(src), destImage(dest), factor);
649 
650  \endcode
651 
652  <b> Required Interface:</b>
653 
654  \code
655  SrcImageIterator src_upperleft, src_lowerright;
656  DestImageIterator dest_upperleft;
657 
658  SrcAccessor src_accessor;
659 
660  dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
661 
662  \endcode
663 
664  <b> Preconditions:</b>
665 
666  \code
667  src_lowerright.x - src_upperleft.x > 1
668  src_lowerright.y - src_upperleft.y > 1
669  \endcode
670 
671 */
672 doxygen_overloaded_function(template <...> void resampleImage)
673 
674 template <class SrcIterator, class SrcAccessor,
675  class DestIterator, class DestAccessor>
676 void
677 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
678  DestIterator id, DestAccessor ad, double xfactor, double yfactor)
679 {
680  int width_old = iend.x - is.x;
681  int height_old = iend.y - is.y;
682 
683  //Bei Verkleinerung muss das dest-Bild ceiling(src*factor), da z.B.
684  //aus 6x6 grossem Bild wird eins 18x18 grosses gemacht bei Vergroesserungsfaktor 3.1
685  //umgekehrt damit wir vom 18x18 zu 6x6 (und nicht 5x5) bei Vergroesserung von 1/3.1
686  //muss das kleinste Integer das groesser als 18/3.1 ist genommen werden.
687  int height_new = sizeForResamplingFactor(height_old, yfactor);
688  int width_new = sizeForResamplingFactor(width_old, xfactor);
689 
690  vigra_precondition((width_old > 1) && (height_old > 1),
691  "resampleImage(): "
692  "Source image too small.\n");
693  vigra_precondition((width_new > 1) && (height_new > 1),
694  "resampleImage(): "
695  "Destination image too small.\n");
696 
697  typedef typename SrcAccessor::value_type SRCVT;
698  typedef BasicImage<SRCVT> TmpImage;
699  typedef typename TmpImage::traverser TmpImageIterator;
700 
701  BasicImage<SRCVT> tmp(width_old, height_new);
702 
703  int x,y;
704 
705  typename BasicImage<SRCVT>::Iterator yt = tmp.upperLeft();
706 
707  for(x=0; x<width_old; ++x, ++is.x, ++yt.x)
708  {
709  typename SrcIterator::column_iterator c1 = is.columnIterator();
710  typename TmpImageIterator::column_iterator ct = yt.columnIterator();
711  resampleLine(c1, c1 + height_old, sa, ct, tmp.accessor(), yfactor);
712  }
713 
714  yt = tmp.upperLeft();
715 
716  for(y=0; y < height_new; ++y, ++yt.y, ++id.y)
717  {
718  typename DestIterator::row_iterator rd = id.rowIterator();
719  typename TmpImageIterator::row_iterator rt = yt.rowIterator();
720  resampleLine(rt, rt + width_old, tmp.accessor(), rd, ad, xfactor);
721  }
722 
723 }
724 
725 template <class SrcIterator, class SrcAccessor,
726  class DestIterator, class DestAccessor>
727 void
728 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
729  DestIterator id, DestAccessor ad, double factor)
730 {
731  resampleImage(is, iend, sa, id, ad, factor, factor);
732 }
733 
734 template <class SrcImageIterator, class SrcAccessor,
735  class DestImageIterator, class DestAccessor>
736 inline void
737 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
738  pair<DestImageIterator, DestAccessor> dest, double factor)
739 {
740  resampleImage(src.first, src.second, src.third, dest.first, dest.second, factor);
741 }
742 
743 template <class SrcImageIterator, class SrcAccessor,
744  class DestImageIterator, class DestAccessor>
745 inline void
746 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
747  pair<DestImageIterator, DestAccessor> dest, double xfactor, double yfactor)
748 {
749  resampleImage(src.first, src.second, src.third, dest.first, dest.second, xfactor, yfactor);
750 }
751 
752 //@}
753 
754 } // namespace vigra
755 
756 
757 #endif /* VIGRA_BASICGEOMETRY_HXX */

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.9.0 (Sat Oct 5 2013)