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

imagecontainer.hxx VIGRA

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_IMAGECONTAINER_HXX
37 #define VIGRA_IMAGECONTAINER_HXX
38 
39 #include "utilities.hxx"
40 #include "array_vector.hxx"
41 #include "copyimage.hxx"
42 
43 namespace vigra {
44 
45 /** \addtogroup ImageContainers Image Containers
46  Classes to manage multiple images (ImageArray..)
47 */
48 //@{
49 
50 /********************************************************/
51 /* */
52 /* ImageArray */
53 /* */
54 /********************************************************/
55 
56 /** \brief Fundamental class template for arrays of equal-sized images.
57 
58  An ImageArray manages an array of images of the type given as
59  template parameter. Use it like a ArrayVector<ImageType>, it has
60  the same interface, only operator< is missing from ImageArray. It
61  offers additional functions for resizing the images and querying
62  their common size. See \ref imageSize() for additional notes.
63 
64  A customized allocator can be passed as a template argument and via the constructor.
65  By default, the allocator of the <tt>ImageType</tt> is reused.
66 
67  <b>\#include</b> <vigra/imagecontainer.hxx> <br/>
68  Namespace: vigra
69 */
70 template <class ImageType,
71  class Alloc = typename ImageType::allocator_type::template rebind<ImageType>::other >
73 {
74  Size2D imageSize_;
75 
76 protected:
78  ImageVector images_;
79 
80 public:
81  /** the type of the contained values/images
82  */
83  typedef ImageType value_type;
84 
85  typedef typename ImageVector::iterator iterator;
86  typedef typename ImageVector::const_iterator const_iterator;
87  typedef typename ImageVector::reverse_iterator reverse_iterator;
88  typedef typename ImageVector::const_reverse_iterator const_reverse_iterator;
89  typedef typename ImageVector::reference reference;
90  typedef typename ImageVector::const_reference const_reference;
91 #if !defined(_MSC_VER) || _MSC_VER >= 1300
92  typedef typename ImageVector::pointer pointer;
93 #endif
94  typedef typename ImageVector::difference_type difference_type;
95  typedef typename ImageVector::size_type size_type;
96 
97  /** init an array of numImages equal-sized images; use the specified allocator.
98  */
99  ImageArray(unsigned int numImages, const Diff2D &imageSize,
100  Alloc const & alloc = Alloc())
101  : imageSize_(imageSize),
102  images_(numImages, ImageType(), alloc)
103  {
104  for(unsigned int i=0; i<numImages; i++)
105  images_[i].resize(Size2D(imageSize));
106  }
107 
108  /** Init an array of numImages equal-sized images. The size
109  depends on ImageType's default constructor (so it will
110  usually be 0x0); use the specified allocator.
111  */
112  ImageArray(unsigned int numImages= 0, Alloc const & alloc = Alloc())
113  : images_(numImages, alloc)
114  {
115  imageSize_= empty()? Size2D(0, 0) : front().size();
116  }
117 
118  /** fill constructor: Init an array with numImages copies of
119  the given image. (STL-Sequence interface); use the specified allocator.
120  */
121  ImageArray(unsigned int numImages, const ImageType &image, Alloc const & alloc = Alloc())
122  : imageSize_(image.size()),
123  images_(numImages, image, alloc)
124  {
125  }
126 
127  /** range constructor: Construct an array containing copies of
128  the images in [begin, end). Those images must all have the
129  same size, see \ref imageSize(). (STL-Sequence interface);
130  use the specified allocator.
131  */
132  template<class InputIterator>
133  ImageArray(InputIterator begin, InputIterator end, Alloc const & alloc = Alloc())
134  : imageSize_(begin!=end? (*begin).size() : Size2D(0,0)),
135  images_(begin, end, alloc)
136  {
137  }
138 
139  virtual ~ImageArray() {}
140 
141  /** Operator for a vector-like access to the contained images
142  (STL-Vector interface)
143  */
144  reference operator [](size_type index)
145  {
146  return images_[index];
147  }
148 
149  /** Operator for a vector-like access to the contained images
150  (STL-Vector interface)
151  */
152  const_reference operator [](size_type index) const
153  {
154  return images_[index];
155  }
156 
157  /** Returns an iterator pointing to the first image
158  (STL-Container interface)
159  */
160  iterator begin()
161  {
162  return images_.begin();
163  }
164 
165  /** Returns an iterator pointing to the first image
166  (STL-Container interface)
167  */
168  const_iterator begin() const
169  {
170  return images_.begin();
171  }
172 
173  /** Returns an iterator pointing behind the last image
174  (STL-Container interface)
175  */
176  iterator end()
177  {
178  return images_.end();
179  }
180 
181  /** Returns an iterator pointing behind the last image
182  (STL-Container interface)
183  */
184  const_iterator end() const
185  {
186  return images_.end();
187  }
188 
189  /** Returns a reverse_iterator pointing to the first image of
190  the reversed view of this array (STL-Reversable Container
191  interface)
192  */
193  reverse_iterator rbegin()
194  {
195  return images_.rbegin();
196  }
197 
198  /** Returns a reverse_iterator pointing to the first image of
199  the reversed view of this array (STL-Reversable Container
200  interface)
201  */
202  const_reverse_iterator rbegin() const
203  {
204  return images_.rbegin();
205  }
206 
207  /** Returns a reverse_iterator pointing behind the last image
208  of the reversed view of this array (STL-Reversable
209  Container interface)
210  */
211  reverse_iterator rend()
212  {
213  return images_.rend();
214  }
215 
216  /** Returns a reverse_iterator pointing behind the last image
217  of the reversed view of this array (STL-Reversable
218  Container interface)
219  */
220  const_reverse_iterator rend() const
221  {
222  return images_.rend();
223  }
224 
225  /** Query size of this ImageArray, that is: the number of
226  images. (STL-Container interface)
227  */
228  size_type size() const
229  {
230  return images_.size();
231  }
232 
233  /** Query maximum size of this ImageArray, that is: the
234  max. parameter you may pass to resize(). (STL-Container
235  interface)
236  */
237  size_type max_size() const
238  {
239  return images_.max_size();
240  }
241 
242  /** Returns true if and only if there are no contained
243  images. (STL-Container interface)
244  */
245  bool empty()
246  {
247  return images_.empty();
248  }
249 
250  /** Returns true if and only if both ImageArrays have exactly
251  the same contents and all images did compare equal with the
252  corresponding image in the other ImageArray. (STL-Forward
253  Container interface)
254  */
256  {
257  return (imageSize() == other.imageSize())
258  && (images_ == other.images_);
259  }
260 
261  /** Insert image at/before pos. (STL-Sequence interface)
262  */
263  iterator insert(iterator pos, const_reference image)
264  {
265  return images_.insert(pos, image);
266  }
267 
268  /** Insert count copies of image at/before pos. (STL-Sequence
269  interface)
270  */
271  void insert (iterator pos, size_type count, const_reference image);
272 
273  /** Insert copies of images from [begin, end) at/before
274  pos. (STL-Sequence interface)
275  */
276  template<class InputIterator>
277  void insert(iterator pos, InputIterator begin, InputIterator end)
278  {
279  images_.insert(pos, begin, end);
280  }
281 
282  /** Removes the image at pos from this array. (STL-Sequence
283  interface)
284  */
285  iterator erase(iterator pos)
286  {
287  return images_.erase(pos);
288  }
289 
290  /** Removes the images from [begin, end) from this
291  array. (STL-Sequence interface)
292  */
293  iterator erase(iterator begin, iterator end)
294  {
295  return images_.erase(begin, end);
296  }
297 
298  /** Empty this array. (STL-Sequence interface)
299  */
300  void clear()
301  {
302  images_.clear();
303  }
304 
305  /** Resize this ImageArray, throwing the last images away if
306  you make the array smaller or appending new images of the
307  right size at the end of the array if you make it
308  larger. (STL-Sequence interface)
309  */
310  void resize(size_type newSize)
311  {
312  if (newSize != size())
313  {
314  size_type oldSize= size();
315  images_.resize(newSize);
316  for (size_type i= oldSize; i<newSize; i++)
317  images_[i].resize(imageSize());
318  }
319  }
320 
321  /** Resize this ImageArray, throwing the last images away if
322  you make the array smaller or appending new copies of image
323  at the end of the array if you make it larger.
324  precondition: <tt>image.size() == imageSize()</tt>
325  (STL-Sequence interface)
326  */
327  void resize(size_type newSize, ImageType &image)
328  {
329  if (newSize != size())
330  {
331  vigra_precondition(image.size() == imageSize(),
332  "trying to append images of wrong size to ImageArray with resize()");
333  images_.resize(newSize, image);
334  }
335  }
336 
337  /** return the first image. (STL-Sequence interface)
338  */
339  reference front()
340  {
341  return images_.front();
342  }
343 
344  /** return the first image. (STL-Sequence interface)
345  */
346  const_reference front() const
347  {
348  return images_.front();
349  }
350 
351  /** return the last image. (STL-Vector interface)
352  */
353  reference back()
354  {
355  return images_.back();
356  }
357 
358  /** return the last image. (STL-Vector interface)
359  */
360  const_reference back() const
361  {
362  return images_.back();
363  }
364 
365  /** append image to array (STL-Back Insertion Sequence interface)
366  */
367  void push_back(const_reference image)
368  {
369  images_.push_back(image);
370  }
371 
372  /** remove last image from array (STL-Back Insertion Sequence interface)
373  */
374  void pop_back()
375  {
376  images_.pop_back();
377  }
378 
379  /** swap contents of this array with the contents of other
380  (STL-Container interface)
381  */
382  void swap(const_reference other)
383  {
384  Size2D oldImageSize = imageSize_;
385  images_.swap(other.images_);
386  imageSize_ = other.imageSize_;
387  other.imageSize_ = oldImageSize;
388  }
389 
390  /** number of image objects for which memory has been allocated
391  (STL-Vector interface)
392  */
393  size_type capacity() const
394  {
395  return images_.capacity();
396  }
397 
398  /** increase capacity(). (STL-Vector interface)
399  */
400  void reserve(size_type n)
401  {
402  images_.reserve(n);
403  }
404 
405  /** Query the size of the contained images. ImageArray will
406  maintain an array of equal-sized images of this
407  size. However, <em>do not resize the contained images
408  manually</em>. ImageArray currently has no way to detect or
409  prevent this.
410  */
412  { return imageSize_; }
413 
414  /** Resize all images to a common new size (No-op if
415  <tt>newSize == imageSize()</tt>). See \ref imageSize() for
416  an important note about resizing the images.
417  */
418  virtual void resizeImages(const Diff2D &newSize)
419  {
420  if (newSize!=imageSize())
421  {
422  for(unsigned int i=0; i<size(); i++)
423  images_[i].resize(Size2D(newSize));
424  imageSize_= newSize;
425  }
426  }
427 
428  /** Resize all images to a common new size (No-op if
429  <tt>newSize == imageSize()</tt>). See \ref imageSize() for
430  an important note about resizing the images.
431 
432  (Convenience function, same as calling
433  <tt>resizeImages(Diff2D(width, height));</tt>.)
434  */
435  void resizeImages(int width, int height)
436  {
437  resizeImages(Size2D(width, height));
438  }
439 };
440 
441 /********************************************************/
442 /* */
443 /* ImagePyramid */
444 /* */
445 /********************************************************/
446 
447 /** \brief Class template for logarithmically tapering image pyramids.
448 
449  An ImagePyramid manages an array of images of the type given as
450  template parameter, where each level has half the width and height
451  of its predecessor. It actually represents a sequence of pyramid
452  levels whose start and end index are configurable. For Burt-style
453  pyramids, see also \ref pyramidReduceBurtFilter and \ref
454  pyramidExpandBurtFilter.
455 
456  A customized allocator can be passed as a template argument and
457  via the constructor. By default, the allocator of the
458  <tt>ImageType</tt> is reused.
459 
460  <b>\#include</b> <vigra/imagecontainer.hxx> <br/>
461  Namespace: vigra
462 */
463 template <class ImageType,
464  class Alloc = typename ImageType::allocator_type::template rebind<ImageType>::other >
466 {
467  int lowestLevel_, highestLevel_;
468 
469 protected:
471  ImageVector images_;
472 
473 public:
474  /** the type of the contained values/images
475  */
476  typedef ImageType value_type;
477 
478  typedef typename ImageVector::iterator iterator;
479  typedef typename ImageVector::const_iterator const_iterator;
480  typedef typename ImageVector::reverse_iterator reverse_iterator;
481  typedef typename ImageVector::const_reverse_iterator const_reverse_iterator;
482  typedef typename ImageVector::reference reference;
483  typedef typename ImageVector::const_reference const_reference;
484 #if !defined(_MSC_VER) || _MSC_VER >= 1300
485  typedef typename ImageVector::pointer pointer;
486 #endif
487  typedef typename ImageVector::difference_type difference_type;
488  typedef int size_type;
489 
490  /** Init a pyramid between the given levels (inclusive).
491  *
492  * Allocate the given \a imageSize at the pyramid level given
493  * in \a sizeAppliesToLevel (default: level 0 / bottom) and
494  * size the other levels using recursive reduction/expansion
495  * by factors of 2. Use the specified allocator for image
496  * creation. The image type must be default constructible and
497  * resizable. sizeAppliesToLevel must be the in range
498  * lowestLevel..highestLevel (inclusive).
499  */
501  const Diff2D &imageSize, int sizeAppliesToLevel = 0,
502  Alloc const & alloc = Alloc())
503  : lowestLevel_(0), highestLevel_(-1),
504  images_(alloc)
505  {
506  resize(lowestLevel, highestLevel, imageSize, sizeAppliesToLevel);
507  }
508 
509  /**
510  * Init a pyramid between the given levels (inclusive).
511  *
512  * Copy the given \a image into the pyramid level given in \a
513  * copyImageToLevel (default: level 0 / bottom) and size the
514  * other levels using recursive reduction/expansion by factors
515  * of 2 (their image data is not initialized). Use the
516  * specified allocator for image creation. The image type
517  * must be default constructible and resizable.
518  * sizeAppliesToLevel must be the in range
519  * lowestLevel..highestLevel (inclusive).
520  */
521  ImagePyramid(int lowestLevel, int highestLevel,
522  const ImageType &image, int copyImageToLevel = 0,
523  Alloc const & alloc = Alloc())
524  : lowestLevel_(0), highestLevel_(-1),
525  images_(alloc)
526  {
527  resize(lowestLevel, highestLevel, image.size(), copyImageToLevel);
528  copyImage(srcImageRange(image), destImage((*this)[copyImageToLevel]));
529  }
530 
531  /**
532  * Init a pyramid between the given levels (inclusive).
533  *
534  * Copy the image given by the range \a ul to \a lr into the
535  * pyramid level given in \a copyImageToLevel (default: level
536  * 0 / bottom) and size the other levels using recursive
537  * reduction/expansion by factors of 2 (their image data is
538  * not initialized). Use the specified allocator for image
539  * creation. The image type must be default constructible and
540  * resizable. sizeAppliesToLevel must be the in range
541  * lowestLevel..highestLevel (inclusive).
542  */
543  template <class SrcIterator, class SrcAccessor>
544  ImagePyramid(int lowestLevel, int highestLevel,
545  SrcIterator ul, SrcIterator lr, SrcAccessor src,
546  int copyImageToLevel = 0,
547  Alloc const & alloc = Alloc())
548  : lowestLevel_(0), highestLevel_(-1),
549  images_(alloc)
550  {
551  resize(lowestLevel, highestLevel, lr - ul, copyImageToLevel);
552  copyImage(srcIterRange(ul, lr, src), destImage((*this)[copyImageToLevel]));
553  }
554 
555  /** Init an empty pyramid. Use the specified allocator.
556  */
557  ImagePyramid(Alloc const & alloc = Alloc())
558  : lowestLevel_(0), highestLevel_(-1),
559  images_(alloc)
560  {}
561 
562  virtual ~ImagePyramid() {}
563 
564  /** Get the index of the lowest allocated level of the pyramid.
565  */
566  int lowestLevel() const
567  {
568  return lowestLevel_;
569  }
570 
571  /** Get the index of the highest allocated level of the pyramid.
572  */
573  int highestLevel() const
574  {
575  return highestLevel_;
576  }
577 
578  /** Operator for a vector-like access to the contained images
579  (STL-Vector interface)
580  */
581  reference operator [](size_type index)
582  {
583  return images_[index - lowestLevel_];
584  }
585 
586  /** Operator for a vector-like access to the contained images
587  (STL-Vector interface)
588  */
589  const_reference operator [](size_type index) const
590  {
591  return images_[index - lowestLevel_];
592  }
593 
594  /** Returns an iterator pointing to the first image
595  (STL-Container interface)
596  */
597  iterator begin()
598  {
599  return images_.begin();
600  }
601 
602  /** Returns an iterator pointing to the first image
603  (STL-Container interface)
604  */
605  const_iterator begin() const
606  {
607  return images_.begin();
608  }
609 
610  /** Returns an iterator pointing behind the last image
611  (STL-Container interface)
612  */
613  iterator end()
614  {
615  return images_.end();
616  }
617 
618  /** Returns an iterator pointing behind the last image
619  (STL-Container interface)
620  */
621  const_iterator end() const
622  {
623  return images_.end();
624  }
625 
626  /** Returns a reverse_iterator pointing to the first image of
627  the reversed view of this array (STL-Reversable Container
628  interface)
629  */
630  reverse_iterator rbegin()
631  {
632  return images_.rbegin();
633  }
634 
635  /** Returns a reverse_iterator pointing to the first image of
636  the reversed view of this array (STL-Reversable Container
637  interface)
638  */
639  const_reverse_iterator rbegin() const
640  {
641  return images_.rbegin();
642  }
643 
644  /** Returns a reverse_iterator pointing behind the last image
645  of the reversed view of this array (STL-Reversable
646  Container interface)
647  */
648  reverse_iterator rend()
649  {
650  return images_.rend();
651  }
652 
653  /** Returns a reverse_iterator pointing behind the last image
654  of the reversed view of this array (STL-Reversable
655  Container interface)
656  */
657  const_reverse_iterator rend() const
658  {
659  return images_.rend();
660  }
661 
662  /** Query size of this ImageArray, that is: the number of
663  images. (STL-Container interface)
664  */
665  size_type size() const
666  {
667  return images_.size();
668  }
669 
670  /** Returns true if and only if there are no contained
671  images. (STL-Container interface)
672  */
673  bool empty()
674  {
675  return images_.empty();
676  }
677 
678  /** Returns true if and only if both ImageArrays have exactly
679  the same contents and all images did compare equal with the
680  corresponding image in the other ImageArray. (STL-Forward
681  Container interface)
682  */
684  {
685  return (lowestLevel_ == other.lowestLevel_) && (highestLevel_ == other.highestLevel_) &&
686  (images_ == other.images_);
687  }
688 
689  /** Empty this array. (STL-Sequence interface)
690  */
691  void clear()
692  {
693  images_.clear();
694  lowestLevel_ = 0;
695  highestLevel_ = -1;
696  }
697 
698  /** Resize this ImageArray, throwing the last images away if
699  you make the array smaller or appending new images of the
700  right size at the end of the array if you make it
701  larger. (STL-Sequence interface)
702  */
703  void resize(int lowestLevel, int highestLevel,
704  const Diff2D &imageSize, int sizeAppliesToLevel = 0)
705  {
706  vigra_precondition(lowestLevel <= highestLevel,
707  "ImagePyramid::resize(): lowestLevel <= highestLevel required.");
708  vigra_precondition(lowestLevel <= sizeAppliesToLevel && sizeAppliesToLevel <= highestLevel,
709  "ImagePyramid::resize(): sizeAppliesToLevel must be between lowest and highest level (inclusive).");
710 
711  ImageVector images(highestLevel - lowestLevel + 1, ImageType());
712 
713  images[sizeAppliesToLevel - lowestLevel].resize(imageSize);
714  for(int i=sizeAppliesToLevel + 1; i<=highestLevel; ++i)
715  {
716  unsigned int w = (images[i - 1 - lowestLevel].width() + 1) / 2;
717  unsigned int h = (images[i - 1 - lowestLevel].height() + 1) / 2;
718  images[i - lowestLevel].resize(w, h);
719  }
720  for(int i=sizeAppliesToLevel - 1; i>=lowestLevel; --i)
721  {
722  unsigned int w = 2*images[i + 1 - lowestLevel].width() - 1;
723  unsigned int h = 2*images[i + 1 - lowestLevel].height() - 1;
724  images[i - lowestLevel].resize(w, h);
725  }
726 
727  images_.swap(images);
728  lowestLevel_ = lowestLevel;
729  highestLevel_ = highestLevel;
730  }
731 
732  /** return the first image (lowestLevel()). (STL-Sequence interface)
733  */
734  reference front()
735  {
736  return images_.front();
737  }
738 
739  /** return the first image (lowestLevel()). (STL-Sequence interface)
740  */
741  const_reference front() const
742  {
743  return images_.front();
744  }
745 
746  /** return the last image (highestLevel()). (STL-Vector interface)
747  */
748  reference back()
749  {
750  return images_.back();
751  }
752 
753  /** return the last image (highestLevel()). (STL-Vector interface)
754  */
755  const_reference back() const
756  {
757  return images_.back();
758  }
759 
760  /** swap contents of this array with the contents of other
761  (STL-Container interface)
762  */
764  {
765  images_.swap(other.images_);
766  std::swap(lowestLevel_, other.lowestLevel_);
767  std::swap(highestLevel_, other.highestLevel_);
768  }
769 };
770 
771 //@}
772 
773 } // namespace vigra
774 
775 #endif // VIGRA_IMAGECONTAINER_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.10.0