[ 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> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><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 /** \brief Reflect image horizontally or vertically.
206 
207  The reflection direction refers to the reflection axis, i.e.
208  horizontal reflection turns the image upside down, vertical reflection
209  changes left for right. The directions are selected by the enum values
210  <tt>vigra::horizontal</tt> and <tt>vigra::vertical</tt>. The two directions
211  can also be "or"ed together to perform both reflections simultaneously
212  (see example below) -- this is the same as a 180 degree rotation.
213 
214  <b> Declarations:</b>
215 
216  pass arguments explicitly:
217  \code
218  namespace vigra {
219  template <class SrcIterator, class SrcAccessor,
220  class DestIterator, class DestAccessor>
221  void
222  reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
223  DestIterator id, DestAccessor ad, Reflect axis);
224  }
225  \endcode
226 
227  use argument objects in conjunction with \ref ArgumentObjectFactories :
228  \code
229  namespace vigra {
230  template <class SrcImageIterator, class SrcAccessor,
231  class DestImageIterator, class DestAccessor>
232  inline void
233  reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
234  pair<DestImageIterator, DestAccessor> dest, Reflect axis);
235  }
236  \endcode
237 
238  <b> Usage:</b>
239 
240  <b>\#include</b> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><br>
241  Namespace: vigra
242 
243  \code
244  Image dest(src.width(), src.height());
245 
246  vigra::reflectImage(srcImageRange(src), destImage(dest), vigra::horizontal | vigra::vertical);
247 
248  \endcode
249 
250  <b> Required Interface:</b>
251 
252  \code
253  SrcImageIterator src_upperleft, src_lowerright;
254  DestImageIterator dest_upperleft;
255 
256  SrcAccessor src_accessor;
257 
258  dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
259 
260  \endcode
261 
262  <b> Preconditions:</b>
263 
264  \code
265  src_lowerright.x - src_upperleft.x > 1
266  src_lowerright.y - src_upperleft.y > 1
267  \endcode
268 
269 */
270 doxygen_overloaded_function(template <...> void reflectImage)
271 
272 template <class SrcIterator, class SrcAccessor,
273  class DestIterator, class DestAccessor>
274 void reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
275  DestIterator id, DestAccessor ad, Reflect reflect)
276 {
277 
278  int ws = end.x - is.x;
279  int hs = end.y - is.y;
280 
281  int x, y;
282 
283  if(reflect == horizontal)
284  {//flipImage
285  is.y += (hs-1);
286  for(x=0; x<ws; ++x, ++is.x, ++id.x)
287  {
288  typename SrcIterator::column_iterator cs = is.columnIterator();
289  typename DestIterator::column_iterator cd = id.columnIterator();
290  for(y=0; y!=hs;y++, cs--, cd++)
291  {
292  ad.set(as(cs), cd);
293  }
294  }
295  }
296  else if(reflect == vertical)
297  {//flopImage
298  is.x += (ws-1);
299  for(x=0; x < ws; ++x, --is.x, ++id.x)
300  {
301 
302  typename SrcIterator::column_iterator cs = is.columnIterator();
303  typename DestIterator::column_iterator cd = id.columnIterator();
304  for(y=0; y!=hs;y++, cs++, cd++)
305  {
306  ad.set(as(cs), cd);
307  }
308  }
309  }
310  else if(reflect == (horizontal | vertical))
311  {//flipFlopImage //???
312  end.x--;
313  end.y--;
314  for(x=0; x != ws; x++, end.x--, id.x++)
315  {
316  typename SrcIterator::column_iterator cs = end.columnIterator();
317  typename DestIterator::column_iterator cd = id.columnIterator();
318  for(y=0; y != hs; y++, cs--, cd++)
319  {
320  ad.set(as(cs), cd);
321  }
322  }
323  }
324  else
325  vigra_fail("reflectImage(): "
326  "This function reflects horizontal or vertical,"
327  " 'and' is included");
328 }
329 
330 template <class SrcImageIterator, class SrcAccessor,
331  class DestImageIterator, class DestAccessor>
332 inline void
333 reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
334  pair<DestImageIterator, DestAccessor> dest, Reflect reflect)
335 {
336  reflectImage(src.first, src.second, src.third, dest.first, dest.second, reflect);
337 }
338 
339 /********************************************************/
340 /* */
341 /* transposeImage */
342 /* */
343 /********************************************************/
344 
345 // names clash with sys/types.h on Mac OS / Darwin, see docs below
346 enum Transpose{major = 1, minor = 2};
347 
348 /** \brief Transpose an image over the major or minor diagonal.
349 
350  The transposition direction refers to the axis, i.e.
351  major transposition turns the upper right corner into the lower left one,
352  whereas minor transposition changes the upper left corner into the lower right one.
353  The directions are selected by the enum values
354  <tt>vigra::major</tt> and <tt>vigra::minor</tt>. The two directions
355  can also be "or"ed together to perform both reflections simultaneously
356  (see example below) -- this is the same as a 180 degree rotation.
357  (Caution: When doing multi-platform development, you should be
358  aware that some <sys/types.h> define major/minor, too. Do not omit
359  the vigra namespace prefix.)
360 
361  <b> Declarations:</b>
362 
363  pass arguments explicitly:
364  \code
365  namespace vigra {
366  template <class SrcIterator, class SrcAccessor,
367  class DestIterator, class DestAccessor>
368  void
369  transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
370  DestIterator id, DestAccessor ad, Transpose axis);
371  }
372  \endcode
373 
374  use argument objects in conjunction with \ref ArgumentObjectFactories :
375  \code
376  namespace vigra {
377  template <class SrcImageIterator, class SrcAccessor,
378  class DestImageIterator, class DestAccessor>
379  inline void
380  transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
381  pair<DestImageIterator, DestAccessor> dest, Transpose axis);
382  }
383  \endcode
384 
385  <b> Usage:</b>
386 
387  <b>\#include</b> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><br>
388  Namespace: vigra
389 
390  \code
391  Image dest(src.width(), src.height());
392 
393  vigra::transposeImage(srcImageRange(src), destImage(dest), vigra::major | vigra::minor);
394 
395  \endcode
396 
397  <b> Required Interface:</b>
398 
399  \code
400  SrcImageIterator src_upperleft, src_lowerright;
401  DestImageIterator dest_upperleft;
402 
403  SrcAccessor src_accessor;
404 
405  dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
406 
407  \endcode
408 
409  <b> Preconditions:</b>
410 
411  \code
412  src_lowerright.x - src_upperleft.x > 1
413  src_lowerright.y - src_upperleft.y > 1
414  \endcode
415 
416 */
417 doxygen_overloaded_function(template <...> void transposeImage)
418 
419 template <class SrcIterator, class SrcAccessor,
420  class DestIterator, class DestAccessor>
421 void transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
422  DestIterator id, DestAccessor ad, Transpose transpose)
423 {
424  int ws = end.x - is.x;
425  int hs = end.y - is.y;
426 
427  int x, y;
428 
429  if(transpose == major)
430  {//Die Funktion spiegelt das Bild um (0,0) (1,1) Diagonale
431  for(x=0; x != ws; x++, is.x++, id.y++)
432  {
433 
434  typename SrcIterator::column_iterator cs = is.columnIterator();
435  typename DestIterator::row_iterator rd = id.rowIterator();
436  for(y=0; y != hs; y++, cs++, rd++)
437  {
438  ad.set(as(cs), rd);
439  }
440  }
441  }
442  else if(transpose == minor)
443  {//Die Funktion spiegelt das Bild (1,0) (0,1) Diagonale
444  end.x--;
445  end.y--;
446  for(x=0; x != ws; x++, --end.x, ++id.y)
447  {
448 
449  typename SrcIterator::column_iterator cs = end.columnIterator();
450  typename DestIterator::row_iterator rd = id.rowIterator();
451  for(y=0; y != hs; y++, --cs, ++rd)
452  {
453  ad.set(as(cs), rd);
454  }
455  }
456  }
457  else if(transpose == (major | minor))
458  {//flipFlopImage //???
459  end.x--;
460  end.y--;
461  for(x=0; x != ws; x++, end.x--, id.x++)
462  {
463  typename SrcIterator::column_iterator cs = end.columnIterator();
464  typename DestIterator::column_iterator cd = id.columnIterator();
465  for(y=0; y != hs; y++, cs--, cd++)
466  {
467  ad.set(as(cs), cd);
468  }
469  }
470 
471  }
472  else
473  vigra_fail("transposeImage(): "
474  "This function transposes major or minor,"
475  " 'and' is included");
476 
477 }
478 
479 template <class SrcImageIterator, class SrcAccessor,
480  class DestImageIterator, class DestAccessor>
481 inline void
482 transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
483  pair<DestImageIterator, DestAccessor> dest, Transpose transpose)
484 {
485  transposeImage(src.first, src.second, src.third, dest.first, dest.second, transpose);
486 }
487 
488 /********************************************************/
489 /* */
490 /* resampleLine */
491 /* */
492 /********************************************************/
493 
494 /*
495 * Vergroessert eine Linie um einen Faktor.
496 * Ist z.B. der Faktor = 4 so werden in der
497 * neuen Linie(Destination) jedes Pixel genau 4 mal
498 * vorkommen, also es findet auch keine Glaetung
499 * statt (NoInterpolation). Als Parameter sollen
500 * der Anfangs-, der Enditerator und der Accessor
501 * der Ausgangslinie (Source line), der Anfangsiterator
502 * und Accessor der Ziellinie (destination line) und
503 * anschliessend der Faktor um den die Linie (Zeile)
504 * vergroessert bzw. verkleinert werden soll.
505 */
506 template <class SrcIterator, class SrcAccessor,
507  class DestIterator, class DestAccessor>
508 void resampleLine(SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
509  DestIterator dest_iter, DestAccessor dest_acc, double factor)
510 {
511  // The width of the src line.
512  int src_width = src_iter_end - src_iter;
513 
514  vigra_precondition(src_width > 0,
515  "resampleLine(): input image too small.");
516  vigra_precondition(factor > 0.0,
517  "resampleLine(): factor must be positive.");
518 
519  if (factor >= 1.0)
520  {
521  int int_factor = (int)factor;
522  double dx = factor - int_factor;
523  double saver = dx;
524  for ( ; src_iter != src_iter_end ; ++src_iter, saver += dx)
525  {
526  if (saver >= 1.0)
527  {
528  saver = saver - (int)saver;
529  dest_acc.set(src_acc(src_iter), dest_iter);
530  ++dest_iter;
531  }
532  for(int i = 0 ; i < int_factor ; i++, ++dest_iter)
533  {
534  dest_acc.set(src_acc(src_iter), dest_iter);
535  }
536  }
537  }
538  else
539  {
540  DestIterator dest_end = dest_iter + (int)VIGRA_CSTD::ceil(src_width*factor);
541  factor = 1.0/factor;
542  int int_factor = (int)factor;
543  double dx = factor - int_factor;
544  double saver = dx;
545  src_iter_end -= 1;
546  for ( ; src_iter != src_iter_end && dest_iter != dest_end ;
547  ++dest_iter, src_iter += int_factor, saver += dx)
548  {
549  if (saver >= 1.0)
550  {
551  saver = saver - (int)saver;
552  ++src_iter;
553  }
554  dest_acc.set(src_acc(src_iter), dest_iter);
555  }
556  if (dest_iter != dest_end)
557  {
558  dest_acc.set(src_acc(src_iter_end), dest_iter);
559  }
560  }
561 }
562 
563 inline int sizeForResamplingFactor(int oldsize, double factor)
564 {
565  return (factor < 1.0)
566  ? (int)VIGRA_CSTD::ceil(oldsize * factor)
567  : (int)(oldsize * factor);
568 }
569 
570 
571 /********************************************************/
572 /* */
573 /* resampleImage */
574 /* */
575 /********************************************************/
576 
577 /** \brief Resample image by a given factor.
578 
579  This algorithm is very fast and does not require any arithmetic on the pixel types.
580  The input image must have a size of at
581  least 2x2. Destiniation pixels are directly copied from the appropriate
582  source pixels. The size of the result image is the product of <tt>factor</tt>
583  and the original size, where we round up if <tt>factor < 1.0</tt> and down otherwise.
584  This size calculation is the main difference to the convention used in the similar
585  function \ref resizeImageNoInterpolation():
586  there, the result size is calculated as <tt>n*(old_width-1)+1</tt> and
587  <tt>n*(old_height-1)+1</tt>. This is because \ref resizeImageNoInterpolation()
588  does not replicate the last pixel in every row/column in order to make it compatible
589  with the other functions of the <tt>resizeImage...</tt> family.
590 
591  The function can be called with different resampling factors for x and y, or
592  with a single factor to be used for both directions.
593 
594  It should also be noted that resampleImage() is implemented so that an enlargement followed
595  by the corresponding shrinking reproduces the original image. The function uses accessors.
596 
597  <b> Declarations:</b>
598 
599  pass arguments explicitly:
600  \code
601  namespace vigra {
602  template <class SrcIterator, class SrcAccessor,
603  class DestIterator, class DestAccessor>
604  void
605  resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
606  DestIterator id, DestAccessor ad, double factor);
607 
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 xfactor, double yfactor);
613  }
614  \endcode
615 
616  use argument objects in conjunction with \ref ArgumentObjectFactories :
617  \code
618  namespace vigra {
619  template <class SrcImageIterator, class SrcAccessor,
620  class DestImageIterator, class DestAccessor>
621  inline void
622  resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
623  pair<DestImageIterator, DestAccessor> dest, double factor);
624 
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 xfactor, double yfactor);
630  }
631  \endcode
632 
633  <b> Usage:</b>
634 
635  <b>\#include</b> <<a href="basicgeometry_8hxx-source.html">vigra/basicgeometry.hxx</a>><br>
636  Namespace: vigra
637 
638  \code
639  double factor = 2.0;
640  Image dest((int)(factor*src.width()), (int)(factor*src.height()));
641 
642  vigra::resampleImage(srcImageRange(src), destImage(dest), factor);
643 
644  \endcode
645 
646  <b> Required Interface:</b>
647 
648  \code
649  SrcImageIterator src_upperleft, src_lowerright;
650  DestImageIterator dest_upperleft;
651 
652  SrcAccessor src_accessor;
653 
654  dest_accessor.set(src_accessor(src_upperleft), dest_upperleft);
655 
656  \endcode
657 
658  <b> Preconditions:</b>
659 
660  \code
661  src_lowerright.x - src_upperleft.x > 1
662  src_lowerright.y - src_upperleft.y > 1
663  \endcode
664 
665 */
666 doxygen_overloaded_function(template <...> void resampleImage)
667 
668 template <class SrcIterator, class SrcAccessor,
669  class DestIterator, class DestAccessor>
670 void
671 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
672  DestIterator id, DestAccessor ad, double xfactor, double yfactor)
673 {
674  int width_old = iend.x - is.x;
675  int height_old = iend.y - is.y;
676 
677  //Bei Verkleinerung muss das dest-Bild ceiling(src*factor), da z.B.
678  //aus 6x6 grossem Bild wird eins 18x18 grosses gemacht bei Vergroesserungsfaktor 3.1
679  //umgekehrt damit wir vom 18x18 zu 6x6 (und nicht 5x5) bei Vergroesserung von 1/3.1
680  //muss das kleinste Integer das groesser als 18/3.1 ist genommen werden.
681  int height_new = sizeForResamplingFactor(height_old, yfactor);
682  int width_new = sizeForResamplingFactor(width_old, xfactor);
683 
684  vigra_precondition((width_old > 1) && (height_old > 1),
685  "resampleImage(): "
686  "Source image to small.\n");
687  vigra_precondition((width_new > 1) && (height_new > 1),
688  "resampleImage(): "
689  "Destination image to small.\n");
690 
691  typedef typename SrcAccessor::value_type SRCVT;
692  typedef BasicImage<SRCVT> TmpImage;
693  typedef typename TmpImage::traverser TmpImageIterator;
694 
695  BasicImage<SRCVT> tmp(width_old, height_new);
696 
697  int x,y;
698 
699  typename BasicImage<SRCVT>::Iterator yt = tmp.upperLeft();
700 
701  for(x=0; x<width_old; ++x, ++is.x, ++yt.x)
702  {
703  typename SrcIterator::column_iterator c1 = is.columnIterator();
704  typename TmpImageIterator::column_iterator ct = yt.columnIterator();
705  resampleLine(c1, c1 + height_old, sa, ct, tmp.accessor(), yfactor);
706  }
707 
708  yt = tmp.upperLeft();
709 
710  for(y=0; y < height_new; ++y, ++yt.y, ++id.y)
711  {
712  typename DestIterator::row_iterator rd = id.rowIterator();
713  typename TmpImageIterator::row_iterator rt = yt.rowIterator();
714  resampleLine(rt, rt + width_old, tmp.accessor(), rd, ad, xfactor);
715  }
716 
717 }
718 
719 template <class SrcIterator, class SrcAccessor,
720  class DestIterator, class DestAccessor>
721 void
722 resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
723  DestIterator id, DestAccessor ad, double factor)
724 {
725  resampleImage(is, iend, sa, id, ad, factor, factor);
726 }
727 
728 template <class SrcImageIterator, class SrcAccessor,
729  class DestImageIterator, class DestAccessor>
730 inline void
731 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
732  pair<DestImageIterator, DestAccessor> dest, double factor)
733 {
734  resampleImage(src.first, src.second, src.third, dest.first, dest.second, factor);
735 }
736 
737 template <class SrcImageIterator, class SrcAccessor,
738  class DestImageIterator, class DestAccessor>
739 inline void
740 resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
741  pair<DestImageIterator, DestAccessor> dest, double xfactor, double yfactor)
742 {
743  resampleImage(src.first, src.second, src.third, dest.first, dest.second, xfactor, yfactor);
744 }
745 
746 //@}
747 
748 } // namespace vigra
749 
750 
751 #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.7.1 (Wed Mar 12 2014)