opencv  2.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mat.hpp
Go to the documentation of this file.
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
16 //
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
19 //
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
22 //
23 // * Redistribution's in binary form must reproduce the above copyright notice,
24 // this list of conditions and the following disclaimer in the documentation
25 // and/or other materials provided with the distribution.
26 //
27 // * The name of the copyright holders may not be used to endorse or promote products
28 // derived from this software without specific prior written permission.
29 //
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
40 //
41 //M*/
42 
43 #ifndef __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
44 #define __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
45 
46 #ifndef SKIP_INCLUDES
47 #include <limits.h>
48 #include <string.h>
49 #endif // SKIP_INCLUDES
50 
51 #ifdef __cplusplus
52 
53 namespace cv
54 {
55 
57 
58 inline Mat::Mat()
59  : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
60  datastart(0), dataend(0), datalimit(0), allocator(0), size(&rows)
61 {
62 }
63 
64 inline Mat::Mat(int _rows, int _cols, int _type)
65  : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
66  datastart(0), dataend(0), datalimit(0), allocator(0), size(&rows)
67 {
68  create(_rows, _cols, _type);
69 }
70 
71 inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
72  : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
73  datastart(0), dataend(0), datalimit(0), allocator(0), size(&rows)
74 {
75  create(_rows, _cols, _type);
76  *this = _s;
77 }
78 
79 inline Mat::Mat(Size _sz, int _type)
80  : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
81  datastart(0), dataend(0), datalimit(0), allocator(0), size(&rows)
82 {
83  create( _sz.height, _sz.width, _type );
84 }
85 
86 inline Mat::Mat(Size _sz, int _type, const Scalar& _s)
87  : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
88  datastart(0), dataend(0), datalimit(0), allocator(0), size(&rows)
89 {
90  create(_sz.height, _sz.width, _type);
91  *this = _s;
92 }
93 
94 inline Mat::Mat(int _dims, const int* _sz, int _type)
95  : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
96  datastart(0), dataend(0), datalimit(0), allocator(0), size(&rows)
97 {
98  create(_dims, _sz, _type);
99 }
100 
101 inline Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s)
102  : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
103  datastart(0), dataend(0), datalimit(0), allocator(0), size(&rows)
104 {
105  create(_dims, _sz, _type);
106  *this = _s;
107 }
108 
109 inline Mat::Mat(const Mat& m)
110  : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
111  refcount(m.refcount), datastart(m.datastart), dataend(m.dataend),
112  datalimit(m.datalimit), allocator(m.allocator), size(&rows)
113 {
114  if( refcount )
115  CV_XADD(refcount, 1);
116  if( m.dims <= 2 )
117  {
118  step[0] = m.step[0]; step[1] = m.step[1];
119  }
120  else
121  {
122  dims = 0;
123  copySize(m);
124  }
125 }
126 
127 inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
128  : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
129  data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0),
130  datalimit(0), allocator(0), size(&rows)
131 {
132  size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz;
133  if( _step == AUTO_STEP )
134  {
135  _step = minstep;
137  }
138  else
139  {
140  if( rows == 1 ) _step = minstep;
141  CV_DbgAssert( _step >= minstep );
142  flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
143  }
144  step[0] = _step; step[1] = esz;
145  datalimit = datastart + _step*rows;
146  dataend = datalimit - _step + minstep;
147 }
148 
149 inline Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
150  : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
151  data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0),
152  datalimit(0), allocator(0), size(&rows)
153 {
154  size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz;
155  if( _step == AUTO_STEP )
156  {
157  _step = minstep;
159  }
160  else
161  {
162  if( rows == 1 ) _step = minstep;
163  CV_DbgAssert( _step >= minstep );
164  flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
165  }
166  step[0] = _step; step[1] = esz;
167  datalimit = datastart + _step*rows;
168  dataend = datalimit - _step + minstep;
169 }
170 
171 
172 inline Mat::Mat(const CvMat* m, bool copyData)
173  : flags(MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG))),
174  dims(2), rows(m->rows), cols(m->cols), data(m->data.ptr), refcount(0),
175  datastart(m->data.ptr), allocator(0), size(&rows)
176 {
177  if( !copyData )
178  {
179  size_t esz = CV_ELEM_SIZE(m->type), minstep = cols*esz, _step = m->step;
180  if( _step == 0 )
181  _step = minstep;
182  datalimit = datastart + _step*rows;
183  dataend = datalimit - _step + minstep;
184  step[0] = _step; step[1] = esz;
185  }
186  else
187  {
188  data = datastart = dataend = 0;
189  Mat(m->rows, m->cols, m->type, m->data.ptr, m->step).copyTo(*this);
190  }
191 }
192 
193 template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
194  : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
195  dims(2), rows((int)vec.size()), cols(1), data(0), refcount(0),
196  datastart(0), dataend(0), allocator(0), size(&rows)
197 {
198  if(vec.empty())
199  return;
200  if( !copyData )
201  {
202  step[0] = step[1] = sizeof(_Tp);
203  data = datastart = (uchar*)&vec[0];
205  }
206  else
207  Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
208 }
209 
210 
211 template<typename _Tp, int n> inline Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
212  : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
213  dims(2), rows(n), cols(1), data(0), refcount(0),
214  datastart(0), dataend(0), allocator(0), size(&rows)
215 {
216  if( !copyData )
217  {
218  step[0] = step[1] = sizeof(_Tp);
219  data = datastart = (uchar*)vec.val;
221  }
222  else
223  Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this);
224 }
225 
226 
227 template<typename _Tp, int m, int n> inline Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
228  : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
229  dims(2), rows(m), cols(n), data(0), refcount(0),
230  datastart(0), dataend(0), allocator(0), size(&rows)
231 {
232  if( !copyData )
233  {
234  step[0] = cols*sizeof(_Tp);
235  step[1] = sizeof(_Tp);
236  data = datastart = (uchar*)M.val;
237  datalimit = dataend = datastart + rows*step[0];
238  }
239  else
240  Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
241 }
242 
243 
244 template<typename _Tp> inline Mat::Mat(const Point_<_Tp>& pt, bool copyData)
245  : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
246  dims(2), rows(2), cols(1), data(0), refcount(0),
247  datastart(0), dataend(0), allocator(0), size(&rows)
248 {
249  if( !copyData )
250  {
251  step[0] = step[1] = sizeof(_Tp);
252  data = datastart = (uchar*)&pt.x;
254  }
255  else
256  {
258  ((_Tp*)data)[0] = pt.x;
259  ((_Tp*)data)[1] = pt.y;
260  }
261 }
262 
263 
264 template<typename _Tp> inline Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
265  : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
266  dims(2), rows(3), cols(1), data(0), refcount(0),
267  datastart(0), dataend(0), allocator(0), size(&rows)
268 {
269  if( !copyData )
270  {
271  step[0] = step[1] = sizeof(_Tp);
272  data = datastart = (uchar*)&pt.x;
274  }
275  else
276  {
278  ((_Tp*)data)[0] = pt.x;
279  ((_Tp*)data)[1] = pt.y;
280  ((_Tp*)data)[2] = pt.z;
281  }
282 }
283 
284 
285 template<typename _Tp> inline Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
286  : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
287  dims(0), rows(0), cols(0), data(0), refcount(0),
288  datastart(0), dataend(0), allocator(0), size(&rows)
289 {
290  *this = *commaInitializer;
291 }
292 
293 inline Mat::~Mat()
294 {
295  release();
296  if( step.p != step.buf )
297  fastFree(step.p);
298 }
299 
300 inline Mat& Mat::operator = (const Mat& m)
301 {
302  if( this != &m )
303  {
304  if( m.refcount )
305  CV_XADD(m.refcount, 1);
306  release();
307  flags = m.flags;
308  if( dims <= 2 && m.dims <= 2 )
309  {
310  dims = m.dims;
311  rows = m.rows;
312  cols = m.cols;
313  step[0] = m.step[0];
314  step[1] = m.step[1];
315  }
316  else
317  copySize(m);
318  data = m.data;
319  datastart = m.datastart;
320  dataend = m.dataend;
321  datalimit = m.datalimit;
322  refcount = m.refcount;
323  allocator = m.allocator;
324  }
325  return *this;
326 }
327 
328 inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); }
329 inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); }
330 inline Mat Mat::rowRange(int startrow, int endrow) const
331  { return Mat(*this, Range(startrow, endrow), Range::all()); }
332 inline Mat Mat::rowRange(const Range& r) const
333  { return Mat(*this, r, Range::all()); }
334 inline Mat Mat::colRange(int startcol, int endcol) const
335  { return Mat(*this, Range::all(), Range(startcol, endcol)); }
336 inline Mat Mat::colRange(const Range& r) const
337  { return Mat(*this, Range::all(), r); }
338 
339 inline Mat Mat::diag(const Mat& d)
340 {
341  Mat m(d.rows, d.rows, d.type(), Scalar(0)), md = m.diag();
342  d.copyTo(md);
343  return m;
344 }
345 
346 inline Mat Mat::clone() const
347 {
348  Mat m;
349  copyTo(m);
350  return m;
351 }
352 
353 inline void Mat::assignTo( Mat& m, int type ) const
354 {
355  if( type < 0 )
356  m = *this;
357  else
358  convertTo(m, type);
359 }
360 
361 inline void Mat::create(int _rows, int _cols, int _type)
362 {
363  _type &= TYPE_MASK;
364  if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
365  return;
366  int sz[] = {_rows, _cols};
367  create(2, sz, _type);
368 }
369 
370 inline void Mat::create(Size _sz, int _type)
371 {
372  create(_sz.height, _sz.width, _type);
373 }
374 
375 inline void Mat::addref()
376 { if( refcount ) CV_XADD(refcount, 1); }
377 
378 inline void Mat::release()
379 {
380  if( refcount && CV_XADD(refcount, -1) == 1 )
381  deallocate();
382  data = datastart = dataend = datalimit = 0;
383  size.p[0] = 0;
384  refcount = 0;
385 }
386 
387 inline Mat Mat::operator()( Range rowRange, Range colRange ) const
388 {
389  return Mat(*this, rowRange, colRange);
390 }
391 
392 inline Mat Mat::operator()( const Rect& roi ) const
393 { return Mat(*this, roi); }
394 
395 inline Mat Mat::operator()(const Range* ranges) const
396 {
397  return Mat(*this, ranges);
398 }
399 
400 inline Mat::operator CvMat() const
401 {
402  CV_DbgAssert(dims <= 2);
403  CvMat m = cvMat(rows, dims == 1 ? 1 : cols, type(), data);
404  m.step = (int)step[0];
405  m.type = (m.type & ~CONTINUOUS_FLAG) | (flags & CONTINUOUS_FLAG);
406  return m;
407 }
408 
409 inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
410 inline bool Mat::isSubmatrix() const { return (flags & SUBMATRIX_FLAG) != 0; }
411 inline size_t Mat::elemSize() const { return dims > 0 ? step.p[dims-1] : 0; }
412 inline size_t Mat::elemSize1() const { return CV_ELEM_SIZE1(flags); }
413 inline int Mat::type() const { return CV_MAT_TYPE(flags); }
414 inline int Mat::depth() const { return CV_MAT_DEPTH(flags); }
415 inline int Mat::channels() const { return CV_MAT_CN(flags); }
416 inline size_t Mat::step1(int i) const { return step.p[i]/elemSize1(); }
417 inline bool Mat::empty() const { return data == 0 || total() == 0; }
418 inline size_t Mat::total() const
419 {
420  if( dims <= 2 )
421  return rows*cols;
422  size_t p = 1;
423  for( int i = 0; i < dims; i++ )
424  p *= size[i];
425  return p;
426 }
427 
428 inline uchar* Mat::ptr(int y)
429 {
430  CV_DbgAssert( data && dims >= 1 && (unsigned)y < (unsigned)size.p[0] );
431  return data + step.p[0]*y;
432 }
433 
434 inline const uchar* Mat::ptr(int y) const
435 {
436  CV_DbgAssert( data && dims >= 1 && (unsigned)y < (unsigned)size.p[0] );
437  return data + step.p[0]*y;
438 }
439 
440 template<typename _Tp> inline _Tp* Mat::ptr(int y)
441 {
442  CV_DbgAssert( data && dims >= 1 && (unsigned)y < (unsigned)size.p[0] );
443  return (_Tp*)(data + step.p[0]*y);
444 }
445 
446 template<typename _Tp> inline const _Tp* Mat::ptr(int y) const
447 {
448  CV_DbgAssert( dims >= 1 && data && (unsigned)y < (unsigned)size.p[0] );
449  return (const _Tp*)(data + step.p[0]*y);
450 }
451 
452 
453 inline uchar* Mat::ptr(int i0, int i1)
454 {
455  CV_DbgAssert( dims >= 2 && data &&
456  (unsigned)i0 < (unsigned)size.p[0] &&
457  (unsigned)i1 < (unsigned)size.p[1] );
458  return data + i0*step.p[0] + i1*step.p[1];
459 }
460 
461 inline const uchar* Mat::ptr(int i0, int i1) const
462 {
463  CV_DbgAssert( dims >= 2 && data &&
464  (unsigned)i0 < (unsigned)size.p[0] &&
465  (unsigned)i1 < (unsigned)size.p[1] );
466  return data + i0*step.p[0] + i1*step.p[1];
467 }
468 
469 inline uchar* Mat::ptr(int i0, int i1, int i2)
470 {
471  CV_DbgAssert( dims >= 3 && data &&
472  (unsigned)i0 < (unsigned)size.p[0] &&
473  (unsigned)i1 < (unsigned)size.p[1] &&
474  (unsigned)i2 < (unsigned)size.p[2] );
475  return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2];
476 }
477 
478 inline const uchar* Mat::ptr(int i0, int i1, int i2) const
479 {
480  CV_DbgAssert( dims >= 3 && data &&
481  (unsigned)i0 < (unsigned)size.p[0] &&
482  (unsigned)i1 < (unsigned)size.p[1] &&
483  (unsigned)i2 < (unsigned)size.p[2] );
484  return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2];
485 }
486 
487 inline uchar* Mat::ptr(const int* idx)
488 {
489  int i, d = dims;
490  uchar* p = data;
491  CV_DbgAssert( d >= 1 && p );
492  for( i = 0; i < d; i++ )
493  {
494  CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
495  p += idx[i]*step.p[i];
496  }
497  return p;
498 }
499 
500 inline const uchar* Mat::ptr(const int* idx) const
501 {
502  int i, d = dims;
503  uchar* p = data;
504  CV_DbgAssert( d >= 1 && p );
505  for( i = 0; i < d; i++ )
506  {
507  CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
508  p += idx[i]*step.p[i];
509  }
510  return p;
511 }
512 
513 template<typename _Tp> inline _Tp& Mat::at(int i0, int i1)
514 {
515  CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
516  (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
518  return ((_Tp*)(data + step.p[0]*i0))[i1];
519 }
520 
521 template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1) const
522 {
523  CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
524  (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
526  return ((const _Tp*)(data + step.p[0]*i0))[i1];
527 }
528 
529 template<typename _Tp> inline _Tp& Mat::at(Point pt)
530 {
531  CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
532  (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
534  return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
535 }
536 
537 template<typename _Tp> inline const _Tp& Mat::at(Point pt) const
538 {
539  CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
540  (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
542  return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
543 }
544 
545 template<typename _Tp> inline _Tp& Mat::at(int i0)
546 {
547  CV_DbgAssert( dims <= 2 && data && (size.p[0] == 1 || size.p[1] == 1) &&
548  (unsigned)i0 < (unsigned)(size.p[0] + size.p[1] - 1) &&
550  return *(_Tp*)(data + step.p[size.p[0]==1]*i0);
551 }
552 
553 template<typename _Tp> inline const _Tp& Mat::at(int i0) const
554 {
555  CV_DbgAssert( dims <= 2 && data && (size.p[0] == 1 || size.p[1] == 1) &&
556  (unsigned)i0 < (unsigned)(size.p[0] + size.p[1] - 1) &&
558  return *(_Tp*)(data + step.p[size.p[0]==1]*i0);
559 }
560 
561 template<typename _Tp> inline _Tp& Mat::at(int i0, int i1, int i2)
562 {
564  return *(_Tp*)ptr(i0, i1, i2);
565 }
566 template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1, int i2) const
567 {
569  return *(const _Tp*)ptr(i0, i1, i2);
570 }
571 template<typename _Tp> inline _Tp& Mat::at(const int* idx)
572 {
574  return *(_Tp*)ptr(idx);
575 }
576 template<typename _Tp> inline const _Tp& Mat::at(const int* idx) const
577 {
579  return *(const _Tp*)ptr(idx);
580 }
581 
582 
583 template<typename _Tp> inline MatConstIterator_<_Tp> Mat::begin() const
584 {
585  CV_DbgAssert( elemSize() == sizeof(_Tp) );
586  return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
587 }
588 
589 template<typename _Tp> inline MatConstIterator_<_Tp> Mat::end() const
590 {
591  CV_DbgAssert( elemSize() == sizeof(_Tp) );
592  MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
593  it += total();
594  return it;
595 }
596 
597 template<typename _Tp> inline MatIterator_<_Tp> Mat::begin()
598 {
599  CV_DbgAssert( elemSize() == sizeof(_Tp) );
600  return MatIterator_<_Tp>((Mat_<_Tp>*)this);
601 }
602 
603 template<typename _Tp> inline MatIterator_<_Tp> Mat::end()
604 {
605  CV_DbgAssert( elemSize() == sizeof(_Tp) );
606  MatIterator_<_Tp> it((Mat_<_Tp>*)this);
607  it += total();
608  return it;
609 }
610 
611 
612 template<typename _Tp> inline void Mat::copyTo(vector<_Tp>& v) const
613 {
615  if( empty() || n == 0 )
616  {
617  v.clear();
618  return;
619  }
620  CV_Assert( n > 0 );
621  v.resize(n);
622  Mat temp(dims, size.p, DataType<_Tp>::type, &v[0]);
624 }
625 
626 template<typename _Tp> inline Mat::operator vector<_Tp>() const
627 {
628  vector<_Tp> v;
629  copyTo(v);
630  return v;
631 }
632 
633 template<typename _Tp, int n> inline Mat::operator Vec<_Tp, n>() const
634 {
635  CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
636  rows + cols - 1 == n && channels() == 1 );
637 
638  if( isContinuous() && type() == DataType<_Tp>::type )
639  return Vec<_Tp, n>((_Tp*)data);
640  Vec<_Tp, n> v; Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
641  convertTo(tmp, tmp.type());
642  return v;
643 }
644 
645 template<typename _Tp, int m, int n> inline Mat::operator Matx<_Tp, m, n>() const
646 {
647  CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
648 
649  if( isContinuous() && type() == DataType<_Tp>::type )
650  return Matx<_Tp, m, n>((_Tp*)data);
651  Matx<_Tp, m, n> mtx; Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
652  convertTo(tmp, tmp.type());
653  return mtx;
654 }
655 
656 
657 template<typename _Tp> inline void Mat::push_back(const _Tp& elem)
658 {
660  /* && dims == 2 (cols == 1 implies dims == 2) */);
661  uchar* tmp = dataend + step[0];
662  if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
663  {
664  *(_Tp*)(data + (size.p[0]++)*step.p[0]) = elem;
665  dataend = tmp;
666  }
667  else
668  push_back_(&elem);
669 }
670 
671 template<typename _Tp> inline void Mat::push_back(const Mat_<_Tp>& m)
672 {
673  push_back((const Mat&)m);
674 }
675 
676 inline Mat::MSize::MSize(int* _p) : p(_p) {}
678 {
679  CV_DbgAssert(p[-1] <= 2);
680  return Size(p[1], p[0]);
681 }
682 inline int Mat::MSize::operator[](int i) const { return p[i]; }
683 inline int& Mat::MSize::operator[](int i) { return p[i]; }
684 inline Mat::MSize::operator const int*() const { return p; }
685 
686 inline bool Mat::MSize::operator == (const MSize& sz) const
687 {
688  int d = p[-1], dsz = sz.p[-1];
689  if( d != dsz )
690  return false;
691  if( d == 2 )
692  return p[0] == sz.p[0] && p[1] == sz.p[1];
693 
694  for( int i = 0; i < d; i++ )
695  if( p[i] != sz.p[i] )
696  return false;
697  return true;
698 }
699 
700 inline bool Mat::MSize::operator != (const MSize& sz) const
701 {
702  return !(*this == sz);
703 }
704 
705 inline Mat::MStep::MStep() { p = buf; p[0] = p[1] = 0; }
706 inline Mat::MStep::MStep(size_t s) { p = buf; p[0] = s; p[1] = 0; }
707 inline size_t Mat::MStep::operator[](int i) const { return p[i]; }
708 inline size_t& Mat::MStep::operator[](int i) { return p[i]; }
709 inline Mat::MStep::operator size_t() const
710 {
711  CV_DbgAssert( p == buf );
712  return buf[0];
713 }
715 {
716  CV_DbgAssert( p == buf );
717  buf[0] = s;
718  return *this;
719 }
720 
721 static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0)
722 {
723  return cvarrToMat(arr, copyData, true, coiMode);
724 }
725 
727 
728 inline SVD::SVD() {}
729 inline SVD::SVD( const Mat& m, int flags ) { operator ()(m, flags); }
730 inline void SVD::solveZ( const Mat& m, Mat& dst )
731 {
732  SVD svd(m);
733  svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
734 }
735 
736 template<typename _Tp, int m, int n, int nm> inline void
738 {
739  assert( nm == MIN(m, n));
740  Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false);
741  SVD::compute(_a, _w, _u, _vt);
742  CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]);
743 }
744 
745 template<typename _Tp, int m, int n, int nm> inline void
747 {
748  assert( nm == MIN(m, n));
749  Mat _a(a, false), _w(w, false);
750  SVD::compute(_a, _w);
751  CV_Assert(_w.data == (uchar*)&w.val[0]);
752 }
753 
754 template<typename _Tp, int m, int n, int nm, int nb> inline void
756  const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs,
758 {
759  assert( nm == MIN(m, n));
760  Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false);
761  SVD::backSubst(_w, _u, _vt, _rhs, _dst);
762  CV_Assert(_dst.data == (uchar*)&dst.val[0]);
763 }
764 
766 
767 template<typename _Tp> inline Mat_<_Tp>::Mat_()
769 
770 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols)
771  : Mat(_rows, _cols, DataType<_Tp>::type) {}
772 
773 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
774  : Mat(_rows, _cols, DataType<_Tp>::type) { *this = value; }
775 
776 template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz)
777  : Mat(_sz.height, _sz.width, DataType<_Tp>::type) {}
778 
779 template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
780  : Mat(_sz.height, _sz.width, DataType<_Tp>::type) { *this = value; }
781 
782 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz)
783  : Mat(_dims, _sz, DataType<_Tp>::type) {}
784 
785 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
786  : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s)) {}
787 
788 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
789  : Mat(m, ranges) {}
790 
791 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat& m)
792  : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; *this = m; }
793 
794 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m)
795  : Mat(m) {}
796 
797 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
798  : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps) {}
799 
800 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& rowRange, const Range& colRange)
801  : Mat(m, rowRange, colRange) {}
802 
803 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
804  : Mat(m, roi) {}
805 
806 template<typename _Tp> template<int n> inline
807  Mat_<_Tp>::Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData)
808  : Mat(n/DataType<_Tp>::channels, 1, DataType<_Tp>::type, &vec)
809 {
811  if( copyData )
812  *this = clone();
813 }
814 
815 template<typename _Tp> template<int m, int n> inline
816  Mat_<_Tp>::Mat_(const Matx<typename DataType<_Tp>::channel_type,m,n>& M, bool copyData)
817  : Mat(m, n/DataType<_Tp>::channels, DataType<_Tp>::type, &M)
818 {
820  if( copyData )
821  *this = clone();
822 }
823 
824 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
825  : Mat(2/DataType<_Tp>::channels, 1, DataType<_Tp>::type, &pt)
826 {
828  if( copyData )
829  *this = clone();
830 }
831 
832 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
833  : Mat(3/DataType<_Tp>::channels, 1, DataType<_Tp>::type, &pt)
834 {
836  if( copyData )
837  *this = clone();
838 }
839 
840 template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
841  : Mat(commaInitializer) {}
842 
843 template<typename _Tp> inline Mat_<_Tp>::Mat_(const vector<_Tp>& vec, bool copyData)
844  : Mat(vec, copyData) {}
845 
846 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
847 {
848  if( DataType<_Tp>::type == m.type() )
849  {
850  Mat::operator = (m);
851  return *this;
852  }
853  if( DataType<_Tp>::depth == m.depth() )
854  {
855  return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
856  }
858  m.convertTo(*this, type());
859  return *this;
860 }
861 
862 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
863 {
864  Mat::operator=(m);
865  return *this;
866 }
867 
868 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
869 {
870  typedef typename DataType<_Tp>::vec_type VT;
871  Mat::operator=(Scalar((const VT&)s));
872  return *this;
873 }
874 
875 
876 template<typename _Tp> inline void Mat_<_Tp>::create(int _rows, int _cols)
877 {
878  Mat::create(_rows, _cols, DataType<_Tp>::type);
879 }
880 
881 template<typename _Tp> inline void Mat_<_Tp>::create(Size _sz)
882 {
884 }
885 
886 template<typename _Tp> inline void Mat_<_Tp>::create(int _dims, const int* _sz)
887 {
888  Mat::create(_dims, _sz, DataType<_Tp>::type);
889 }
890 
891 
892 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
893 { return Mat_<_Tp>(Mat::cross(m)); }
894 
895 template<typename _Tp> template<typename T2> inline Mat_<_Tp>::operator Mat_<T2>() const
896 { return Mat_<T2>(*this); }
897 
898 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::row(int y) const
899 { return Mat_(*this, Range(y, y+1), Range::all()); }
900 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::col(int x) const
901 { return Mat_(*this, Range::all(), Range(x, x+1)); }
902 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::diag(int d) const
903 { return Mat_(Mat::diag(d)); }
904 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::clone() const
905 { return Mat_(Mat::clone()); }
906 
907 template<typename _Tp> inline size_t Mat_<_Tp>::elemSize() const
908 {
909  CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
910  return sizeof(_Tp);
911 }
912 
913 template<typename _Tp> inline size_t Mat_<_Tp>::elemSize1() const
914 {
916  return sizeof(_Tp)/DataType<_Tp>::channels;
917 }
918 template<typename _Tp> inline int Mat_<_Tp>::type() const
919 {
921  return DataType<_Tp>::type;
922 }
923 template<typename _Tp> inline int Mat_<_Tp>::depth() const
924 {
926  return DataType<_Tp>::depth;
927 }
928 template<typename _Tp> inline int Mat_<_Tp>::channels() const
929 {
932 }
933 template<typename _Tp> inline size_t Mat_<_Tp>::stepT(int i) const { return step.p[i]/elemSize(); }
934 template<typename _Tp> inline size_t Mat_<_Tp>::step1(int i) const { return step.p[i]/elemSize1(); }
935 
936 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::reshape(int _rows) const
937 { return Mat_<_Tp>(Mat::reshape(0,_rows)); }
938 
939 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
940 { return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright)); }
941 
942 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range& rowRange, const Range& colRange ) const
943 { return Mat_<_Tp>(*this, rowRange, colRange); }
944 
945 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
946 { return Mat_<_Tp>(*this, roi); }
947 
948 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
949 { return Mat_<_Tp>(*this, ranges); }
950 
951 template<typename _Tp> inline _Tp* Mat_<_Tp>::operator [](int y)
952 { return (_Tp*)ptr(y); }
953 template<typename _Tp> inline const _Tp* Mat_<_Tp>::operator [](int y) const
954 { return (const _Tp*)ptr(y); }
955 
956 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1)
957 {
958  CV_DbgAssert( dims <= 2 && data &&
959  (unsigned)i0 < (unsigned)size.p[0] &&
960  (unsigned)i1 < (unsigned)size.p[1] &&
961  type() == DataType<_Tp>::type );
962  return ((_Tp*)(data + step.p[0]*i0))[i1];
963 }
964 
965 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const
966 {
967  CV_DbgAssert( dims <= 2 && data &&
968  (unsigned)i0 < (unsigned)size.p[0] &&
969  (unsigned)i1 < (unsigned)size.p[1] &&
970  type() == DataType<_Tp>::type );
971  return ((const _Tp*)(data + step.p[0]*i0))[i1];
972 }
973 
974 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(Point pt)
975 {
976  CV_DbgAssert( dims <= 2 && data &&
977  (unsigned)pt.y < (unsigned)size.p[0] &&
978  (unsigned)pt.x < (unsigned)size.p[1] &&
979  type() == DataType<_Tp>::type );
980  return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
981 }
982 
983 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(Point pt) const
984 {
985  CV_DbgAssert( dims <= 2 && data &&
986  (unsigned)pt.y < (unsigned)size.p[0] &&
987  (unsigned)pt.x < (unsigned)size.p[1] &&
988  type() == DataType<_Tp>::type );
989  return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
990 }
991 
992 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(const int* idx)
993 {
994  return Mat::at<_Tp>(idx);
995 }
996 
997 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
998 {
999  return Mat::at<_Tp>(idx);
1000 }
1001 
1002 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0)
1003 {
1004  return this->at<_Tp>(i0);
1005 }
1006 
1007 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0) const
1008 {
1009  return this->at<_Tp>(i0);
1010 }
1011 
1012 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
1013 {
1014  return this->at<_Tp>(i0, i1, i2);
1015 }
1016 
1017 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
1018 {
1019  return this->at<_Tp>(i0, i1, i2);
1020 }
1021 
1022 
1023 template<typename _Tp> inline Mat_<_Tp>::operator vector<_Tp>() const
1024 {
1025  vector<_Tp> v;
1026  copyTo(v);
1027  return v;
1028 }
1029 
1030 template<typename _Tp> template<int n> inline Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
1031 {
1033  return this->Mat::operator Vec<typename DataType<_Tp>::channel_type, n>();
1034 }
1035 
1036 template<typename _Tp> template<int m, int n> inline Mat_<_Tp>::operator Matx<typename DataType<_Tp>::channel_type, m, n>() const
1037 {
1039  return this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
1040 }
1041 
1042 template<typename T1, typename T2, typename Op> inline void
1043 process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
1044 {
1045  int y, x, rows = m1.rows, cols = m1.cols;
1046  int c1 = m1.channels(), c2 = m2.channels();
1047 
1048  CV_DbgAssert( m1.size() == m2.size() );
1049 
1050  for( y = 0; y < rows; y++ )
1051  {
1052  const T1* src = m1[y];
1053  T2* dst = m2[y];
1054 
1055  for( x = 0; x < cols; x++ )
1056  dst[x] = op(src[x]);
1057  }
1058 }
1059 
1060 template<typename T1, typename T2, typename T3, typename Op> inline void
1061 process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
1062 {
1063  int y, x, rows = m1.rows, cols = m1.cols;
1064 
1065  CV_DbgAssert( m1.size() == m2.size() );
1066 
1067  for( y = 0; y < rows; y++ )
1068  {
1069  const T1* src1 = m1[y];
1070  const T2* src2 = m2[y];
1071  T3* dst = m3[y];
1072 
1073  for( x = 0; x < cols; x++ )
1074  dst[x] = op( src1[x], src2[x] );
1075  }
1076 }
1077 
1079 
1081 {
1082 public:
1083  MatOp() {};
1084  virtual ~MatOp() {};
1085 
1086  virtual bool elementWise(const MatExpr& expr) const;
1087  virtual void assign(const MatExpr& expr, Mat& m, int type=-1) const = 0;
1088  virtual void roi(const MatExpr& expr, const Range& rowRange,
1089  const Range& colRange, MatExpr& res) const;
1090  virtual void diag(const MatExpr& expr, int d, MatExpr& res) const;
1091  virtual void augAssignAdd(const MatExpr& expr, Mat& m) const;
1092  virtual void augAssignSubtract(const MatExpr& expr, Mat& m) const;
1093  virtual void augAssignMultiply(const MatExpr& expr, Mat& m) const;
1094  virtual void augAssignDivide(const MatExpr& expr, Mat& m) const;
1095  virtual void augAssignAnd(const MatExpr& expr, Mat& m) const;
1096  virtual void augAssignOr(const MatExpr& expr, Mat& m) const;
1097  virtual void augAssignXor(const MatExpr& expr, Mat& m) const;
1098 
1099  virtual void add(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
1100  virtual void add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const;
1101 
1102  virtual void subtract(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
1103  virtual void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const;
1104 
1105  virtual void multiply(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const;
1106  virtual void multiply(const MatExpr& expr1, double s, MatExpr& res) const;
1107 
1108  virtual void divide(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const;
1109  virtual void divide(double s, const MatExpr& expr, MatExpr& res) const;
1110 
1111  virtual void abs(const MatExpr& expr, MatExpr& res) const;
1112 
1113  virtual void transpose(const MatExpr& expr, MatExpr& res) const;
1114  virtual void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
1115  virtual void invert(const MatExpr& expr, int method, MatExpr& res) const;
1116 };
1117 
1118 
1120 {
1121 public:
1122  MatExpr() : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s(Scalar()) {}
1123  MatExpr(const MatOp* _op, int _flags, const Mat& _a=Mat(), const Mat& _b=Mat(),
1124  const Mat& _c=Mat(), double _alpha=1, double _beta=1, const Scalar& _s=Scalar())
1125  : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s) {}
1126  explicit MatExpr(const Mat& m);
1127  operator Mat() const
1128  {
1129  Mat m;
1130  op->assign(*this, m);
1131  return m;
1132  }
1133 
1134  template<typename _Tp> operator Mat_<_Tp>() const
1135  {
1136  Mat_<_Tp> m;
1137  op->assign(*this, m, DataType<_Tp>::type);
1138  return m;
1139  }
1140 
1141  MatExpr row(int y) const;
1142  MatExpr col(int x) const;
1143  MatExpr diag(int d=0) const;
1144  MatExpr operator()( const Range& rowRange, const Range& colRange ) const;
1145  MatExpr operator()( const Rect& roi ) const;
1146 
1147  Mat cross(const Mat& m) const;
1148  double dot(const Mat& m) const;
1149 
1150  MatExpr t() const;
1151  MatExpr inv(int method = DECOMP_LU) const;
1152  MatExpr mul(const MatExpr& e, double scale=1) const;
1153  MatExpr mul(const Mat& m, double scale=1) const;
1154 
1155  const MatOp* op;
1156  int flags;
1157 
1158  Mat a, b, c;
1159  double alpha, beta;
1161 };
1162 
1163 
1164 CV_EXPORTS MatExpr operator + (const Mat& a, const Mat& b);
1165 CV_EXPORTS MatExpr operator + (const Mat& a, const Scalar& s);
1166 CV_EXPORTS MatExpr operator + (const Scalar& s, const Mat& a);
1167 CV_EXPORTS MatExpr operator + (const MatExpr& e, const Mat& m);
1168 CV_EXPORTS MatExpr operator + (const Mat& m, const MatExpr& e);
1169 CV_EXPORTS MatExpr operator + (const MatExpr& e, const Scalar& s);
1170 CV_EXPORTS MatExpr operator + (const Scalar& s, const MatExpr& e);
1171 CV_EXPORTS MatExpr operator + (const MatExpr& e1, const MatExpr& e2);
1172 
1173 CV_EXPORTS MatExpr operator - (const Mat& a, const Mat& b);
1174 CV_EXPORTS MatExpr operator - (const Mat& a, const Scalar& s);
1175 CV_EXPORTS MatExpr operator - (const Scalar& s, const Mat& a);
1176 CV_EXPORTS MatExpr operator - (const MatExpr& e, const Mat& m);
1177 CV_EXPORTS MatExpr operator - (const Mat& m, const MatExpr& e);
1178 CV_EXPORTS MatExpr operator - (const MatExpr& e, const Scalar& s);
1179 CV_EXPORTS MatExpr operator - (const Scalar& s, const MatExpr& e);
1180 CV_EXPORTS MatExpr operator - (const MatExpr& e1, const MatExpr& e2);
1181 
1182 CV_EXPORTS MatExpr operator - (const Mat& m);
1184 
1185 CV_EXPORTS MatExpr operator * (const Mat& a, const Mat& b);
1186 CV_EXPORTS MatExpr operator * (const Mat& a, double s);
1187 CV_EXPORTS MatExpr operator * (double s, const Mat& a);
1188 CV_EXPORTS MatExpr operator * (const MatExpr& e, const Mat& m);
1189 CV_EXPORTS MatExpr operator * (const Mat& m, const MatExpr& e);
1190 CV_EXPORTS MatExpr operator * (const MatExpr& e, double s);
1191 CV_EXPORTS MatExpr operator * (double s, const MatExpr& e);
1192 CV_EXPORTS MatExpr operator * (const MatExpr& e1, const MatExpr& e2);
1193 
1194 CV_EXPORTS MatExpr operator / (const Mat& a, const Mat& b);
1195 CV_EXPORTS MatExpr operator / (const Mat& a, double s);
1196 CV_EXPORTS MatExpr operator / (double s, const Mat& a);
1197 CV_EXPORTS MatExpr operator / (const MatExpr& e, const Mat& m);
1198 CV_EXPORTS MatExpr operator / (const Mat& m, const MatExpr& e);
1199 CV_EXPORTS MatExpr operator / (const MatExpr& e, double s);
1200 CV_EXPORTS MatExpr operator / (double s, const MatExpr& e);
1201 CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2);
1202 
1203 CV_EXPORTS MatExpr operator < (const Mat& a, const Mat& b);
1204 CV_EXPORTS MatExpr operator < (const Mat& a, double s);
1205 CV_EXPORTS MatExpr operator < (double s, const Mat& a);
1206 
1207 CV_EXPORTS MatExpr operator <= (const Mat& a, const Mat& b);
1208 CV_EXPORTS MatExpr operator <= (const Mat& a, double s);
1209 CV_EXPORTS MatExpr operator <= (double s, const Mat& a);
1210 
1211 CV_EXPORTS MatExpr operator == (const Mat& a, const Mat& b);
1212 CV_EXPORTS MatExpr operator == (const Mat& a, double s);
1213 CV_EXPORTS MatExpr operator == (double s, const Mat& a);
1214 
1215 CV_EXPORTS MatExpr operator != (const Mat& a, const Mat& b);
1216 CV_EXPORTS MatExpr operator != (const Mat& a, double s);
1217 CV_EXPORTS MatExpr operator != (double s, const Mat& a);
1218 
1219 CV_EXPORTS MatExpr operator >= (const Mat& a, const Mat& b);
1220 CV_EXPORTS MatExpr operator >= (const Mat& a, double s);
1221 CV_EXPORTS MatExpr operator >= (double s, const Mat& a);
1222 
1223 CV_EXPORTS MatExpr operator > (const Mat& a, const Mat& b);
1224 CV_EXPORTS MatExpr operator > (const Mat& a, double s);
1225 CV_EXPORTS MatExpr operator > (double s, const Mat& a);
1226 
1227 CV_EXPORTS MatExpr min(const Mat& a, const Mat& b);
1228 CV_EXPORTS MatExpr min(const Mat& a, double s);
1229 CV_EXPORTS MatExpr min(double s, const Mat& a);
1230 
1231 CV_EXPORTS MatExpr max(const Mat& a, const Mat& b);
1232 CV_EXPORTS MatExpr max(const Mat& a, double s);
1233 CV_EXPORTS MatExpr max(double s, const Mat& a);
1234 
1235 template<typename _Tp> static inline MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1236 {
1237  return cv::min((const Mat&)a, (const Mat&)b);
1238 }
1239 
1240 template<typename _Tp> static inline MatExpr min(const Mat_<_Tp>& a, double s)
1241 {
1242  return cv::min((const Mat&)a, s);
1243 }
1244 
1245 template<typename _Tp> static inline MatExpr min(double s, const Mat_<_Tp>& a)
1246 {
1247  return cv::min((const Mat&)a, s);
1248 }
1249 
1250 template<typename _Tp> static inline MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1251 {
1252  return cv::max((const Mat&)a, (const Mat&)b);
1253 }
1254 
1255 template<typename _Tp> static inline MatExpr max(const Mat_<_Tp>& a, double s)
1256 {
1257  return cv::max((const Mat&)a, s);
1258 }
1259 
1260 template<typename _Tp> static inline MatExpr max(double s, const Mat_<_Tp>& a)
1261 {
1262  return cv::max((const Mat&)a, s);
1263 }
1264 
1265 CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b);
1266 CV_EXPORTS MatExpr operator & (const Mat& a, const Scalar& s);
1267 CV_EXPORTS MatExpr operator & (const Scalar& s, const Mat& a);
1268 
1269 CV_EXPORTS MatExpr operator | (const Mat& a, const Mat& b);
1270 CV_EXPORTS MatExpr operator | (const Mat& a, const Scalar& s);
1271 CV_EXPORTS MatExpr operator | (const Scalar& s, const Mat& a);
1272 
1273 CV_EXPORTS MatExpr operator ^ (const Mat& a, const Mat& b);
1274 CV_EXPORTS MatExpr operator ^ (const Mat& a, const Scalar& s);
1275 CV_EXPORTS MatExpr operator ^ (const Scalar& s, const Mat& a);
1276 
1277 CV_EXPORTS MatExpr operator ~(const Mat& m);
1278 
1279 CV_EXPORTS MatExpr abs(const Mat& m);
1280 CV_EXPORTS MatExpr abs(const MatExpr& e);
1281 
1282 template<typename _Tp> static inline MatExpr abs(const Mat_<_Tp>& m)
1283 {
1284  return cv::abs((const Mat&)m);
1285 }
1286 
1288 
1289 inline Mat& Mat::operator = (const MatExpr& e)
1290 {
1291  e.op->assign(e, *this);
1292  return *this;
1293 }
1294 
1295 template<typename _Tp> Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e)
1296 {
1297  e.op->assign(e, *this, DataType<_Tp>::type);
1298  return *this;
1299 }
1300 
1301 static inline Mat& operator += (const Mat& a, const Mat& b)
1302 {
1303  add(a, b, (Mat&)a);
1304  return (Mat&)a;
1305 }
1306 
1307 static inline Mat& operator += (const Mat& a, const Scalar& s)
1308 {
1309  add(a, s, (Mat&)a);
1310  return (Mat&)a;
1311 }
1312 
1313 template<typename _Tp> static inline
1314 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1315 {
1316  add(a, b, (Mat&)a);
1317  return (Mat_<_Tp>&)a;
1318 }
1319 
1320 template<typename _Tp> static inline
1321 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Scalar& s)
1322 {
1323  add(a, s, (Mat&)a);
1324  return (Mat_<_Tp>&)a;
1325 }
1326 
1327 static inline Mat& operator += (const Mat& a, const MatExpr& b)
1328 {
1329  b.op->augAssignAdd(b, (Mat&)a);
1330  return (Mat&)a;
1331 }
1332 
1333 template<typename _Tp> static inline
1334 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b)
1335 {
1336  b.op->augAssignAdd(b, (Mat&)a);
1337  return (Mat_<_Tp>&)a;
1338 }
1339 
1340 static inline Mat& operator -= (const Mat& a, const Mat& b)
1341 {
1342  subtract(a, b, (Mat&)a);
1343  return (Mat&)a;
1344 }
1345 
1346 static inline Mat& operator -= (const Mat& a, const Scalar& s)
1347 {
1348  subtract(a, s, (Mat&)a);
1349  return (Mat&)a;
1350 }
1351 
1352 template<typename _Tp> static inline
1353 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1354 {
1355  subtract(a, b, (Mat&)a);
1356  return (Mat_<_Tp>&)a;
1357 }
1358 
1359 template<typename _Tp> static inline
1360 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Scalar& s)
1361 {
1362  subtract(a, s, (Mat&)a);
1363  return (Mat_<_Tp>&)a;
1364 }
1365 
1366 static inline Mat& operator -= (const Mat& a, const MatExpr& b)
1367 {
1368  b.op->augAssignSubtract(b, (Mat&)a);
1369  return (Mat&)a;
1370 }
1371 
1372 template<typename _Tp> static inline
1373 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b)
1374 {
1375  b.op->augAssignSubtract(b, (Mat&)a);
1376  return (Mat_<_Tp>&)a;
1377 }
1378 
1379 static inline Mat& operator *= (const Mat& a, const Mat& b)
1380 {
1381  gemm(a, b, 1, Mat(), 0, (Mat&)a, 0);
1382  return (Mat&)a;
1383 }
1384 
1385 static inline Mat& operator *= (const Mat& a, double s)
1386 {
1387  a.convertTo((Mat&)a, -1, s);
1388  return (Mat&)a;
1389 }
1390 
1391 template<typename _Tp> static inline
1392 Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1393 {
1394  gemm(a, b, 1, Mat(), 0, (Mat&)a, 0);
1395  return (Mat_<_Tp>&)a;
1396 }
1397 
1398 template<typename _Tp> static inline
1399 Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, double s)
1400 {
1401  a.convertTo((Mat&)a, -1, s);
1402  return (Mat_<_Tp>&)a;
1403 }
1404 
1405 static inline Mat& operator *= (const Mat& a, const MatExpr& b)
1406 {
1407  b.op->augAssignMultiply(b, (Mat&)a);
1408  return (Mat&)a;
1409 }
1410 
1411 template<typename _Tp> static inline
1412 Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b)
1413 {
1414  b.op->augAssignMultiply(b, (Mat&)a);
1415  return (Mat_<_Tp>&)a;
1416 }
1417 
1418 static inline Mat& operator /= (const Mat& a, const Mat& b)
1419 {
1420  divide(a, b, (Mat&)a);
1421  return (Mat&)a;
1422 }
1423 
1424 static inline Mat& operator /= (const Mat& a, double s)
1425 {
1426  a.convertTo((Mat&)a, -1, 1./s);
1427  return (Mat&)a;
1428 }
1429 
1430 template<typename _Tp> static inline
1431 Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1432 {
1433  divide(a, b, (Mat&)a);
1434  return (Mat_<_Tp>&)a;
1435 }
1436 
1437 template<typename _Tp> static inline
1438 Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, double s)
1439 {
1440  a.convertTo((Mat&)a, -1, 1./s);
1441  return (Mat_<_Tp>&)a;
1442 }
1443 
1444 static inline Mat& operator /= (const Mat& a, const MatExpr& b)
1445 {
1446  b.op->augAssignDivide(b, (Mat&)a);
1447  return (Mat&)a;
1448 }
1449 
1450 template<typename _Tp> static inline
1451 Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b)
1452 {
1453  b.op->augAssignDivide(b, (Mat&)a);
1454  return (Mat_<_Tp>&)a;
1455 }
1456 
1458 
1459 static inline Mat& operator &= (const Mat& a, const Mat& b)
1460 {
1461  bitwise_and(a, b, (Mat&)a);
1462  return (Mat&)a;
1463 }
1464 
1465 static inline Mat& operator &= (const Mat& a, const Scalar& s)
1466 {
1467  bitwise_and(a, s, (Mat&)a);
1468  return (Mat&)a;
1469 }
1470 
1471 template<typename _Tp> static inline Mat_<_Tp>&
1472 operator &= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1473 {
1474  bitwise_and(a, b, (Mat&)a);
1475  return (Mat_<_Tp>&)a;
1476 }
1477 
1478 template<typename _Tp> static inline Mat_<_Tp>&
1479 operator &= (const Mat_<_Tp>& a, const Scalar& s)
1480 {
1481  bitwise_and(a, s, (Mat&)a);
1482  return (Mat_<_Tp>&)a;
1483 }
1484 
1485 static inline Mat& operator |= (const Mat& a, const Mat& b)
1486 {
1487  bitwise_or(a, b, (Mat&)a);
1488  return (Mat&)a;
1489 }
1490 
1491 static inline Mat& operator |= (const Mat& a, const Scalar& s)
1492 {
1493  bitwise_or(a, s, (Mat&)a);
1494  return (Mat&)a;
1495 }
1496 
1497 template<typename _Tp> static inline Mat_<_Tp>&
1498 operator |= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1499 {
1500  bitwise_or(a, b, (Mat&)a);
1501  return (Mat_<_Tp>&)a;
1502 }
1503 
1504 template<typename _Tp> static inline Mat_<_Tp>&
1505 operator |= (const Mat_<_Tp>& a, const Scalar& s)
1506 {
1507  bitwise_or(a, s, (Mat&)a);
1508  return (Mat_<_Tp>&)a;
1509 }
1510 
1511 static inline Mat& operator ^= (const Mat& a, const Mat& b)
1512 {
1513  bitwise_xor(a, b, (Mat&)a);
1514  return (Mat&)a;
1515 }
1516 
1517 static inline Mat& operator ^= (const Mat& a, const Scalar& s)
1518 {
1519  bitwise_xor(a, s, (Mat&)a);
1520  return (Mat&)a;
1521 }
1522 
1523 template<typename _Tp> static inline Mat_<_Tp>&
1524 operator ^= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1525 {
1526  bitwise_xor(a, b, (Mat&)a);
1527  return (Mat_<_Tp>&)a;
1528 }
1529 
1530 template<typename _Tp> static inline Mat_<_Tp>&
1531 operator ^= (const Mat_<_Tp>& a, const Scalar& s)
1532 {
1533  bitwise_xor(a, s, (Mat&)a);
1534  return (Mat_<_Tp>&)a;
1535 }
1536 
1538 
1539 template<typename _Tp> void split(const Mat& src, vector<Mat_<_Tp> >& mv)
1540 { split(src, (vector<Mat>&)mv ); }
1541 
1543 
1544 template<typename _Tp> inline MatExpr Mat_<_Tp>::zeros(int rows, int cols)
1545 {
1546  return Mat::zeros(rows, cols, DataType<_Tp>::type);
1547 }
1548 
1549 template<typename _Tp> inline MatExpr Mat_<_Tp>::zeros(Size sz)
1550 {
1551  return Mat::zeros(sz, DataType<_Tp>::type);
1552 }
1553 
1554 template<typename _Tp> inline MatExpr Mat_<_Tp>::ones(int rows, int cols)
1555 {
1556  return Mat::ones(rows, cols, DataType<_Tp>::type);
1557 }
1558 
1559 template<typename _Tp> inline MatExpr Mat_<_Tp>::ones(Size sz)
1560 {
1561  return Mat::ones(sz, DataType<_Tp>::type);
1562 }
1563 
1564 template<typename _Tp> inline MatExpr Mat_<_Tp>::eye(int rows, int cols)
1565 {
1566  return Mat::eye(rows, cols, DataType<_Tp>::type);
1567 }
1568 
1569 template<typename _Tp> inline MatExpr Mat_<_Tp>::eye(Size sz)
1570 {
1571  return Mat::eye(sz, DataType<_Tp>::type);
1572 }
1573 
1575 
1577  : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0) {}
1578 
1580  : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
1581 {
1582  if( m && m->isContinuous() )
1583  {
1584  sliceStart = m->data;
1585  sliceEnd = sliceStart + m->total()*elemSize;
1586  }
1587  seek((const int*)0);
1588 }
1589 
1590 inline MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col)
1591  : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
1592 {
1593  CV_Assert(m && m->dims <= 2);
1594  if( m->isContinuous() )
1595  {
1596  sliceStart = m->data;
1597  sliceEnd = sliceStart + m->total()*elemSize;
1598  }
1599  int idx[]={_row, _col};
1600  seek(idx);
1601 }
1602 
1604  : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
1605 {
1606  CV_Assert(m && m->dims <= 2);
1607  if( m->isContinuous() )
1608  {
1609  sliceStart = m->data;
1610  sliceEnd = sliceStart + m->total()*elemSize;
1611  }
1612  int idx[]={_pt.y, _pt.x};
1613  seek(idx);
1614 }
1615 
1617  : m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd)
1618 {}
1619 
1621 {
1622  m = it.m; elemSize = it.elemSize; ptr = it.ptr;
1624  return *this;
1625 }
1626 
1627 inline uchar* MatConstIterator::operator *() const { return ptr; }
1628 
1630 {
1631  if( !m || ofs == 0 )
1632  return *this;
1633  ptrdiff_t ofsb = ofs*elemSize;
1634  ptr += ofsb;
1635  if( ptr < sliceStart || sliceEnd <= ptr )
1636  {
1637  ptr -= ofsb;
1638  seek(ofs, true);
1639  }
1640  return *this;
1641 }
1642 
1644 { return (*this += -ofs); }
1645 
1647 {
1648  if( m && (ptr -= elemSize) < sliceStart )
1649  {
1650  ptr += elemSize;
1651  seek(-1, true);
1652  }
1653  return *this;
1654 }
1655 
1657 {
1658  MatConstIterator b = *this;
1659  *this += -1;
1660  return b;
1661 }
1662 
1664 {
1665  if( m && (ptr += elemSize) >= sliceEnd )
1666  {
1667  ptr -= elemSize;
1668  seek(1, true);
1669  }
1670  return *this;
1671 }
1672 
1674 {
1675  MatConstIterator b = *this;
1676  *this += 1;
1677  return b;
1678 }
1679 
1680 template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_() {}
1681 
1682 template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m)
1683  : MatConstIterator(_m) {}
1684 
1685 template<typename _Tp> inline MatConstIterator_<_Tp>::
1686  MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col)
1687  : MatConstIterator(_m, _row, _col) {}
1688 
1689 template<typename _Tp> inline MatConstIterator_<_Tp>::
1691  : MatConstIterator(_m, _pt) {}
1692 
1693 template<typename _Tp> inline MatConstIterator_<_Tp>::
1695  : MatConstIterator(it) {}
1696 
1697 template<typename _Tp> inline MatConstIterator_<_Tp>&
1699 {
1701  return *this;
1702 }
1703 
1704 template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator *() const { return *(_Tp*)(this->ptr); }
1705 
1706 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs)
1707 {
1709  return *this;
1710 }
1711 
1712 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs)
1713 { return (*this += -ofs); }
1714 
1716 {
1718  return *this;
1719 }
1720 
1722 {
1723  MatConstIterator_ b = *this;
1725  return b;
1726 }
1727 
1729 {
1731  return *this;
1732 }
1733 
1735 {
1736  MatConstIterator_ b = *this;
1738  return b;
1739 }
1740 
1741 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_() : MatConstIterator_<_Tp>() {}
1742 
1743 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
1744  : MatConstIterator_<_Tp>(_m) {}
1745 
1746 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
1747  : MatConstIterator_<_Tp>(_m, _row, _col) {}
1748 
1749 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, Point _pt)
1750  : MatConstIterator_<_Tp>(_m, _pt) {}
1751 
1752 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, const int* _idx)
1753  : MatConstIterator_<_Tp>(_m, _idx) {}
1754 
1755 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
1756  : MatConstIterator_<_Tp>(it) {}
1757 
1758 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
1759 {
1761  return *this;
1762 }
1763 
1764 template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator *() const { return *(_Tp*)(this->ptr); }
1765 
1766 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs)
1767 {
1769  return *this;
1770 }
1771 
1772 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs)
1773 {
1775  return *this;
1776 }
1777 
1778 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
1779 {
1781  return *this;
1782 }
1783 
1784 template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
1785 {
1786  MatIterator_ b = *this;
1788  return b;
1789 }
1790 
1791 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
1792 {
1794  return *this;
1795 }
1796 
1797 template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
1798 {
1799  MatIterator_ b = *this;
1801  return b;
1802 }
1803 
1804 template<typename _Tp> inline Point MatConstIterator_<_Tp>::pos() const
1805 {
1806  if( !m )
1807  return Point();
1808  CV_DbgAssert( m->dims <= 2 );
1809  if( m->isContinuous() )
1810  {
1811  ptrdiff_t ofs = ptr - (_Tp*)m->data;
1812  int y = (int)(ofs / m->cols), x = (int)(ofs - (ptrdiff_t)y*m->cols);
1813  return Point(x, y);
1814  }
1815  else
1816  {
1817  ptrdiff_t ofs = (uchar*)ptr - m->data;
1818  int y = (int)(ofs / m->step), x = (int)((ofs - y*m->step)/sizeof(_Tp));
1819  return Point(x, y);
1820  }
1821 }
1822 
1823 static inline bool
1825 { return a.m == b.m && a.ptr == b.ptr; }
1826 
1827 template<typename _Tp> static inline bool
1828 operator != (const MatConstIterator& a, const MatConstIterator& b)
1829 { return !(a == b); }
1830 
1831 template<typename _Tp> static inline bool
1833 { return a.m == b.m && a.ptr == b.ptr; }
1834 
1835 template<typename _Tp> static inline bool
1837 { return a.m != b.m || a.ptr != b.ptr; }
1838 
1839 template<typename _Tp> static inline bool
1841 { return a.m == b.m && a.ptr == b.ptr; }
1842 
1843 template<typename _Tp> static inline bool
1845 { return a.m != b.m || a.ptr != b.ptr; }
1846 
1847 static inline bool
1848 operator < (const MatConstIterator& a, const MatConstIterator& b)
1849 { return a.ptr < b.ptr; }
1850 
1851 static inline bool
1852 operator > (const MatConstIterator& a, const MatConstIterator& b)
1853 { return a.ptr > b.ptr; }
1854 
1855 static inline bool
1856 operator <= (const MatConstIterator& a, const MatConstIterator& b)
1857 { return a.ptr <= b.ptr; }
1858 
1859 static inline bool
1860 operator >= (const MatConstIterator& a, const MatConstIterator& b)
1861 { return a.ptr >= b.ptr; }
1862 
1863 CV_EXPORTS ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a);
1864 
1865 static inline MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs)
1866 { MatConstIterator b = a; return b += ofs; }
1867 
1868 static inline MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a)
1869 { MatConstIterator b = a; return b += ofs; }
1870 
1871 static inline MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
1872 { MatConstIterator b = a; return b += -ofs; }
1873 
1874 template<typename _Tp> static inline MatConstIterator_<_Tp>
1875 operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
1876 { MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatConstIterator_<_Tp>&)t; }
1877 
1878 template<typename _Tp> static inline MatConstIterator_<_Tp>
1879 operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a)
1880 { MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatConstIterator_<_Tp>&)t; }
1881 
1882 template<typename _Tp> static inline MatConstIterator_<_Tp>
1883 operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
1884 { MatConstIterator t = (const MatConstIterator&)a - ofs; return (MatConstIterator_<_Tp>&)t; }
1885 
1886 inline uchar* MatConstIterator::operator [](ptrdiff_t i) const
1887 { return *(*this + i); }
1888 
1889 template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const
1890 { return *(_Tp*)MatConstIterator::operator [](i); }
1891 
1892 template<typename _Tp> static inline MatIterator_<_Tp>
1893 operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
1894 { MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatIterator_<_Tp>&)t; }
1895 
1896 template<typename _Tp> static inline MatIterator_<_Tp>
1897 operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a)
1898 { MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatIterator_<_Tp>&)t; }
1899 
1900 template<typename _Tp> static inline MatIterator_<_Tp>
1901 operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
1902 { MatConstIterator t = (const MatConstIterator&)a - ofs; return (MatIterator_<_Tp>&)t; }
1903 
1904 template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const
1905 { return *(*this + i); }
1906 
1907 template<typename _Tp> inline MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
1908 { return Mat::begin<_Tp>(); }
1909 
1910 template<typename _Tp> inline MatConstIterator_<_Tp> Mat_<_Tp>::end() const
1911 { return Mat::end<_Tp>(); }
1912 
1913 template<typename _Tp> inline MatIterator_<_Tp> Mat_<_Tp>::begin()
1914 { return Mat::begin<_Tp>(); }
1915 
1916 template<typename _Tp> inline MatIterator_<_Tp> Mat_<_Tp>::end()
1917 { return Mat::end<_Tp>(); }
1918 
1919 template<typename _Tp> inline MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m) : it(_m) {}
1920 
1921 template<typename _Tp> template<typename T2> inline MatCommaInitializer_<_Tp>&
1923 {
1924  CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() );
1925  *this->it = _Tp(v); ++this->it;
1926  return *this;
1927 }
1928 
1929 template<typename _Tp> inline Mat_<_Tp> MatCommaInitializer_<_Tp>::operator *() const
1930 {
1931  CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
1932  return Mat_<_Tp>(*this->it.m);
1933 }
1934 
1935 template<typename _Tp> inline MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
1936 {
1937  CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
1938  return Mat_<_Tp>(*this->it.m);
1939 }
1940 
1941 template<typename _Tp, typename T2> static inline MatCommaInitializer_<_Tp>
1942 operator << (const Mat_<_Tp>& m, T2 val)
1943 {
1944  MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
1945  return (commaInitializer, val);
1946 }
1947 
1949 
1951 : flags(MAGIC_VAL), hdr(0)
1952 {
1953 }
1954 
1955 inline SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
1956 : flags(MAGIC_VAL), hdr(0)
1957 {
1958  create(_dims, _sizes, _type);
1959 }
1960 
1962 : flags(m.flags), hdr(m.hdr)
1963 {
1964  addref();
1965 }
1966 
1968 {
1969  release();
1970 }
1971 
1973 {
1974  if( this != &m )
1975  {
1976  if( m.hdr )
1977  CV_XADD(&m.hdr->refcount, 1);
1978  release();
1979  flags = m.flags;
1980  hdr = m.hdr;
1981  }
1982  return *this;
1983 }
1984 
1986 { return (*this = SparseMat(m)); }
1987 
1989 {
1990  SparseMat temp;
1991  this->copyTo(temp);
1992  return temp;
1993 }
1994 
1995 
1996 inline void SparseMat::assignTo( SparseMat& m, int type ) const
1997 {
1998  if( type < 0 )
1999  m = *this;
2000  else
2001  convertTo(m, type);
2002 }
2003 
2004 inline void SparseMat::addref()
2005 { if( hdr ) CV_XADD(&hdr->refcount, 1); }
2006 
2007 inline void SparseMat::release()
2008 {
2009  if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
2010  delete hdr;
2011  hdr = 0;
2012 }
2013 
2014 inline size_t SparseMat::elemSize() const
2015 { return CV_ELEM_SIZE(flags); }
2016 
2017 inline size_t SparseMat::elemSize1() const
2018 { return CV_ELEM_SIZE1(flags); }
2019 
2020 inline int SparseMat::type() const
2021 { return CV_MAT_TYPE(flags); }
2022 
2023 inline int SparseMat::depth() const
2024 { return CV_MAT_DEPTH(flags); }
2025 
2026 inline int SparseMat::channels() const
2027 { return CV_MAT_CN(flags); }
2028 
2029 inline const int* SparseMat::size() const
2030 {
2031  return hdr ? hdr->size : 0;
2032 }
2033 
2034 inline int SparseMat::size(int i) const
2035 {
2036  if( hdr )
2037  {
2038  CV_DbgAssert((unsigned)i < (unsigned)hdr->dims);
2039  return hdr->size[i];
2040  }
2041  return 0;
2042 }
2043 
2044 inline int SparseMat::dims() const
2045 {
2046  return hdr ? hdr->dims : 0;
2047 }
2048 
2049 inline size_t SparseMat::nzcount() const
2050 {
2051  return hdr ? hdr->nodeCount : 0;
2052 }
2053 
2054 inline size_t SparseMat::hash(int i0) const
2055 {
2056  return (size_t)i0;
2057 }
2058 
2059 inline size_t SparseMat::hash(int i0, int i1) const
2060 {
2061  return (size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1;
2062 }
2063 
2064 inline size_t SparseMat::hash(int i0, int i1, int i2) const
2065 {
2066  return ((size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1)*HASH_SCALE + (unsigned)i2;
2067 }
2068 
2069 inline size_t SparseMat::hash(const int* idx) const
2070 {
2071  size_t h = (unsigned)idx[0];
2072  if( !hdr )
2073  return 0;
2074  int i, d = hdr->dims;
2075  for( i = 1; i < d; i++ )
2076  h = h*HASH_SCALE + (unsigned)idx[i];
2077  return h;
2078 }
2079 
2080 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, size_t* hashval)
2081 { return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval); }
2082 
2083 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
2084 { return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval); }
2085 
2086 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval)
2087 { return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval); }
2088 
2089 template<typename _Tp> inline _Tp& SparseMat::ref(const int* idx, size_t* hashval)
2090 { return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval); }
2091 
2092 template<typename _Tp> inline _Tp SparseMat::value(int i0, size_t* hashval) const
2093 {
2094  const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
2095  return p ? *p : _Tp();
2096 }
2097 
2098 template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, size_t* hashval) const
2099 {
2100  const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
2101  return p ? *p : _Tp();
2102 }
2103 
2104 template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const
2105 {
2106  const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
2107  return p ? *p : _Tp();
2108 }
2109 
2110 template<typename _Tp> inline _Tp SparseMat::value(const int* idx, size_t* hashval) const
2111 {
2112  const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
2113  return p ? *p : _Tp();
2114 }
2115 
2116 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, size_t* hashval) const
2117 { return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval); }
2118 
2119 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
2120 { return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval); }
2121 
2122 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const
2123 { return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval); }
2124 
2125 template<typename _Tp> inline const _Tp* SparseMat::find(const int* idx, size_t* hashval) const
2126 { return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval); }
2127 
2128 template<typename _Tp> inline _Tp& SparseMat::value(Node* n)
2129 { return *(_Tp*)((uchar*)n + hdr->valueOffset); }
2130 
2131 template<typename _Tp> inline const _Tp& SparseMat::value(const Node* n) const
2132 { return *(const _Tp*)((const uchar*)n + hdr->valueOffset); }
2133 
2134 inline SparseMat::Node* SparseMat::node(size_t nidx)
2135 { return (Node*)&hdr->pool[nidx]; }
2136 
2137 inline const SparseMat::Node* SparseMat::node(size_t nidx) const
2138 { return (const Node*)&hdr->pool[nidx]; }
2139 
2141 { return SparseMatIterator(this); }
2142 
2144 { return SparseMatConstIterator(this); }
2145 
2147 { SparseMatIterator it(this); it.seekEnd(); return it; }
2148 
2150 { SparseMatConstIterator it(this); it.seekEnd(); return it; }
2151 
2152 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::begin()
2153 { return SparseMatIterator_<_Tp>(this); }
2154 
2155 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::begin() const
2156 { return SparseMatConstIterator_<_Tp>(this); }
2157 
2158 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::end()
2159 { SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
2160 
2161 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::end() const
2162 { SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
2163 
2164 
2166 : m(0), hashidx(0), ptr(0)
2167 {
2168 }
2169 
2171 : m(it.m), hashidx(it.hashidx), ptr(it.ptr)
2172 {
2173 }
2174 
2175 static inline bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
2176 { return it1.m == it2.m && it1.hashidx == it2.hashidx && it1.ptr == it2.ptr; }
2177 
2178 static inline bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
2179 { return !(it1 == it2); }
2180 
2181 
2183 {
2184  if( this != &it )
2185  {
2186  m = it.m;
2187  hashidx = it.hashidx;
2188  ptr = it.ptr;
2189  }
2190  return *this;
2191 }
2192 
2193 template<typename _Tp> inline const _Tp& SparseMatConstIterator::value() const
2194 { return *(_Tp*)ptr; }
2195 
2197 {
2198  return ptr && m && m->hdr ?
2199  (const SparseMat::Node*)(ptr - m->hdr->valueOffset) : 0;
2200 }
2201 
2203 {
2204  SparseMatConstIterator it = *this;
2205  ++*this;
2206  return it;
2207 }
2208 
2209 
2211 {
2212  if( m && m->hdr )
2213  {
2214  hashidx = m->hdr->hashtab.size();
2215  ptr = 0;
2216  }
2217 }
2218 
2220 {}
2221 
2224 {}
2225 
2228 {
2229 }
2230 
2232 {
2233  (SparseMatConstIterator&)*this = it;
2234  return *this;
2235 }
2236 
2237 template<typename _Tp> inline _Tp& SparseMatIterator::value() const
2238 { return *(_Tp*)ptr; }
2239 
2241 {
2243 }
2244 
2246 {
2248  return *this;
2249 }
2250 
2252 {
2253  SparseMatIterator it = *this;
2254  ++*this;
2255  return it;
2256 }
2257 
2258 
2259 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_()
2260 { flags = MAGIC_VAL | DataType<_Tp>::type; }
2261 
2262 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
2263 : SparseMat(_dims, _sizes, DataType<_Tp>::type)
2264 {}
2265 
2266 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
2267 {
2268  if( m.type() == DataType<_Tp>::type )
2269  *this = (const SparseMat_<_Tp>&)m;
2270  else
2271  m.convertTo(this, DataType<_Tp>::type);
2272 }
2273 
2274 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m)
2275 {
2276  this->flags = m.flags;
2277  this->hdr = m.hdr;
2278  if( this->hdr )
2279  CV_XADD(&this->hdr->refcount, 1);
2280 }
2281 
2282 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const Mat& m)
2283 {
2284  SparseMat sm(m);
2285  *this = sm;
2286 }
2287 
2288 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const CvSparseMat* m)
2289 {
2290  SparseMat sm(m);
2291  *this = sm;
2292 }
2293 
2294 template<typename _Tp> inline SparseMat_<_Tp>&
2296 {
2297  if( this != &m )
2298  {
2299  if( m.hdr ) CV_XADD(&m.hdr->refcount, 1);
2300  release();
2301  flags = m.flags;
2302  hdr = m.hdr;
2303  }
2304  return *this;
2305 }
2306 
2307 template<typename _Tp> inline SparseMat_<_Tp>&
2309 {
2310  if( m.type() == DataType<_Tp>::type )
2311  return (*this = (const SparseMat_<_Tp>&)m);
2312  m.convertTo(*this, DataType<_Tp>::type);
2313  return *this;
2314 }
2315 
2316 template<typename _Tp> inline SparseMat_<_Tp>&
2318 { return (*this = SparseMat(m)); }
2319 
2320 template<typename _Tp> inline SparseMat_<_Tp>
2322 {
2323  SparseMat_<_Tp> m;
2324  this->copyTo(m);
2325  return m;
2326 }
2327 
2328 template<typename _Tp> inline void
2329 SparseMat_<_Tp>::create(int _dims, const int* _sizes)
2330 {
2331  SparseMat::create(_dims, _sizes, DataType<_Tp>::type);
2332 }
2333 
2334 template<typename _Tp> inline
2336 {
2337  return SparseMat::operator CvSparseMat*();
2338 }
2339 
2340 template<typename _Tp> inline int SparseMat_<_Tp>::type() const
2341 { return DataType<_Tp>::type; }
2342 
2343 template<typename _Tp> inline int SparseMat_<_Tp>::depth() const
2344 { return DataType<_Tp>::depth; }
2345 
2346 template<typename _Tp> inline int SparseMat_<_Tp>::channels() const
2347 { return DataType<_Tp>::channels; }
2348 
2349 template<typename _Tp> inline _Tp&
2350 SparseMat_<_Tp>::ref(int i0, size_t* hashval)
2351 { return SparseMat::ref<_Tp>(i0, hashval); }
2352 
2353 template<typename _Tp> inline _Tp
2354 SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
2355 { return SparseMat::value<_Tp>(i0, hashval); }
2356 
2357 template<typename _Tp> inline _Tp&
2358 SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
2359 { return SparseMat::ref<_Tp>(i0, i1, hashval); }
2360 
2361 template<typename _Tp> inline _Tp
2362 SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const
2363 { return SparseMat::value<_Tp>(i0, i1, hashval); }
2364 
2365 template<typename _Tp> inline _Tp&
2366 SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval)
2367 { return SparseMat::ref<_Tp>(i0, i1, i2, hashval); }
2368 
2369 template<typename _Tp> inline _Tp
2370 SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const
2371 { return SparseMat::value<_Tp>(i0, i1, i2, hashval); }
2372 
2373 template<typename _Tp> inline _Tp&
2374 SparseMat_<_Tp>::ref(const int* idx, size_t* hashval)
2375 { return SparseMat::ref<_Tp>(idx, hashval); }
2376 
2377 template<typename _Tp> inline _Tp
2378 SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const
2379 { return SparseMat::value<_Tp>(idx, hashval); }
2380 
2381 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
2382 { return SparseMatIterator_<_Tp>(this); }
2383 
2384 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
2385 { return SparseMatConstIterator_<_Tp>(this); }
2386 
2387 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
2388 { SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
2389 
2390 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
2391 { SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
2392 
2393 template<typename _Tp> inline
2395 {}
2396 
2397 template<typename _Tp> inline
2400 {}
2401 
2402 template<typename _Tp> inline
2405 {}
2406 
2407 template<typename _Tp> inline SparseMatConstIterator_<_Tp>&
2409 { return ((SparseMatConstIterator&)*this = it); }
2410 
2411 template<typename _Tp> inline const _Tp&
2413 { return *(const _Tp*)this->ptr; }
2414 
2415 template<typename _Tp> inline SparseMatConstIterator_<_Tp>&
2417 {
2419  return *this;
2420 }
2421 
2422 template<typename _Tp> inline SparseMatConstIterator_<_Tp>
2424 {
2425  SparseMatConstIterator it = *this;
2427  return it;
2428 }
2429 
2430 template<typename _Tp> inline
2432 {}
2433 
2434 template<typename _Tp> inline
2436 : SparseMatConstIterator_<_Tp>(_m)
2437 {}
2438 
2439 template<typename _Tp> inline
2441 : SparseMatConstIterator_<_Tp>(it)
2442 {}
2443 
2444 template<typename _Tp> inline SparseMatIterator_<_Tp>&
2446 { return ((SparseMatIterator&)*this = it); }
2447 
2448 template<typename _Tp> inline _Tp&
2450 { return *(_Tp*)this->ptr; }
2451 
2452 template<typename _Tp> inline SparseMatIterator_<_Tp>&
2454 {
2456  return *this;
2457 }
2458 
2459 template<typename _Tp> inline SparseMatIterator_<_Tp>
2461 {
2462  SparseMatIterator it = *this;
2464  return it;
2465 }
2466 
2467 }
2468 
2469 #endif
2470 #endif