SLAMflex SE  0.1.0
SLAMflex provides detection and tracking of dominant planes for smartphone devices. This plane can then be used to show AR content relative to the plane orientation. The detection of plane is performed in the field of view of the smartphone camera. In subsequent frames it is tracked. The interface returns the plane position and orientation.
image.h
Go to the documentation of this file.
1 /*
2  This file is part of the CVD Library.
3 
4  Copyright (C) 2005 The Authors
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc.,
19  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21 //-*- c++ -*-
23 // //
24 // CVD::image.h //
25 // //
26 // Definitions for of template class CVD::Image, fast_image //
27 // //
28 // derived from IPRS_* developed by Tom Drummond //
29 // Reworked to provide class heirachy and memory managementby E. Rosten//
30 // //
32 
33 #ifndef CVD_IMAGE_H
34 #define CVD_IMAGE_H
35 
36 #include <string.h>
37 #include "image_ref.h"
38 #include "exceptions.h"
39 #include <string>
40 #include <utility>
41 #include <iterator>
42 #include "aligned_mem.h"
43 
44 namespace CVD {
45 
46 namespace Exceptions {
47 
49  namespace Image {
52  struct All: public CVD::Exceptions::All {};
53 
56  struct IncompatibleImageSizes : public All {
57  IncompatibleImageSizes(const std::string & function)
58  {
59  what = "Incompatible image sizes in " + function;
60  };
61  };
62 
65  struct ImageRefNotInImage : public All {
66  ImageRefNotInImage(const std::string & function)
67  {
68  what = "Input ImageRefs not in image in " + function;
69  };
70  };
71  }
72 }
73 
74 namespace Internal
75 {
76  template<class C> class ImagePromise
77  {};
78 };
79 
80 
81 #define CVD_IMAGE_ASSERT(X,Y)
82 
83 
90 namespace ImageError
91 {
96 }
97 
98 
99 namespace ImageUtil
100 {
101  template<class T> inline void memfill(T* data, int n, const T val)
102  {
103  T* de = data + n;
104  for(;data < de; data++)
105  *data=val;
106  }
107 
108  template<> inline void memfill(unsigned char* data, int n, const unsigned char val)
109  {
110  memset(data, val, n);
111  }
112 
113  template<> inline void memfill(signed char* data, int n, const signed char val)
114  {
115  memset(data, val, n);
116  }
117 
118  template<> inline void memfill(char* data, int n, const char val)
119  {
120  memset(data, val, n);
121  }
122 }
123 
124 template<class T> class SubImage;
125 
126 
127 template<class T> class ConstSubImageIterator
128 {
129  public:
131  {
132  ptr++;
133  if(ptr == row_end)
134  {
135  ptr += row_increment;
136  row_end += total_width;
137 
138  if(ptr >= end)
139  end = NULL;
140  }
141  return *this;
142  }
143 
144  void operator++(int)
145  {
146  operator++();
147  }
148 
149  const T* operator->() const { return ptr; }
150  const T& operator*() const { return *ptr;}
151 
152  bool operator<(const ConstSubImageIterator& s) const
153  {
154  //It's illegal to iterate _past_ end(), so < is equivalent to !=
155  //for end iterators.
156  if(is_end && s.is_end)
157  return 0;
158  else if(is_end)
159  return s.end != NULL;
160  else if(s.is_end)
161  return end != NULL;
162  else
163  return ptr < s.ptr;
164  }
165 
166  bool operator==(const ConstSubImageIterator& s) const
167  {
168  return !((*this)!=s);
169  }
170 
171  bool operator!=(const ConstSubImageIterator& s) const
172  {
173  if(is_end && s.is_end)
174  return 0;
175  else if(is_end)
176  return s.end != NULL;
177  else if(s.is_end)
178  return end != NULL;
179  else
180  return ptr != s.ptr;
181  }
182 
183 
184  //Make it look like a standard iterator
185  typedef std::forward_iterator_tag iterator_category;
186  typedef T value_type;
187  typedef ptrdiff_t difference_type;
188  typedef const T* pointer;
189  typedef const T& reference;
190 
191 
192 
194  {}
195 
196  ConstSubImageIterator(const T* start, int image_width, int row_stride, const T* off_end)
197  :ptr(const_cast<T*>(start)),
198  row_end(start + image_width),
199  end(off_end),
200  is_end(0),
201  row_increment(row_stride-image_width),
202  total_width(row_stride)
203  { }
204 
205  //Prevent automatic conversion from a pointer (ie Image::iterator)
206  explicit ConstSubImageIterator(const T* end)
207  :ptr(const_cast<T*>(end)),is_end(1),row_increment(0),total_width(0)
208  { }
209 
210  protected:
211  T* ptr;
212  const T *row_end, *end;
213  bool is_end;
215 };
216 
217 template<class T> class SubImageIterator: public ConstSubImageIterator<T>
218 {
219  public:
220  SubImageIterator(T* start, int image_width, int row_stride, const T* off_end)
221  :ConstSubImageIterator<T>(start, image_width, row_stride, off_end)
222  {}
223 
224  explicit SubImageIterator(T* end)
225  :ConstSubImageIterator<T>(end)
226  { }
227 
229  {}
230 
231  typedef T* pointer;
232  typedef T& reference;
233 
236 };
237 
248 template<class T> class SubImage
249 {
250  public:
255  SubImage(T* data, const ImageRef& size, int stride)
256  :my_data(data),my_size(size),my_stride(stride)
257  {
258  }
259 
260 
263  bool in_image(const ImageRef& ir) const
264  {
265  return ir.x >=0 && ir.y >=0 && ir.x < my_size.x && ir.y < my_size.y;
266  }
267 
271  bool in_image_with_border(const ImageRef& ir, int border) const
272  {
273  return ir.x >=border && ir.y >=border && ir.x < my_size.x - border && ir.y < my_size.y - border;
274  }
275 
278  {}
279 
283  inline T& operator[](const ImageRef& pos)
284  {
286  return (my_data[pos.y*my_stride + pos.x]);
287  }
288 
292  inline const T& operator[](const ImageRef& pos) const
293  {
295  return (my_data[pos.y*my_stride + pos.x]);
296  }
297 
302  inline T* operator[](int row)
303  {
305  return my_data+row*my_stride;
306  }
307 
312  inline const T* operator[](int row) const
313  {
315  return my_data+row*my_stride;
316  }
317 
319  inline ImageRef pos(const T* ptr) const
320  {
321  int diff = ptr - data();
322  return ImageRef(diff % my_stride, diff / my_size.x);
323  }
324 
326  inline const T* data() const
327  {
328  return my_data;
329  }
330 
332  inline T* data()
333  {
334  return my_data;
335  }
336 
339 
341  inline iterator begin()
342  {
343  return SubImageIterator<T>(data(), size().x, my_stride, end_ptr());
344  }
346  inline const_iterator begin() const
347  {
349  }
350 
352  inline iterator end()
353  {
354  //Operator [] would always throw here!
355  return SubImageIterator<T>(end_ptr());
356  }
358  inline const_iterator end() const
359  {
360  //Operator [] would always throw here!
362  }
363 
364  inline void copy_from( const SubImage<T> & other ){
366  std::copy(other.begin(), other.end(), this->begin());
367  }
368 
370  inline ImageRef size() const
371  {
372  return my_size;
373  }
374 
376  inline int row_stride() const
377  {
378  return my_stride;
379  }
380 
382  inline int totalsize() const
383  {
384  return my_stride * my_size.y;
385  }
386 
388  inline void zero()
389  {
390  memset(my_data, 0, totalsize()*sizeof(T));
391  }
392 
395  inline void fill(const T d)
396  {
397  for(int y=0; y < my_size.y; y++)
398  ImageUtil::memfill( (*this)[y], my_size.x, d);
399  }
400 
403  SubImage(const SubImage& copyof)
404  {
405  my_size = copyof.my_size;
406  my_data = copyof.my_data;
407  my_stride = copyof.my_stride;
408  }
409 
410 
414  SubImage sub_image(const ImageRef& start, const ImageRef& size)
415  {
418  return SubImage( &operator[](start), size, my_stride);
419  }
420 
424  const SubImage sub_image(const ImageRef& start, const ImageRef& size) const
425  {
428 
429  T*ptr = my_data + start.y * my_stride + start.x;
430  return SubImage(ptr, size, my_stride);
431  }
432 
435  {
436  return *this;
437  }
438 
439  protected:
440  T* my_data;
442  int my_stride;
443 
445  T* end_ptr() { return my_data+my_size.y*my_stride; }
446 
448  const T* end_ptr() const { return my_data+my_size.y*my_stride; }
449 
451  {}
452 
453 };
454 
455 
471 template<class T> class BasicImage: public SubImage<T>
472 {
473  public:
478  :SubImage<T>(data, size, size.x)
479  {
480  }
481 
484  BasicImage(const BasicImage& copyof)
485  :SubImage<T>(copyof)
486  {
487  }
488 
489  void operator=(const BasicImage&copyof)
490  {
491  SubImage<T>::my_size = copyof.my_size;
492  SubImage<T>::my_data = copyof.my_data;
494  }
495 
498  {}
499 
503  typedef T* iterator;
507  typedef const T* const_iterator;
508 
511  const_iterator begin() const { return SubImage<T>::my_data; }
514  iterator begin() { return SubImage<T>::my_data; }
515 
518  const_iterator end() const { return SubImage<T>::my_data+SubImage<T>::totalsize(); }
522 
523 
524 
525  protected:
528  {}
529  private:
530 };
531 
532 
556 template<class T> class ImageCreationIterator: public std::iterator<std::input_iterator_tag, T, ptrdiff_t>
557 {
558  public:
559  void operator++(int) { num++; }
560  void operator++() { num++; }
561  bool operator==(const ImageCreationIterator& i){return num == i.num;}
562  bool operator!=(const ImageCreationIterator& i){return num != i.num;}
563 
564  const T& operator*() { return *construct_from_me; }
565 
566  ImageCreationIterator(const T& data)
567  :construct_from_me(&data),num(0){}
568 
570  :construct_from_me(0),num(i){}
571 
572  private:
574  int num;
575 };
576 
577 
580 template<class C> inline ImageCreationIterator<C> CreateImagesBegin(const C& from_me)
581 {
582  return ImageCreationIterator<C>(from_me);
583 }
587 template<class C> inline ImageCreationIterator<C> CreateImagesEnd(const C&, int i)
588 {
589  return ImageCreationIterator<C>(i);
590 }
591 
594 template<class C> inline ImageCreationIterator<C> CreateImagesEnd(int i)
595 {
596  return ImageCreationIterator<C>(i);
597 }
598 
616 template<class T>
617 class Image: public BasicImage<T>
618 {
619  private:
621  {
622  const Image* im;
623  };
624 
625  public:
629  Image(const Image& copy) :
630  BasicImage<T>(copy)
631  {
632  dup_from(&copy);
633  }
634 
635 
641  Image(const CopyPlaceHolder& c)
642  {
643  dup_from(NULL);
644  copy_from(*(c.im));
645  }
646 
649  CopyPlaceHolder copy_from_me() const
650  {
651  CopyPlaceHolder c = {this};
652  return c;
653  }
654 
655 
659  {
660  resize(copy.size());
661  std::copy(copy.begin(), copy.end(), this->begin());
662  }
663 
664 
665 
666 
670  {
671  Image<T> tmp(copy.size());
672  *this = tmp;
673 
674  std::copy(copy.begin(), copy.end(), this->begin());
675  }
676 
678  void make_unique()
679  {
680  if(*num_copies > 1)
681  {
682  Image<T> tmp(*this);
683  copy_from(tmp);
684  }
685  }
686 
690  const Image& operator=(const Image& copyof)
691  {
692  remove();
693  dup_from(&copyof);
694  return *this;
695  }
696 
697  template<class C> const Image& operator=(Internal::ImagePromise<C> p)
698  {
699  p.execute(*this);
700  return *this;
701  }
702 
703  template<class C> Image(Internal::ImagePromise<C> p)
704  {
705  dup_from(NULL);
706  p.execute(*this);
707  }
708 
711  {
712  dup_from(NULL);
713  }
714 
718  {
719  num_copies = new int;
720  *num_copies = 1;
721  this->my_size = size;
722  this->my_stride = size.x;
723  this->my_data = Internal::aligned_alloc<T>(this->totalsize(), 16);
724  }
725 
729  Image(const ImageRef& size, const T& val)
730  {
731  Image<T> tmp(size);
732  tmp.fill(val);
733  dup_from(&tmp);
734  }
735 
739  Image(const std::pair<ImageRef, T>& p)
740  {
741  Image<T> tmp(p.first);
742  tmp.fill(p.second);
743  dup_from(&tmp);
744  }
745 
749  void resize(const ImageRef& size)
750  {
751  if(size != BasicImage<T>::my_size || *num_copies > 1)
752  {
753  Image<T> new_im(size);
754  *this = new_im;
755  }
756  }
757 
760  //The resized image is filled with val.
763  void resize(const ImageRef& size, const T& val)
764  {
765  if(*num_copies > 1 || size != BasicImage<T>::my_size)
766  {
767  Image<T> new_im(size, val);
768  *this = new_im;
769  }
770  else fill(val);
771  }
772 
775  {
776  remove();
777  }
778 
779 
780  private:
781 
782 
783  int* num_copies; //Reference count.
784 
785  inline void remove() //Get rid of a reference to the data
786  {
787  if(this->my_data && *num_copies && --(*num_copies) == 0)
788  {
789  Internal::aligned_free<T>(this->my_data, this->totalsize());
790  this->my_data = 0;
791  delete num_copies;
792  num_copies = 0;
793  }
794  }
795 
796  inline void dup_from(const Image* copyof) //Duplicate from another image
797  {
798  if(copyof != NULL && copyof->my_data != NULL)
799  {
800  this->my_size = copyof->my_size;
801  this->my_stride = copyof->my_stride;
802  this->my_data = copyof->my_data;
803  num_copies = copyof->num_copies;
804  (*num_copies)++;
805  }
806  else
807  {
808  this->my_size.home();
809  this->my_stride=0;
810  this->my_data = 0;
811  num_copies = 0;
812  }
813  }
814 };
815 
816 
817 } // end namespace
818 #endif
#define CVD_IMAGE_ASSERT(X, Y)
Definition: image.h:81
SubImage & ref()
Return a reference to a SubImage. Useful for passing anonymous SubImages to functions.
Definition: image.h:434
Image(Internal::ImagePromise< C > p)
Definition: image.h:703
BasicImage(const BasicImage &copyof)
Definition: image.h:484
T * iterator
Definition: image.h:503
T * end_ptr()
Return an off-the-end pointer without ever throwing AccessOutsideImage.
Definition: image.h:445
int totalsize() const
What is the total number of elements in the image (i.e. size().x * size().y), including padding...
Definition: image.h:382
SubImageIterator< T > iterator
Definition: image.h:337
BasicImage(T *data, const ImageRef &size)
Definition: image.h:477
int y
The y co-ordinate.
Definition: image_ref.h:180
int x
The x co-ordinate.
Definition: image_ref.h:179
T & operator[](const ImageRef &pos)
Definition: image.h:283
ConstSubImageIterator(const T *start, int image_width, int row_stride, const T *off_end)
Definition: image.h:196
const T & operator*() const
Definition: image.h:150
void resize(const ImageRef &size)
Definition: image.h:749
T * operator[](int row)
Definition: image.h:302
void fill(const T d)
Definition: image.h:395
T * data()
Returns the raw image data.
Definition: image.h:332
Image(const ImageRef &size, const T &val)
Definition: image.h:729
SubImage(T *data, const ImageRef &size, int stride)
Definition: image.h:255
Image(const std::pair< ImageRef, T > &p)
Definition: image.h:739
ImageCreationIterator< C > CreateImagesEnd(const C &, int i)
Definition: image.h:587
iterator end()
Returns an iterator pointing to one past the end of the image.
Definition: image.h:352
~BasicImage()
The image data is not destroyed when a BasicImage is destroyed.
Definition: image.h:497
const SubImage sub_image(const ImageRef &start, const ImageRef &size) const
Definition: image.h:424
const T & operator[](const ImageRef &pos) const
Definition: image.h:292
void memfill(T *data, int n, const T val)
Definition: image.h:101
Definition: abs.h:24
ImageCreationIterator(const T &data)
Definition: image.h:566
ConstSubImageIterator< T > const_iterator
Definition: image.h:338
bool operator!=(const ImageCreationIterator &i)
Definition: image.h:562
void copy(const BasicImage< S > &in, BasicImage< T > &out, ImageRef size=ImageRef(-1,-1), ImageRef begin=ImageRef(), ImageRef dst=ImageRef())
Definition: utility.h:26
Image(const CopyPlaceHolder &c)
Definition: image.h:641
SubImageIterator(T *end)
Definition: image.h:224
SubImageIterator(T *start, int image_width, int row_stride, const T *off_end)
Definition: image.h:220
int row_stride() const
What is the row stride of the image?
Definition: image.h:376
void copy_from(const BasicImage< T > &copy)
Definition: image.h:658
void copy_from(const SubImage< T > &copy)
Definition: image.h:669
const Image & operator=(const Image &copyof)
Definition: image.h:690
Image(const Image &copy)
Definition: image.h:629
IncompatibleImageSizes(const std::string &function)
Definition: image.h:57
const T * const_iterator
Definition: image.h:507
ptrdiff_t difference_type
Definition: image.h:187
const T * operator[](int row) const
Definition: image.h:312
int my_stride
The row stride.
Definition: image.h:442
const T * end_ptr() const
Return an off-the-end pointer without ever throwing AccessOutsideImage.
Definition: image.h:448
int * num_copies
Definition: image.h:783
SubImage sub_image(const ImageRef &start, const ImageRef &size)
Definition: image.h:414
BasicImage()
The default constructor does nothing.
Definition: image.h:527
const ConstSubImageIterator & operator++()
Definition: image.h:130
Image(const ImageRef &size)
Definition: image.h:717
void make_unique()
Make this image independent of any copies (i.e. force a copy of the image data).
Definition: image.h:678
const T & operator*()
Definition: image.h:564
~SubImage()
The image data is not destroyed when a BasicImage is destroyed.
Definition: image.h:277
iterator end()
Definition: image.h:521
ImageRef size() const
What is the size of this image?
Definition: image.h:370
bool in_image_with_border(const ImageRef &ir, int border) const
Definition: image.h:271
~Image()
The destructor removes the image data.
Definition: image.h:774
ImageRefNotInImage(const std::string &function)
Definition: image.h:66
void copy_from(const SubImage< T > &other)
Definition: image.h:364
iterator begin()
Returns an iterator referencing the first (top-left) pixel in the image.
Definition: image.h:341
const T * data() const
Returns the raw image data.
Definition: image.h:326
Image()
Default constructor.
Definition: image.h:710
iterator begin()
Definition: image.h:514
ImageRef ir(const TooN::Vector< 2 > &v)
bool operator<(const ConstSubImageIterator &s) const
Definition: image.h:152
ImageCreationIterator(int i)
Definition: image.h:569
std::forward_iterator_tag iterator_category
Definition: image.h:185
void dup_from(const Image *copyof)
Definition: image.h:796
ImageRef my_size
The size of the image.
Definition: image.h:441
SubImage(const SubImage &copyof)
Definition: image.h:403
const_iterator end() const
Definition: image.h:518
const T * construct_from_me
Definition: image.h:573
void operator=(const BasicImage &copyof)
Definition: image.h:489
const_iterator begin() const
Definition: image.h:511
bool operator==(const ImageCreationIterator &i)
Definition: image.h:561
const Image & operator=(Internal::ImagePromise< C > p)
Definition: image.h:697
void home()
Resets the ImageRef to (0,0)
Definition: image_ref.h:240
const T * operator->() const
Definition: image.h:149
const_iterator begin() const
Returns a const iterator referencing the first (top-left) pixel in the image.
Definition: image.h:346
void zero()
Set all the pixels in the image to zero. This is a relatively fast operation, using memset...
Definition: image.h:388
ImageCreationIterator< C > CreateImagesBegin(const C &from_me)
Definition: image.h:580
std::string what
The error message.
Definition: exceptions.h:38
ConstSubImageIterator(const T *end)
Definition: image.h:206
ImageRef pos(const T *ptr) const
Given a pointer, this returns the image position as an ImageRef.
Definition: image.h:319
const Image * im
Definition: image.h:622
CopyPlaceHolder copy_from_me() const
Definition: image.h:649
T * my_data
The raw image data.
Definition: image.h:440
bool operator==(const ConstSubImageIterator &s) const
Definition: image.h:166
bool in_image(const ImageRef &ir) const
Definition: image.h:263
void resize(const ImageRef &size, const T &val)
Definition: image.h:763
bool operator!=(const ConstSubImageIterator &s) const
Definition: image.h:171
const_iterator end() const
Returns a const iterator pointing to one past the end of the image.
Definition: image.h:358