MIRA
ImgIterator.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
47 #ifndef _MIRA_IMGITERATOR_H_
48 #define _MIRA_IMGITERATOR_H_
49 
50 #include <opencv2/core/core.hpp>
51 
52 #include <geometry/Point.h>
53 
54 namespace mira {
55 
57 
58 /*
59  * Okay, enough is enough.
60  * The cv::Mat iterators were buggy in OpenCV 2.0, 2.1 and 2.2.
61  * Before OpenCV 2.2 typedefs for "pointer", "reference" and
62  * "iterator_category" were missing and hence the MatConstIterator_ iterator
63  * was not STL-compatible.
64  * In OpenCV 2.2. a couple of things were reorganized while forgetting to
65  * modify some type casts accordingly, resulting in compiler errors if methods
66  * like pos() were used, e.g.
67  *
68  * That's why we implement our own iterators (where most of the code was
69  * taken from the OpenCV 2.1 implementation though)
70  */
72 {
73 public:
74 
75  ImgIteratorBase() : m(NULL), ptr(NULL), sliceStart(NULL), sliceEnd(NULL) {}
76 
77  ImgIteratorBase(const cv::Mat* iMat) :
78  m(iMat), ptr(NULL), sliceStart(NULL), sliceEnd(NULL)
79  {
80  if( m && m->isContinuous() )
81  {
82  sliceStart = m->data;
83  sliceEnd = sliceStart + total(m)*m->elemSize();
84  }
85  seek(0);
86  }
87 
88  ImgIteratorBase(const cv::Mat* iMat, int iRow, int iCol=0) :
89  m(iMat), ptr(NULL), sliceStart(NULL), sliceEnd(NULL)
90  {
91  //assert(m && m->dims <= 2);
92  assert(m);
93  if( m->isContinuous() )
94  {
95  sliceStart = m->data;
96  sliceEnd = sliceStart + total(m)*m->elemSize();
97  }
98  ptrdiff_t ofs = iRow*m->step + iCol;
99  seek(ofs);
100  }
101 
102  // default copy constructor and assignment operators are fine
103 
105  ImgIteratorBase& operator += (ptrdiff_t ofs) {
106  if( !m || ofs == 0 )
107  return *this;
108  ptrdiff_t ofsb = ofs * m->elemSize();
109  ptr += ofsb;
110  if( ptr < sliceStart || sliceEnd <= ptr )
111  {
112  ptr -= ofsb;
113  seek(ofs, true);
114  }
115  return *this;
116  }
117 
119  ImgIteratorBase& operator -= (ptrdiff_t ofs) {
120  return (*this += -ofs);
121  }
122 
125  if( m && (ptr -= m->elemSize()) < sliceStart )
126  {
127  ptr += m->elemSize();
128  seek(-1, true);
129  }
130  return *this;
131  }
132 
135  if( m && (ptr += m->elemSize()) >= sliceEnd )
136  {
137  ptr -= m->elemSize();
138  seek(1, true);
139  }
140  return *this;
141  }
142 
144  Point2i pos() const {
145  if(!m)
146  return Point2i();
147  //assert( m->dims <= 2 );
148  ptrdiff_t ofs = ptr - m->data;
149  int y = (int)(ofs/step(m));
150  return Point2i((int)((ofs - y*step(m))/m->elemSize()), y);
151  }
152 
153  ptrdiff_t lpos() const;
154 
155  void seek(ptrdiff_t ofs, bool relative=false);
156 
157  const cv::Mat* m;
158  const uchar* ptr;
159  const uchar* sliceStart;
160  const uchar* sliceEnd;
161 
162 protected:
163 
164  static std::size_t total(const cv::Mat* m) {
165  return m->rows*m->cols;
166  }
167 
168  static std::size_t step(const cv::Mat* m) {
169  return m->step;
170  }
171 };
172 
174 
175 inline void ImgIteratorBase::seek(ptrdiff_t ofs, bool relative)
176 {
177  assert(m!=NULL);
178  std::size_t elemSize = m->elemSize();
179 
180  // empty matrix is not searchable
181  if (elemSize == 0 || m->total() == 0)
182  return;
183 
184  if( m->isContinuous() )
185  {
186  ptr = (relative ? ptr : sliceStart) + ofs*elemSize;
187  if( ptr < sliceStart )
188  ptr = sliceStart;
189  else if( ptr > sliceEnd )
190  ptr = sliceEnd;
191  return;
192  }
193 
194  //assert(m->dims==2);
195  ptrdiff_t ofs0, y;
196  if( relative )
197  {
198  ofs0 = ptr - m->data;
199  y = ofs0/step(m);
200  ofs += y*m->cols + (ofs0 - y*step(m))/elemSize;
201  }
202  y = ofs/m->cols;
203  int y1 = std::min(std::max((int)y, 0), m->rows-1);
204  sliceStart = m->data + y1*step(m);
205  sliceEnd = sliceStart + m->cols*elemSize;
206  ptr = y < 0 ? sliceStart : y >= m->rows ? sliceEnd :
207  sliceStart + (ofs - y*m->cols)*elemSize;
208 }
209 
210 inline ptrdiff_t ImgIteratorBase::lpos() const
211 {
212  if(!m)
213  return 0;
214 
215  std::size_t elemSize = m->elemSize();
216  if( m->isContinuous() )
217  return (ptr - sliceStart)/elemSize;
218  ptrdiff_t ofs = ptr - m->data;
219 
220  //assert(m->dims==2);
221  ptrdiff_t y = ofs/step(m);
222  return y*m->cols + (ofs - y*step(m))/elemSize;
223 }
224 
225 inline bool operator == (const ImgIteratorBase& a, const ImgIteratorBase& b)
226 { return a.m == b.m && a.ptr == b.ptr; }
227 
228 inline bool operator != (const ImgIteratorBase& a, const ImgIteratorBase& b)
229 { return !(a == b); }
230 
231 inline bool operator < (const ImgIteratorBase& a, const ImgIteratorBase& b)
232 { return a.ptr < b.ptr; }
233 
234 inline bool operator > (const ImgIteratorBase& a, const ImgIteratorBase& b)
235 { return a.ptr > b.ptr; }
236 
237 inline bool operator <= (const ImgIteratorBase& a, const ImgIteratorBase& b)
238 { return a.ptr <= b.ptr; }
239 
240 inline bool operator >= (const ImgIteratorBase& a, const ImgIteratorBase& b)
241 { return a.ptr >= b.ptr; }
242 
244 
245 #define MIRA_GENERATE_IMG_ITERATOR_OPS(IteratorType) \
246  \
247 IteratorType& operator+= (int ofs) { \
248  Base::operator+= (ofs); \
249  return *this; \
250 } \
251  \
252 IteratorType& operator-= (int ofs) { \
253  Base::operator += (-ofs); \
254  return *this; \
255 } \
256  \
257 IteratorType& operator--() { \
258  Base::operator--(); \
259  return *this; \
260 } \
261  \
262 IteratorType operator--(int){ \
263  IteratorType b = *this; \
264  Base::operator--(); \
265  return b; \
266 } \
267  \
268 IteratorType& operator++(){ \
269  Base::operator++(); \
270  return *this; \
271 } \
272  \
273 IteratorType operator++(int){ \
274  IteratorType b = *this; \
275  Base::operator++(); \
276  return b; \
277 }
278 
280 
286 template<typename T>
288 {
289  typedef ImgIteratorBase Base;
290 
291 public:
292  typedef T value_type;
293  typedef int difference_type;
294 
295  typedef const T* pointer;
296  typedef const T& reference;
297  typedef std::bidirectional_iterator_tag iterator_category;
298 
299 public:
300 
302  ImgConstIterator(const cv::Mat_<T>* m) : Base(m) {}
303 
304 public:
305 
307  const T& operator *() const { return *(const T*)(this->ptr); }
308 
310  const T* operator->() const { return (const T*)(this->ptr); }
311 
312 public:
314 };
315 
317 
323 template<typename T>
324 class ImgIterator : public ImgConstIterator<T>
325 {
326  typedef ImgConstIterator<T> Base;
327 public:
328 
329  typedef T* pointer;
330  typedef T& reference;
331 
332 public:
333 
335  ImgIterator(cv::Mat_<T>* m) : Base(m) {}
336 
337 public:
338 
340  T& operator *() { return *(T*)(this->ptr); } // casts constness away, but that is safe
341 
343  T* operator->() { return (T*)(this->ptr); }
344 
345 public:
347 };
348 
350 
352 {
353 public:
354 
355  template <typename T>
356  const T& at(std::size_t i) const {
357  return *((T*)this + i);
358  }
359 
360  template <typename T>
361  T& at(std::size_t i) {
362  return *((T*)this + i);
363  }
364 
365 };
366 
368 
375 {
376  typedef ImgIteratorBase Base;
377 public:
379  typedef int difference_type;
380 
383  typedef std::bidirectional_iterator_tag iterator_category;
384 
385 public:
386 
389 
390 public:
391 
392  reference operator *() const { return *getValue(); }
393  pointer operator->() const { return getValue(); }
394 
395 public:
396 
398 
399 protected:
400 
401  value_type* getValue() { return (value_type*)(ptr); }
402  const value_type* getValue() const { return (const value_type*)(ptr); }
403 
404 
405 };
406 
408 
409 
416 {
418 public:
419 
422 
423 public:
424 
427 
428 public:
429 
432 
435 
436 public:
437 
439 };
440 
442 
443 }
444 
445 #endif
T * operator->()
Dereferences to the Pixel.
Definition: ImgIterator.h:343
Untyped image iterator, that allows to iterate over images or image regions pixel by pixel similar to...
Definition: ImgIterator.h:415
ImgIteratorBase & operator--()
move backward one element
Definition: ImgIterator.h:124
bool operator<=(const ImgIteratorBase &a, const ImgIteratorBase &b)
Definition: ImgIterator.h:237
Point2i pos() const
returns the current iterator position
Definition: ImgIterator.h:144
ptrdiff_t lpos() const
Definition: ImgIterator.h:210
ImgConstIterator()
Definition: ImgIterator.h:301
T * pointer
Definition: ImgIterator.h:329
bool operator<(const ImgIteratorBase &a, const ImgIteratorBase &b)
Definition: ImgIterator.h:231
UntypedImgIteratorValue & reference
Definition: ImgIterator.h:421
General point class template.
Definition: Point.h:133
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
UntypedImgConstIterator(const cv::Mat *m)
Definition: ImgIterator.h:388
void seek(ptrdiff_t ofs, bool relative=false)
Definition: ImgIterator.h:175
Class for 2D, 3D and N-dimensional points.
Point< int, 2 > Point2i
a 2D integer point
Definition: Point.h:227
UntypedImgIteratorValue * pointer
Definition: ImgIterator.h:420
ImgConstIterator(const cv::Mat_< T > *m)
Definition: ImgIterator.h:302
const uchar * sliceStart
Definition: ImgIterator.h:159
UntypedImgIterator(cv::Mat *m)
Definition: ImgIterator.h:426
bool operator>(const ImgIteratorBase &a, const ImgIteratorBase &b)
Definition: ImgIterator.h:234
const value_type * getValue() const
Definition: ImgIterator.h:402
const T * operator->() const
Dereferences to the Pixel.
Definition: ImgIterator.h:310
static std::size_t total(const cv::Mat *m)
Definition: ImgIterator.h:164
std::bidirectional_iterator_tag iterator_category
Definition: ImgIterator.h:383
const T * pointer
Definition: ImgIterator.h:295
const UntypedImgIteratorValue * pointer
Definition: ImgIterator.h:381
ImgIteratorBase(const cv::Mat *iMat)
Definition: ImgIterator.h:77
ImgIteratorBase & operator-=(ptrdiff_t ofs)
shifts the iterator backward by the specified number of elements
Definition: ImgIterator.h:119
Definition: ImgIterator.h:71
static std::size_t step(const cv::Mat *m)
Definition: ImgIterator.h:168
int difference_type
Definition: ImgIterator.h:293
pointer operator->() const
Definition: ImgIterator.h:393
const cv::Mat * m
Definition: ImgIterator.h:157
reference operator*()
Dereferences to the Pixel.
Definition: ImgIterator.h:431
UntypedImgIterator()
Definition: ImgIterator.h:425
ImgIterator(cv::Mat_< T > *m)
Definition: ImgIterator.h:335
bool operator==(const ImgIteratorBase &a, const ImgIteratorBase &b)
Definition: ImgIterator.h:225
Const image iterator that allows to iterate over images or image regions pixel by pixel similar to it...
Definition: ImgIterator.h:287
std::bidirectional_iterator_tag iterator_category
Definition: ImgIterator.h:297
pointer operator->()
Dereferences to the Pixel.
Definition: ImgIterator.h:434
ImgIteratorBase & operator+=(ptrdiff_t ofs)
shifts the iterator forward by the specified number of elements
Definition: ImgIterator.h:105
UntypedImgIteratorValue value_type
Definition: ImgIterator.h:378
bool operator>=(const ImgIteratorBase &a, const ImgIteratorBase &b)
Definition: ImgIterator.h:240
ImgIteratorBase & operator++()
move forward one element
Definition: ImgIterator.h:134
ImgIteratorBase()
Definition: ImgIterator.h:75
reference operator*() const
Definition: ImgIterator.h:392
const T & reference
Definition: ImgIterator.h:296
UntypedImgConstIterator()
Definition: ImgIterator.h:387
ImgIteratorBase(const cv::Mat *iMat, int iRow, int iCol=0)
Definition: ImgIterator.h:88
Untyped const image iterator, that allows to iterate over images or image regions pixel by pixel simi...
Definition: ImgIterator.h:374
const UntypedImgIteratorValue & reference
Definition: ImgIterator.h:382
const T & operator*() const
Dereferences to the Pixel.
Definition: ImgIterator.h:307
bool operator!=(const ImgIteratorBase &a, const ImgIteratorBase &b)
Definition: ImgIterator.h:228
const uchar * sliceEnd
Definition: ImgIterator.h:160
Definition: ImgIterator.h:351
typedef Mat
#define MIRA_GENERATE_IMG_ITERATOR_OPS(IteratorType)
Definition: ImgIterator.h:245
T value_type
Definition: ImgIterator.h:292
const T & at(std::size_t i) const
Definition: ImgIterator.h:356
ImgIterator()
Definition: ImgIterator.h:334
value_type * getValue()
Definition: ImgIterator.h:401
T & reference
Definition: ImgIterator.h:330
int difference_type
Definition: ImgIterator.h:379
T & operator*()
Dereferences to the Pixel.
Definition: ImgIterator.h:340
T & at(std::size_t i)
Definition: ImgIterator.h:361
Image iterator that allows to iterate over images or image regions pixel by pixel similar to iterator...
Definition: ImgIterator.h:324
const uchar * ptr
Definition: ImgIterator.h:158