// copy or use the software.
//
//
-// License Agreement
+// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
+// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
//
//M*/
-#ifndef __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
-#define __OPENCV_CORE_MATRIX_OPERATIONS_HPP__
+#ifndef __OPENCV_CORE_MAT_HPP__
+#define __OPENCV_CORE_MAT_HPP__
-#ifndef SKIP_INCLUDES
-#include <limits.h>
-#include <string.h>
-#endif // SKIP_INCLUDES
+#ifndef __cplusplus
+# error mat.hpp header must be compiled as C++
+#endif
+
+#include "opencv2/core/matx.hpp"
+#include "opencv2/core/types.hpp"
-#ifdef __cplusplus
+#include "opencv2/core/bufferpool.hpp"
namespace cv
{
-//////////////////////////////// Mat ////////////////////////////////
-
-inline void Mat::initEmpty()
-{
- flags = MAGIC_VAL;
- dims = rows = cols = 0;
- data = datastart = dataend = datalimit = 0;
- refcount = 0;
- allocator = 0;
-}
-
-inline Mat::Mat() : size(&rows)
-{
- initEmpty();
-}
+enum { ACCESS_READ=1<<24, ACCESS_WRITE=1<<25,
+ ACCESS_RW=3<<24, ACCESS_MASK=ACCESS_RW, ACCESS_FAST=1<<26 };
-inline Mat::Mat(int _rows, int _cols, int _type) : size(&rows)
-{
- initEmpty();
- create(_rows, _cols, _type);
-}
+class CV_EXPORTS _OutputArray;
-inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s) : size(&rows)
-{
- initEmpty();
- create(_rows, _cols, _type);
- *this = _s;
-}
+//////////////////////// Input/Output Array Arguments /////////////////////////////////
-inline Mat::Mat(Size _sz, int _type) : size(&rows)
+/*!
+ Proxy datatype for passing Mat's and vector<>'s as input parameters
+ */
+class CV_EXPORTS _InputArray
{
- initEmpty();
- create( _sz.height, _sz.width, _type );
-}
+public:
+ enum {
+ KIND_SHIFT = 16,
+ FIXED_TYPE = 0x8000 << KIND_SHIFT,
+ FIXED_SIZE = 0x4000 << KIND_SHIFT,
+ KIND_MASK = 31 << KIND_SHIFT,
+
+ NONE = 0 << KIND_SHIFT,
+ MAT = 1 << KIND_SHIFT,
+ MATX = 2 << KIND_SHIFT,
+ STD_VECTOR = 3 << KIND_SHIFT,
+ STD_VECTOR_VECTOR = 4 << KIND_SHIFT,
+ STD_VECTOR_MAT = 5 << KIND_SHIFT,
+ EXPR = 6 << KIND_SHIFT,
+ OPENGL_BUFFER = 7 << KIND_SHIFT,
+ CUDA_MEM = 8 << KIND_SHIFT,
+ GPU_MAT = 9 << KIND_SHIFT,
+ UMAT =10 << KIND_SHIFT,
+ STD_VECTOR_UMAT =11 << KIND_SHIFT
+ };
+
+ _InputArray();
+ _InputArray(int _flags, void* _obj);
+ _InputArray(const Mat& m);
+ _InputArray(const MatExpr& expr);
+ _InputArray(const std::vector<Mat>& vec);
+ template<typename _Tp> _InputArray(const Mat_<_Tp>& m);
+ template<typename _Tp> _InputArray(const std::vector<_Tp>& vec);
+ template<typename _Tp> _InputArray(const std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _InputArray(const std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _InputArray(const _Tp* vec, int n);
+ template<typename _Tp, int m, int n> _InputArray(const Matx<_Tp, m, n>& matx);
+ _InputArray(const double& val);
+ _InputArray(const cuda::GpuMat& d_mat);
+ _InputArray(const ogl::Buffer& buf);
+ _InputArray(const cuda::CudaMem& cuda_mem);
+ template<typename _Tp> _InputArray(const cudev::GpuMat_<_Tp>& m);
+ _InputArray(const UMat& um);
+ _InputArray(const std::vector<UMat>& umv);
+
+ virtual Mat getMat(int idx=-1) const;
+ virtual UMat getUMat(int idx=-1) const;
+ virtual void getMatVector(std::vector<Mat>& mv) const;
+ virtual void getUMatVector(std::vector<UMat>& umv) const;
+ virtual cuda::GpuMat getGpuMat() const;
+ virtual ogl::Buffer getOGlBuffer() const;
+ void* getObj() const;
+
+ virtual int kind() const;
+ virtual int dims(int i=-1) const;
+ virtual int cols(int i=-1) const;
+ virtual int rows(int i=-1) const;
+ virtual Size size(int i=-1) const;
+ virtual int sizend(int* sz, int i=-1) const;
+ virtual bool sameSize(const _InputArray& arr) const;
+ virtual size_t total(int i=-1) const;
+ virtual int type(int i=-1) const;
+ virtual int depth(int i=-1) const;
+ virtual int channels(int i=-1) const;
+ virtual bool isContinuous(int i=-1) const;
+ virtual bool isSubmatrix(int i=-1) const;
+ virtual bool empty() const;
+ virtual void copyTo(const _OutputArray& arr) const;
+ virtual void copyTo(const _OutputArray& arr, const _InputArray & mask) const;
+ virtual size_t offset(int i=-1) const;
+ virtual size_t step(int i=-1) const;
+ bool isMat() const;
+ bool isUMat() const;
+ bool isMatVector() const;
+ bool isUMatVector() const;
+ bool isMatx() const;
+
+ virtual ~_InputArray();
+
+protected:
+ int flags;
+ void* obj;
+ Size sz;
-inline Mat::Mat(Size _sz, int _type, const Scalar& _s) : size(&rows)
-{
- initEmpty();
- create(_sz.height, _sz.width, _type);
- *this = _s;
-}
+ void init(int _flags, const void* _obj);
+ void init(int _flags, const void* _obj, Size _sz);
+};
-inline Mat::Mat(int _dims, const int* _sz, int _type) : size(&rows)
-{
- initEmpty();
- create(_dims, _sz, _type);
-}
-inline Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s) : size(&rows)
-{
- initEmpty();
- create(_dims, _sz, _type);
- *this = _s;
-}
-
-inline Mat::Mat(const Mat& m)
- : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
- refcount(m.refcount), datastart(m.datastart), dataend(m.dataend),
- datalimit(m.datalimit), allocator(m.allocator), size(&rows)
-{
- if( refcount )
- CV_XADD(refcount, 1);
- if( m.dims <= 2 )
- {
- step[0] = m.step[0]; step[1] = m.step[1];
- }
- else
- {
- dims = 0;
- copySize(m);
- }
-}
-
-inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
- : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
- data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0),
- datalimit(0), allocator(0), size(&rows)
+/*!
+ Proxy datatype for passing Mat's and vector<>'s as input parameters
+ */
+class CV_EXPORTS _OutputArray : public _InputArray
{
- size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz;
- if( _step == AUTO_STEP )
- {
- _step = minstep;
- flags |= CONTINUOUS_FLAG;
- }
- else
- {
- if( rows == 1 ) _step = minstep;
- CV_DbgAssert( _step >= minstep );
- flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
- }
- step[0] = _step; step[1] = esz;
- datalimit = datastart + _step*rows;
- dataend = datalimit - _step + minstep;
-}
-
-inline Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
- : flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
- data((uchar*)_data), refcount(0), datastart((uchar*)_data), dataend(0),
- datalimit(0), allocator(0), size(&rows)
-{
- size_t esz = CV_ELEM_SIZE(_type), minstep = cols*esz;
- if( _step == AUTO_STEP )
- {
- _step = minstep;
- flags |= CONTINUOUS_FLAG;
- }
- else
- {
- if( rows == 1 ) _step = minstep;
- CV_DbgAssert( _step >= minstep );
- flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
- }
- step[0] = _step; step[1] = esz;
- datalimit = datastart + _step*rows;
- dataend = datalimit - _step + minstep;
-}
-
-
-template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
- : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- dims(2), rows((int)vec.size()), cols(1), data(0), refcount(0),
- datastart(0), dataend(0), allocator(0), size(&rows)
-{
- if(vec.empty())
- return;
- if( !copyData )
- {
- step[0] = step[1] = sizeof(_Tp);
- data = datastart = (uchar*)&vec[0];
- datalimit = dataend = datastart + rows*step[0];
- }
- else
- Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
-}
-
-
-template<typename _Tp, int n> inline Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
- : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- dims(2), rows(n), cols(1), data(0), refcount(0),
- datastart(0), dataend(0), allocator(0), size(&rows)
-{
- if( !copyData )
- {
- step[0] = step[1] = sizeof(_Tp);
- data = datastart = (uchar*)vec.val;
- datalimit = dataend = datastart + rows*step[0];
- }
- else
- Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this);
-}
-
-
-template<typename _Tp, int m, int n> inline Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
- : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- dims(2), rows(m), cols(n), data(0), refcount(0),
- datastart(0), dataend(0), allocator(0), size(&rows)
-{
- if( !copyData )
- {
- step[0] = cols*sizeof(_Tp);
- step[1] = sizeof(_Tp);
- data = datastart = (uchar*)M.val;
- datalimit = dataend = datastart + rows*step[0];
- }
- else
- Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this);
-}
-
-
-template<typename _Tp> inline Mat::Mat(const Point_<_Tp>& pt, bool copyData)
- : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- dims(2), rows(2), cols(1), data(0), refcount(0),
- datastart(0), dataend(0), allocator(0), size(&rows)
-{
- if( !copyData )
- {
- step[0] = step[1] = sizeof(_Tp);
- data = datastart = (uchar*)&pt.x;
- datalimit = dataend = datastart + rows*step[0];
- }
- else
+public:
+ enum
{
- create(2, 1, DataType<_Tp>::type);
- ((_Tp*)data)[0] = pt.x;
- ((_Tp*)data)[1] = pt.y;
- }
-}
+ DEPTH_MASK_8U = 1 << CV_8U,
+ DEPTH_MASK_8S = 1 << CV_8S,
+ DEPTH_MASK_16U = 1 << CV_16U,
+ DEPTH_MASK_16S = 1 << CV_16S,
+ DEPTH_MASK_32S = 1 << CV_32S,
+ DEPTH_MASK_32F = 1 << CV_32F,
+ DEPTH_MASK_64F = 1 << CV_64F,
+ DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1,
+ DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S,
+ DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F
+ };
+
+ _OutputArray();
+ _OutputArray(int _flags, void* _obj);
+ _OutputArray(Mat& m);
+ _OutputArray(std::vector<Mat>& vec);
+ _OutputArray(cuda::GpuMat& d_mat);
+ _OutputArray(ogl::Buffer& buf);
+ _OutputArray(cuda::CudaMem& cuda_mem);
+ template<typename _Tp> _OutputArray(cudev::GpuMat_<_Tp>& m);
+ template<typename _Tp> _OutputArray(std::vector<_Tp>& vec);
+ template<typename _Tp> _OutputArray(std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _OutputArray(std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _OutputArray(Mat_<_Tp>& m);
+ template<typename _Tp> _OutputArray(_Tp* vec, int n);
+ template<typename _Tp, int m, int n> _OutputArray(Matx<_Tp, m, n>& matx);
+ _OutputArray(UMat& m);
+ _OutputArray(std::vector<UMat>& vec);
+
+ _OutputArray(const Mat& m);
+ _OutputArray(const std::vector<Mat>& vec);
+ _OutputArray(const cuda::GpuMat& d_mat);
+ _OutputArray(const ogl::Buffer& buf);
+ _OutputArray(const cuda::CudaMem& cuda_mem);
+ template<typename _Tp> _OutputArray(const cudev::GpuMat_<_Tp>& m);
+ template<typename _Tp> _OutputArray(const std::vector<_Tp>& vec);
+ template<typename _Tp> _OutputArray(const std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _OutputArray(const std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _OutputArray(const Mat_<_Tp>& m);
+ template<typename _Tp> _OutputArray(const _Tp* vec, int n);
+ template<typename _Tp, int m, int n> _OutputArray(const Matx<_Tp, m, n>& matx);
+ _OutputArray(const UMat& m);
+ _OutputArray(const std::vector<UMat>& vec);
+
+ virtual bool fixedSize() const;
+ virtual bool fixedType() const;
+ virtual bool needed() const;
+ virtual Mat& getMatRef(int i=-1) const;
+ virtual UMat& getUMatRef(int i=-1) const;
+ virtual cuda::GpuMat& getGpuMatRef() const;
+ virtual ogl::Buffer& getOGlBufferRef() const;
+ virtual cuda::CudaMem& getCudaMemRef() const;
+ virtual void create(Size sz, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
+ virtual void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
+ virtual void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, int fixedDepthMask=0) const;
+ virtual void createSameSize(const _InputArray& arr, int mtype) const;
+ virtual void release() const;
+ virtual void clear() const;
+ virtual void setTo(const _InputArray& value, const _InputArray & mask = _InputArray()) const;
+
+ void assign(const UMat& u) const;
+ void assign(const Mat& m) const;
+};
-template<typename _Tp> inline Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
- : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- dims(2), rows(3), cols(1), data(0), refcount(0),
- datastart(0), dataend(0), allocator(0), size(&rows)
-{
- if( !copyData )
- {
- step[0] = step[1] = sizeof(_Tp);
- data = datastart = (uchar*)&pt.x;
- datalimit = dataend = datastart + rows*step[0];
- }
- else
- {
- create(3, 1, DataType<_Tp>::type);
- ((_Tp*)data)[0] = pt.x;
- ((_Tp*)data)[1] = pt.y;
- ((_Tp*)data)[2] = pt.z;
- }
-}
-
-
-template<typename _Tp> inline Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
- : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- dims(0), rows(0), cols(0), data(0), refcount(0),
- datastart(0), dataend(0), allocator(0), size(&rows)
+class CV_EXPORTS _InputOutputArray : public _OutputArray
{
- *this = *commaInitializer;
-}
+public:
+ _InputOutputArray();
+ _InputOutputArray(int _flags, void* _obj);
+ _InputOutputArray(Mat& m);
+ _InputOutputArray(std::vector<Mat>& vec);
+ _InputOutputArray(cuda::GpuMat& d_mat);
+ _InputOutputArray(ogl::Buffer& buf);
+ _InputOutputArray(cuda::CudaMem& cuda_mem);
+ template<typename _Tp> _InputOutputArray(cudev::GpuMat_<_Tp>& m);
+ template<typename _Tp> _InputOutputArray(std::vector<_Tp>& vec);
+ template<typename _Tp> _InputOutputArray(std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _InputOutputArray(std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _InputOutputArray(Mat_<_Tp>& m);
+ template<typename _Tp> _InputOutputArray(_Tp* vec, int n);
+ template<typename _Tp, int m, int n> _InputOutputArray(Matx<_Tp, m, n>& matx);
+ _InputOutputArray(UMat& m);
+ _InputOutputArray(std::vector<UMat>& vec);
+
+ _InputOutputArray(const Mat& m);
+ _InputOutputArray(const std::vector<Mat>& vec);
+ _InputOutputArray(const cuda::GpuMat& d_mat);
+ _InputOutputArray(const ogl::Buffer& buf);
+ _InputOutputArray(const cuda::CudaMem& cuda_mem);
+ template<typename _Tp> _InputOutputArray(const cudev::GpuMat_<_Tp>& m);
+ template<typename _Tp> _InputOutputArray(const std::vector<_Tp>& vec);
+ template<typename _Tp> _InputOutputArray(const std::vector<std::vector<_Tp> >& vec);
+ template<typename _Tp> _InputOutputArray(const std::vector<Mat_<_Tp> >& vec);
+ template<typename _Tp> _InputOutputArray(const Mat_<_Tp>& m);
+ template<typename _Tp> _InputOutputArray(const _Tp* vec, int n);
+ template<typename _Tp, int m, int n> _InputOutputArray(const Matx<_Tp, m, n>& matx);
+ _InputOutputArray(const UMat& m);
+ _InputOutputArray(const std::vector<UMat>& vec);
+};
-inline Mat::~Mat()
-{
- release();
- if( step.p != step.buf )
- fastFree(step.p);
-}
+typedef const _InputArray& InputArray;
+typedef InputArray InputArrayOfArrays;
+typedef const _OutputArray& OutputArray;
+typedef OutputArray OutputArrayOfArrays;
+typedef const _InputOutputArray& InputOutputArray;
+typedef InputOutputArray InputOutputArrayOfArrays;
-inline Mat& Mat::operator = (const Mat& m)
-{
- if( this != &m )
- {
- if( m.refcount )
- CV_XADD(m.refcount, 1);
- release();
- flags = m.flags;
- if( dims <= 2 && m.dims <= 2 )
- {
- dims = m.dims;
- rows = m.rows;
- cols = m.cols;
- step[0] = m.step[0];
- step[1] = m.step[1];
- }
- else
- copySize(m);
- data = m.data;
- datastart = m.datastart;
- dataend = m.dataend;
- datalimit = m.datalimit;
- refcount = m.refcount;
- allocator = m.allocator;
- }
- return *this;
-}
-
-inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); }
-inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); }
-inline Mat Mat::rowRange(int startrow, int endrow) const
- { return Mat(*this, Range(startrow, endrow), Range::all()); }
-inline Mat Mat::rowRange(const Range& r) const
- { return Mat(*this, r, Range::all()); }
-inline Mat Mat::colRange(int startcol, int endcol) const
- { return Mat(*this, Range::all(), Range(startcol, endcol)); }
-inline Mat Mat::colRange(const Range& r) const
- { return Mat(*this, Range::all(), r); }
-
-inline Mat Mat::diag(const Mat& d)
-{
- CV_Assert( d.cols == 1 || d.rows == 1 );
- int len = d.rows + d.cols - 1;
- Mat m(len, len, d.type(), Scalar(0)), md = m.diag();
- if( d.cols == 1 )
- d.copyTo(md);
- else
- transpose(d, md);
- return m;
-}
-
-inline Mat Mat::clone() const
-{
- Mat m;
- copyTo(m);
- return m;
-}
+CV_EXPORTS InputOutputArray noArray();
-inline void Mat::assignTo( Mat& m, int _type ) const
-{
- if( _type < 0 )
- m = *this;
- else
- convertTo(m, _type);
-}
+/////////////////////////////////// MatAllocator //////////////////////////////////////
-inline void Mat::create(int _rows, int _cols, int _type)
+//! Usage flags for allocator
+enum UMatUsageFlags
{
- _type &= TYPE_MASK;
- if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
- return;
- int sz[] = {_rows, _cols};
- create(2, sz, _type);
-}
-
-inline void Mat::create(Size _sz, int _type)
-{
- create(_sz.height, _sz.width, _type);
-}
+ USAGE_DEFAULT = 0,
-inline void Mat::addref()
-{ if( refcount ) CV_XADD(refcount, 1); }
+ // default allocation policy is platform and usage specific
+ USAGE_ALLOCATE_HOST_MEMORY = 1 << 0,
+ USAGE_ALLOCATE_DEVICE_MEMORY = 1 << 1,
-inline void Mat::release()
-{
- if( refcount && CV_XADD(refcount, -1) == 1 )
- deallocate();
- data = datastart = dataend = datalimit = 0;
- for(int i = 0; i < dims; i++)
- size.p[i] = 0;
- refcount = 0;
-}
-
-inline Mat Mat::operator()( Range _rowRange, Range _colRange ) const
-{
- return Mat(*this, _rowRange, _colRange);
-}
+ __UMAT_USAGE_FLAGS_32BIT = 0x7fffffff // Binary compatibility hint
+};
-inline Mat Mat::operator()( const Rect& roi ) const
-{ return Mat(*this, roi); }
+struct CV_EXPORTS UMatData;
-inline Mat Mat::operator()(const Range* ranges) const
-{
- return Mat(*this, ranges);
-}
+/*!
+ Custom array allocator
-inline Mat::operator CvMat() const
-{
- CV_DbgAssert(dims <= 2);
- CvMat m = cvMat(rows, dims == 1 ? 1 : cols, type(), data);
- m.step = (int)step[0];
- m.type = (m.type & ~CONTINUOUS_FLAG) | (flags & CONTINUOUS_FLAG);
- return m;
-}
-
-inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
-inline bool Mat::isSubmatrix() const { return (flags & SUBMATRIX_FLAG) != 0; }
-inline size_t Mat::elemSize() const { return dims > 0 ? step.p[dims-1] : 0; }
-inline size_t Mat::elemSize1() const { return CV_ELEM_SIZE1(flags); }
-inline int Mat::type() const { return CV_MAT_TYPE(flags); }
-inline int Mat::depth() const { return CV_MAT_DEPTH(flags); }
-inline int Mat::channels() const { return CV_MAT_CN(flags); }
-inline size_t Mat::step1(int i) const { return step.p[i]/elemSize1(); }
-inline bool Mat::empty() const { return data == 0 || total() == 0; }
-inline size_t Mat::total() const
+*/
+class CV_EXPORTS MatAllocator
{
- if( dims <= 2 )
- return (size_t)rows*cols;
- size_t p = 1;
- for( int i = 0; i < dims; i++ )
- p *= size[i];
- return p;
-}
-
-inline uchar* Mat::ptr(int y)
-{
- CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
- return data + step.p[0]*y;
-}
+public:
+ MatAllocator() {}
+ virtual ~MatAllocator() {}
+
+ // let's comment it off for now to detect and fix all the uses of allocator
+ //virtual void allocate(int dims, const int* sizes, int type, int*& refcount,
+ // uchar*& datastart, uchar*& data, size_t* step) = 0;
+ //virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0;
+ virtual UMatData* allocate(int dims, const int* sizes, int type,
+ void* data, size_t* step, int flags, UMatUsageFlags usageFlags) const = 0;
+ virtual bool allocate(UMatData* data, int accessflags, UMatUsageFlags usageFlags) const = 0;
+ virtual void deallocate(UMatData* data) const = 0;
+ virtual void map(UMatData* data, int accessflags) const;
+ virtual void unmap(UMatData* data) const;
+ virtual void download(UMatData* data, void* dst, int dims, const size_t sz[],
+ const size_t srcofs[], const size_t srcstep[],
+ const size_t dststep[]) const;
+ virtual void upload(UMatData* data, const void* src, int dims, const size_t sz[],
+ const size_t dstofs[], const size_t dststep[],
+ const size_t srcstep[]) const;
+ virtual void copy(UMatData* srcdata, UMatData* dstdata, int dims, const size_t sz[],
+ const size_t srcofs[], const size_t srcstep[],
+ const size_t dstofs[], const size_t dststep[], bool sync) const;
+
+ // default implementation returns DummyBufferPoolController
+ virtual BufferPoolController* getBufferPoolController() const;
+};
-inline const uchar* Mat::ptr(int y) const
-{
- CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
- return data + step.p[0]*y;
-}
-template<typename _Tp> inline _Tp* Mat::ptr(int y)
-{
- CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
- return (_Tp*)(data + step.p[0]*y);
-}
+//////////////////////////////// MatCommaInitializer //////////////////////////////////
-template<typename _Tp> inline const _Tp* Mat::ptr(int y) const
-{
- CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
- return (const _Tp*)(data + step.p[0]*y);
-}
+/*!
+ Comma-separated Matrix Initializer
+ The class instances are usually not created explicitly.
+ Instead, they are created on "matrix << firstValue" operator.
-inline uchar* Mat::ptr(int i0, int i1)
-{
- CV_DbgAssert( dims >= 2 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] );
- return data + i0*step.p[0] + i1*step.p[1];
-}
+ The sample below initializes 2x2 rotation matrix:
-inline const uchar* Mat::ptr(int i0, int i1) const
+ \code
+ double angle = 30, a = cos(angle*CV_PI/180), b = sin(angle*CV_PI/180);
+ Mat R = (Mat_<double>(2,2) << a, -b, b, a);
+ \endcode
+*/
+template<typename _Tp> class MatCommaInitializer_
{
- CV_DbgAssert( dims >= 2 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] );
- return data + i0*step.p[0] + i1*step.p[1];
-}
+public:
+ //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat
+ MatCommaInitializer_(Mat_<_Tp>* _m);
+ //! the operator that takes the next value and put it to the matrix
+ template<typename T2> MatCommaInitializer_<_Tp>& operator , (T2 v);
+ //! another form of conversion operator
+ operator Mat_<_Tp>() const;
+protected:
+ MatIterator_<_Tp> it;
+};
-template<typename _Tp> inline _Tp* Mat::ptr(int i0, int i1)
-{
- CV_DbgAssert( dims >= 2 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] );
- return (_Tp*)(data + i0*step.p[0] + i1*step.p[1]);
-}
-template<typename _Tp> inline const _Tp* Mat::ptr(int i0, int i1) const
-{
- CV_DbgAssert( dims >= 2 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] );
- return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1]);
-}
+/////////////////////////////////////// Mat ///////////////////////////////////////////
+
+// note that umatdata might be allocated together
+// with the matrix data, not as a separate object.
+// therefore, it does not have constructor or destructor;
+// it should be explicitly initialized using init().
+struct CV_EXPORTS UMatData
+{
+ enum { COPY_ON_MAP=1, HOST_COPY_OBSOLETE=2,
+ DEVICE_COPY_OBSOLETE=4, TEMP_UMAT=8, TEMP_COPIED_UMAT=24,
+ USER_ALLOCATED=32, DEVICE_MEM_MAPPED=64};
+ UMatData(const MatAllocator* allocator);
+ ~UMatData();
+
+ // provide atomic access to the structure
+ void lock();
+ void unlock();
+
+ bool hostCopyObsolete() const;
+ bool deviceCopyObsolete() const;
+ bool deviceMemMapped() const;
+ bool copyOnMap() const;
+ bool tempUMat() const;
+ bool tempCopiedUMat() const;
+ void markHostCopyObsolete(bool flag);
+ void markDeviceCopyObsolete(bool flag);
+ void markDeviceMemMapped(bool flag);
+
+ const MatAllocator* prevAllocator;
+ const MatAllocator* currAllocator;
+ int urefcount;
+ int refcount;
+ uchar* data;
+ uchar* origdata;
+ size_t size, capacity;
-inline uchar* Mat::ptr(int i0, int i1, int i2)
-{
- CV_DbgAssert( dims >= 3 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] &&
- (unsigned)i2 < (unsigned)size.p[2] );
- return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2];
-}
-
-inline const uchar* Mat::ptr(int i0, int i1, int i2) const
-{
- CV_DbgAssert( dims >= 3 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] &&
- (unsigned)i2 < (unsigned)size.p[2] );
- return data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2];
-}
-
-template<typename _Tp> inline _Tp* Mat::ptr(int i0, int i1, int i2)
-{
- CV_DbgAssert( dims >= 3 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] &&
- (unsigned)i2 < (unsigned)size.p[2] );
- return (_Tp*)(data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]);
-}
-
-template<typename _Tp> inline const _Tp* Mat::ptr(int i0, int i1, int i2) const
-{
- CV_DbgAssert( dims >= 3 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] &&
- (unsigned)i2 < (unsigned)size.p[2] );
- return (const _Tp*)(data + i0*step.p[0] + i1*step.p[1] + i2*step.p[2]);
-}
-
-inline uchar* Mat::ptr(const int* idx)
-{
- int i, d = dims;
- uchar* p = data;
- CV_DbgAssert( d >= 1 && p );
- for( i = 0; i < d; i++ )
- {
- CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
- p += idx[i]*step.p[i];
- }
- return p;
-}
+ int flags;
+ void* handle;
+ void* userdata;
+ int allocatorFlags_;
+};
-inline const uchar* Mat::ptr(const int* idx) const
-{
- int i, d = dims;
- uchar* p = data;
- CV_DbgAssert( d >= 1 && p );
- for( i = 0; i < d; i++ )
- {
- CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
- p += idx[i]*step.p[i];
- }
- return p;
-}
-template<typename _Tp> inline _Tp& Mat::at(int i0, int i1)
+struct CV_EXPORTS UMatDataAutoLock
{
- CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
- CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
- return ((_Tp*)(data + step.p[0]*i0))[i1];
-}
+ explicit UMatDataAutoLock(UMatData* u);
+ ~UMatDataAutoLock();
+ UMatData* u;
+};
-template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1) const
-{
- CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
- CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
- return ((const _Tp*)(data + step.p[0]*i0))[i1];
-}
-template<typename _Tp> inline _Tp& Mat::at(Point pt)
+struct CV_EXPORTS MatSize
{
- CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
- (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
- CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
- return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
-}
+ explicit MatSize(int* _p);
+ Size operator()() const;
+ const int& operator[](int i) const;
+ int& operator[](int i);
+ operator const int*() const;
+ bool operator == (const MatSize& sz) const;
+ bool operator != (const MatSize& sz) const;
-template<typename _Tp> inline const _Tp& Mat::at(Point pt) const
-{
- CV_DbgAssert( dims <= 2 && data && (unsigned)pt.y < (unsigned)size.p[0] &&
- (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) &&
- CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
- return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
-}
+ int* p;
+};
-template<typename _Tp> inline _Tp& Mat::at(int i0)
-{
- CV_DbgAssert( dims <= 2 && data &&
- (unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) &&
- elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- if( isContinuous() || size.p[0] == 1 )
- return ((_Tp*)data)[i0];
- if( size.p[1] == 1 )
- return *(_Tp*)(data + step.p[0]*i0);
- int i = i0/cols, j = i0 - i*cols;
- return ((_Tp*)(data + step.p[0]*i))[j];
-}
-
-template<typename _Tp> inline const _Tp& Mat::at(int i0) const
-{
- CV_DbgAssert( dims <= 2 && data &&
- (unsigned)i0 < (unsigned)(size.p[0]*size.p[1]) &&
- elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- if( isContinuous() || size.p[0] == 1 )
- return ((const _Tp*)data)[i0];
- if( size.p[1] == 1 )
- return *(const _Tp*)(data + step.p[0]*i0);
- int i = i0/cols, j = i0 - i*cols;
- return ((const _Tp*)(data + step.p[0]*i))[j];
-}
-
-template<typename _Tp> inline _Tp& Mat::at(int i0, int i1, int i2)
-{
- CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- return *(_Tp*)ptr(i0, i1, i2);
-}
-template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1, int i2) const
-{
- CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- return *(const _Tp*)ptr(i0, i1, i2);
-}
-template<typename _Tp> inline _Tp& Mat::at(const int* idx)
-{
- CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- return *(_Tp*)ptr(idx);
-}
-template<typename _Tp> inline const _Tp& Mat::at(const int* idx) const
-{
- CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- return *(const _Tp*)ptr(idx);
-}
-template<typename _Tp, int n> _Tp& Mat::at(const Vec<int, n>& idx)
-{
- CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- return *(_Tp*)ptr(idx.val);
-}
-template<typename _Tp, int n> inline const _Tp& Mat::at(const Vec<int, n>& idx) const
+struct CV_EXPORTS MatStep
{
- CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) );
- return *(const _Tp*)ptr(idx.val);
-}
+ MatStep();
+ explicit MatStep(size_t s);
+ const size_t& operator[](int i) const;
+ size_t& operator[](int i);
+ operator size_t() const;
+ MatStep& operator = (size_t s);
+ size_t* p;
+ size_t buf[2];
+protected:
+ MatStep& operator = (const MatStep&);
+};
-template<typename _Tp> inline MatConstIterator_<_Tp> Mat::begin() const
-{
- CV_DbgAssert( elemSize() == sizeof(_Tp) );
- return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
-}
-
-template<typename _Tp> inline MatConstIterator_<_Tp> Mat::end() const
+ /*!
+ The n-dimensional matrix class.
+
+ The class represents an n-dimensional dense numerical array that can act as
+ a matrix, image, optical flow map, 3-focal tensor etc.
+ It is very similar to CvMat and CvMatND types from earlier versions of OpenCV,
+ and similarly to those types, the matrix can be multi-channel. It also fully supports ROI mechanism.
+
+ There are many different ways to create cv::Mat object. Here are the some popular ones:
+ <ul>
+ <li> using cv::Mat::create(nrows, ncols, type) method or
+ the similar constructor cv::Mat::Mat(nrows, ncols, type[, fill_value]) constructor.
+ A new matrix of the specified size and specifed type will be allocated.
+ "type" has the same meaning as in cvCreateMat function,
+ e.g. CV_8UC1 means 8-bit single-channel matrix, CV_32FC2 means 2-channel (i.e. complex)
+ floating-point matrix etc:
+
+ \code
+ // make 7x7 complex matrix filled with 1+3j.
+ cv::Mat M(7,7,CV_32FC2,Scalar(1,3));
+ // and now turn M to 100x60 15-channel 8-bit matrix.
+ // The old content will be deallocated
+ M.create(100,60,CV_8UC(15));
+ \endcode
+
+ As noted in the introduction of this chapter, Mat::create()
+ will only allocate a new matrix when the current matrix dimensionality
+ or type are different from the specified.
+
+ <li> by using a copy constructor or assignment operator, where on the right side it can
+ be a matrix or expression, see below. Again, as noted in the introduction,
+ matrix assignment is O(1) operation because it only copies the header
+ and increases the reference counter. cv::Mat::clone() method can be used to get a full
+ (a.k.a. deep) copy of the matrix when you need it.
+
+ <li> by constructing a header for a part of another matrix. It can be a single row, single column,
+ several rows, several columns, rectangular region in the matrix (called a minor in algebra) or
+ a diagonal. Such operations are also O(1), because the new header will reference the same data.
+ You can actually modify a part of the matrix using this feature, e.g.
+
+ \code
+ // add 5-th row, multiplied by 3 to the 3rd row
+ M.row(3) = M.row(3) + M.row(5)*3;
+
+ // now copy 7-th column to the 1-st column
+ // M.col(1) = M.col(7); // this will not work
+ Mat M1 = M.col(1);
+ M.col(7).copyTo(M1);
+
+ // create new 320x240 image
+ cv::Mat img(Size(320,240),CV_8UC3);
+ // select a roi
+ cv::Mat roi(img, Rect(10,10,100,100));
+ // fill the ROI with (0,255,0) (which is green in RGB space);
+ // the original 320x240 image will be modified
+ roi = Scalar(0,255,0);
+ \endcode
+
+ Thanks to the additional cv::Mat::datastart and cv::Mat::dataend members, it is possible to
+ compute the relative sub-matrix position in the main "container" matrix using cv::Mat::locateROI():
+
+ \code
+ Mat A = Mat::eye(10, 10, CV_32S);
+ // extracts A columns, 1 (inclusive) to 3 (exclusive).
+ Mat B = A(Range::all(), Range(1, 3));
+ // extracts B rows, 5 (inclusive) to 9 (exclusive).
+ // that is, C ~ A(Range(5, 9), Range(1, 3))
+ Mat C = B(Range(5, 9), Range::all());
+ Size size; Point ofs;
+ C.locateROI(size, ofs);
+ // size will be (width=10,height=10) and the ofs will be (x=1, y=5)
+ \endcode
+
+ As in the case of whole matrices, if you need a deep copy, use cv::Mat::clone() method
+ of the extracted sub-matrices.
+
+ <li> by making a header for user-allocated-data. It can be useful for
+ <ol>
+ <li> processing "foreign" data using OpenCV (e.g. when you implement
+ a DirectShow filter or a processing module for gstreamer etc.), e.g.
+
+ \code
+ void process_video_frame(const unsigned char* pixels,
+ int width, int height, int step)
+ {
+ cv::Mat img(height, width, CV_8UC3, pixels, step);
+ cv::GaussianBlur(img, img, cv::Size(7,7), 1.5, 1.5);
+ }
+ \endcode
+
+ <li> for quick initialization of small matrices and/or super-fast element access
+
+ \code
+ double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};
+ cv::Mat M = cv::Mat(3, 3, CV_64F, m).inv();
+ \endcode
+ </ol>
+
+ partial yet very common cases of this "user-allocated data" case are conversions
+ from CvMat and IplImage to cv::Mat. For this purpose there are special constructors
+ taking pointers to CvMat or IplImage and the optional
+ flag indicating whether to copy the data or not.
+
+ Backward conversion from cv::Mat to CvMat or IplImage is provided via cast operators
+ cv::Mat::operator CvMat() an cv::Mat::operator IplImage().
+ The operators do not copy the data.
+
+
+ \code
+ IplImage* img = cvLoadImage("greatwave.jpg", 1);
+ Mat mtx(img); // convert IplImage* -> cv::Mat
+ CvMat oldmat = mtx; // convert cv::Mat -> CvMat
+ CV_Assert(oldmat.cols == img->width && oldmat.rows == img->height &&
+ oldmat.data.ptr == (uchar*)img->imageData && oldmat.step == img->widthStep);
+ \endcode
+
+ <li> by using MATLAB-style matrix initializers, cv::Mat::zeros(), cv::Mat::ones(), cv::Mat::eye(), e.g.:
+
+ \code
+ // create a double-precision identity martix and add it to M.
+ M += Mat::eye(M.rows, M.cols, CV_64F);
+ \endcode
+
+ <li> by using comma-separated initializer:
+
+ \code
+ // create 3x3 double-precision identity matrix
+ Mat M = (Mat_<double>(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
+ \endcode
+
+ here we first call constructor of cv::Mat_ class (that we describe further) with the proper matrix,
+ and then we just put "<<" operator followed by comma-separated values that can be constants,
+ variables, expressions etc. Also, note the extra parentheses that are needed to avoid compiler errors.
+
+ </ul>
+
+ Once matrix is created, it will be automatically managed by using reference-counting mechanism
+ (unless the matrix header is built on top of user-allocated data,
+ in which case you should handle the data by yourself).
+ The matrix data will be deallocated when no one points to it;
+ if you want to release the data pointed by a matrix header before the matrix destructor is called,
+ use cv::Mat::release().
+
+ The next important thing to learn about the matrix class is element access. Here is how the matrix is stored.
+ The elements are stored in row-major order (row by row). The cv::Mat::data member points to the first element of the first row,
+ cv::Mat::rows contains the number of matrix rows and cv::Mat::cols - the number of matrix columns. There is yet another member,
+ cv::Mat::step that is used to actually compute address of a matrix element. cv::Mat::step is needed because the matrix can be
+ a part of another matrix or because there can some padding space in the end of each row for a proper alignment.
+
+ Given these parameters, address of the matrix element M_{ij} is computed as following:
+
+ addr(M_{ij})=M.data + M.step*i + j*M.elemSize()
+
+ if you know the matrix element type, e.g. it is float, then you can use cv::Mat::at() method:
+
+ addr(M_{ij})=&M.at<float>(i,j)
+
+ (where & is used to convert the reference returned by cv::Mat::at() to a pointer).
+ if you need to process a whole row of matrix, the most efficient way is to get
+ the pointer to the row first, and then just use plain C operator []:
+
+ \code
+ // compute sum of positive matrix elements
+ // (assuming that M is double-precision matrix)
+ double sum=0;
+ for(int i = 0; i < M.rows; i++)
+ {
+ const double* Mi = M.ptr<double>(i);
+ for(int j = 0; j < M.cols; j++)
+ sum += std::max(Mi[j], 0.);
+ }
+ \endcode
+
+ Some operations, like the above one, do not actually depend on the matrix shape,
+ they just process elements of a matrix one by one (or elements from multiple matrices
+ that are sitting in the same place, e.g. matrix addition). Such operations are called
+ element-wise and it makes sense to check whether all the input/output matrices are continuous,
+ i.e. have no gaps in the end of each row, and if yes, process them as a single long row:
+
+ \code
+ // compute sum of positive matrix elements, optimized variant
+ double sum=0;
+ int cols = M.cols, rows = M.rows;
+ if(M.isContinuous())
+ {
+ cols *= rows;
+ rows = 1;
+ }
+ for(int i = 0; i < rows; i++)
+ {
+ const double* Mi = M.ptr<double>(i);
+ for(int j = 0; j < cols; j++)
+ sum += std::max(Mi[j], 0.);
+ }
+ \endcode
+ in the case of continuous matrix the outer loop body will be executed just once,
+ so the overhead will be smaller, which will be especially noticeable in the case of small matrices.
+
+ Finally, there are STL-style iterators that are smart enough to skip gaps between successive rows:
+ \code
+ // compute sum of positive matrix elements, iterator-based variant
+ double sum=0;
+ MatConstIterator_<double> it = M.begin<double>(), it_end = M.end<double>();
+ for(; it != it_end; ++it)
+ sum += std::max(*it, 0.);
+ \endcode
+
+ The matrix iterators are random-access iterators, so they can be passed
+ to any STL algorithm, including std::sort().
+*/
+class CV_EXPORTS Mat
{
- CV_DbgAssert( elemSize() == sizeof(_Tp) );
- MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
- it += total();
- return it;
-}
+public:
+ //! default constructor
+ Mat();
+ //! constructs 2D matrix of the specified size and type
+ // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
+ Mat(int rows, int cols, int type);
+ Mat(Size size, int type);
+ //! constucts 2D matrix and fills it with the specified value _s.
+ Mat(int rows, int cols, int type, const Scalar& s);
+ Mat(Size size, int type, const Scalar& s);
+
+ //! constructs n-dimensional matrix
+ Mat(int ndims, const int* sizes, int type);
+ Mat(int ndims, const int* sizes, int type, const Scalar& s);
+
+ //! copy constructor
+ Mat(const Mat& m);
+ //! constructor for matrix headers pointing to user-allocated data
+ Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
+ Mat(Size size, int type, void* data, size_t step=AUTO_STEP);
+ Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0);
+
+ //! creates a matrix header for a part of the bigger matrix
+ Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());
+ Mat(const Mat& m, const Rect& roi);
+ Mat(const Mat& m, const Range* ranges);
+ //! builds matrix from std::vector with or without copying the data
+ template<typename _Tp> explicit Mat(const std::vector<_Tp>& vec, bool copyData=false);
+ //! builds matrix from cv::Vec; the data is copied by default
+ template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true);
+ //! builds matrix from cv::Matx; the data is copied by default
+ template<typename _Tp, int m, int n> explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true);
+ //! builds matrix from a 2D point
+ template<typename _Tp> explicit Mat(const Point_<_Tp>& pt, bool copyData=true);
+ //! builds matrix from a 3D point
+ template<typename _Tp> explicit Mat(const Point3_<_Tp>& pt, bool copyData=true);
+ //! builds matrix from comma initializer
+ template<typename _Tp> explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer);
+
+ //! download data from GpuMat
+ explicit Mat(const cuda::GpuMat& m);
+
+ //! destructor - calls release()
+ ~Mat();
+ //! assignment operators
+ Mat& operator = (const Mat& m);
+ Mat& operator = (const MatExpr& expr);
+
+ //! retrieve UMat from Mat
+ UMat getUMat(int accessFlags, UMatUsageFlags usageFlags = USAGE_DEFAULT) const;
+
+ //! returns a new matrix header for the specified row
+ Mat row(int y) const;
+ //! returns a new matrix header for the specified column
+ Mat col(int x) const;
+ //! ... for the specified row span
+ Mat rowRange(int startrow, int endrow) const;
+ Mat rowRange(const Range& r) const;
+ //! ... for the specified column span
+ Mat colRange(int startcol, int endcol) const;
+ Mat colRange(const Range& r) const;
+ //! ... for the specified diagonal
+ // (d=0 - the main diagonal,
+ // >0 - a diagonal from the lower half,
+ // <0 - a diagonal from the upper half)
+ Mat diag(int d=0) const;
+ //! constructs a square diagonal matrix which main diagonal is vector "d"
+ static Mat diag(const Mat& d);
+
+ //! returns deep copy of the matrix, i.e. the data is copied
+ Mat clone() const;
+ //! copies the matrix content to "m".
+ // It calls m.create(this->size(), this->type()).
+ void copyTo( OutputArray m ) const;
+ //! copies those matrix elements to "m" that are marked with non-zero mask elements.
+ void copyTo( OutputArray m, InputArray mask ) const;
+ //! converts matrix to another datatype with optional scalng. See cvConvertScale.
+ void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
+
+ void assignTo( Mat& m, int type=-1 ) const;
+
+ //! sets every matrix element to s
+ Mat& operator = (const Scalar& s);
+ //! sets some of the matrix elements to s, according to the mask
+ Mat& setTo(InputArray value, InputArray mask=noArray());
+ //! creates alternative matrix header for the same data, with different
+ // number of channels and/or different number of rows. see cvReshape.
+ Mat reshape(int cn, int rows=0) const;
+ Mat reshape(int cn, int newndims, const int* newsz) const;
+
+ //! matrix transposition by means of matrix expressions
+ MatExpr t() const;
+ //! matrix inversion by means of matrix expressions
+ MatExpr inv(int method=DECOMP_LU) const;
+ //! per-element matrix multiplication by means of matrix expressions
+ MatExpr mul(InputArray m, double scale=1) const;
+
+ //! computes cross-product of 2 3D vectors
+ Mat cross(InputArray m) const;
+ //! computes dot-product
+ double dot(InputArray m) const;
+
+ //! Matlab-style matrix initialization
+ static MatExpr zeros(int rows, int cols, int type);
+ static MatExpr zeros(Size size, int type);
+ static MatExpr zeros(int ndims, const int* sz, int type);
+ static MatExpr ones(int rows, int cols, int type);
+ static MatExpr ones(Size size, int type);
+ static MatExpr ones(int ndims, const int* sz, int type);
+ static MatExpr eye(int rows, int cols, int type);
+ static MatExpr eye(Size size, int type);
+
+ //! allocates new matrix data unless the matrix already has specified size and type.
+ // previous data is unreferenced if needed.
+ void create(int rows, int cols, int type);
+ void create(Size size, int type);
+ void create(int ndims, const int* sizes, int type);
+
+ //! increases the reference counter; use with care to avoid memleaks
+ void addref();
+ //! decreases reference counter;
+ // deallocates the data when reference counter reaches 0.
+ void release();
+
+ //! deallocates the matrix data
+ void deallocate();
+ //! internal use function; properly re-allocates _size, _step arrays
+ void copySize(const Mat& m);
+
+ //! reserves enough space to fit sz hyper-planes
+ void reserve(size_t sz);
+ //! resizes matrix to the specified number of hyper-planes
+ void resize(size_t sz);
+ //! resizes matrix to the specified number of hyper-planes; initializes the newly added elements
+ void resize(size_t sz, const Scalar& s);
+ //! internal function
+ void push_back_(const void* elem);
+ //! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat)
+ template<typename _Tp> void push_back(const _Tp& elem);
+ template<typename _Tp> void push_back(const Mat_<_Tp>& elem);
+ void push_back(const Mat& m);
+ //! removes several hyper-planes from bottom of the matrix
+ void pop_back(size_t nelems=1);
+
+ //! locates matrix header within a parent matrix. See below
+ void locateROI( Size& wholeSize, Point& ofs ) const;
+ //! moves/resizes the current matrix ROI inside the parent matrix.
+ Mat& adjustROI( int dtop, int dbottom, int dleft, int dright );
+ //! extracts a rectangular sub-matrix
+ // (this is a generalized form of row, rowRange etc.)
+ Mat operator()( Range rowRange, Range colRange ) const;
+ Mat operator()( const Rect& roi ) const;
+ Mat operator()( const Range* ranges ) const;
+
+ // //! converts header to CvMat; no data is copied
+ // operator CvMat() const;
+ // //! converts header to CvMatND; no data is copied
+ // operator CvMatND() const;
+ // //! converts header to IplImage; no data is copied
+ // operator IplImage() const;
+
+ template<typename _Tp> operator std::vector<_Tp>() const;
+ template<typename _Tp, int n> operator Vec<_Tp, n>() const;
+ template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const;
+
+ //! returns true iff the matrix data is continuous
+ // (i.e. when there are no gaps between successive rows).
+ // similar to CV_IS_MAT_CONT(cvmat->type)
+ bool isContinuous() const;
+
+ //! returns true if the matrix is a submatrix of another matrix
+ bool isSubmatrix() const;
+
+ //! returns element size in bytes,
+ // similar to CV_ELEM_SIZE(cvmat->type)
+ size_t elemSize() const;
+ //! returns the size of element channel in bytes.
+ size_t elemSize1() const;
+ //! returns element type, similar to CV_MAT_TYPE(cvmat->type)
+ int type() const;
+ //! returns element type, similar to CV_MAT_DEPTH(cvmat->type)
+ int depth() const;
+ //! returns element type, similar to CV_MAT_CN(cvmat->type)
+ int channels() const;
+ //! returns step/elemSize1()
+ size_t step1(int i=0) const;
+ //! returns true if matrix data is NULL
+ bool empty() const;
+ //! returns the total number of matrix elements
+ size_t total() const;
+
+ //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise
+ int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const;
+
+ //! returns pointer to i0-th submatrix along the dimension #0
+ uchar* ptr(int i0=0);
+ const uchar* ptr(int i0=0) const;
+
+ //! returns pointer to (i0,i1) submatrix along the dimensions #0 and #1
+ uchar* ptr(int i0, int i1);
+ const uchar* ptr(int i0, int i1) const;
+
+ //! returns pointer to (i0,i1,i3) submatrix along the dimensions #0, #1, #2
+ uchar* ptr(int i0, int i1, int i2);
+ const uchar* ptr(int i0, int i1, int i2) const;
+
+ //! returns pointer to the matrix element
+ uchar* ptr(const int* idx);
+ //! returns read-only pointer to the matrix element
+ const uchar* ptr(const int* idx) const;
+
+ template<int n> uchar* ptr(const Vec<int, n>& idx);
+ template<int n> const uchar* ptr(const Vec<int, n>& idx) const;
+
+ //! template version of the above method
+ template<typename _Tp> _Tp* ptr(int i0=0);
+ template<typename _Tp> const _Tp* ptr(int i0=0) const;
+
+ template<typename _Tp> _Tp* ptr(int i0, int i1);
+ template<typename _Tp> const _Tp* ptr(int i0, int i1) const;
+
+ template<typename _Tp> _Tp* ptr(int i0, int i1, int i2);
+ template<typename _Tp> const _Tp* ptr(int i0, int i1, int i2) const;
+
+ template<typename _Tp> _Tp* ptr(const int* idx);
+ template<typename _Tp> const _Tp* ptr(const int* idx) const;
+
+ template<typename _Tp, int n> _Tp* ptr(const Vec<int, n>& idx);
+ template<typename _Tp, int n> const _Tp* ptr(const Vec<int, n>& idx) const;
+
+ //! the same as above, with the pointer dereferencing
+ template<typename _Tp> _Tp& at(int i0=0);
+ template<typename _Tp> const _Tp& at(int i0=0) const;
+
+ template<typename _Tp> _Tp& at(int i0, int i1);
+ template<typename _Tp> const _Tp& at(int i0, int i1) const;
+
+ template<typename _Tp> _Tp& at(int i0, int i1, int i2);
+ template<typename _Tp> const _Tp& at(int i0, int i1, int i2) const;
+
+ template<typename _Tp> _Tp& at(const int* idx);
+ template<typename _Tp> const _Tp& at(const int* idx) const;
+
+ template<typename _Tp, int n> _Tp& at(const Vec<int, n>& idx);
+ template<typename _Tp, int n> const _Tp& at(const Vec<int, n>& idx) const;
+
+ //! special versions for 2D arrays (especially convenient for referencing image pixels)
+ template<typename _Tp> _Tp& at(Point pt);
+ template<typename _Tp> const _Tp& at(Point pt) const;
+
+ //! template methods for iteration over matrix elements.
+ // the iterators take care of skipping gaps in the end of rows (if any)
+ template<typename _Tp> MatIterator_<_Tp> begin();
+ template<typename _Tp> MatIterator_<_Tp> end();
+ template<typename _Tp> MatConstIterator_<_Tp> begin() const;
+ template<typename _Tp> MatConstIterator_<_Tp> end() const;
+
+ //! template methods for for operation over all matrix elements.
+ // the operations take care of skipping gaps in the end of rows (if any)
+ template<typename _Tp, typename Functor> void forEach(const Functor& operation);
+ template<typename _Tp, typename Functor> void forEach(const Functor& operation) const;
+
+ enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };
+ enum { MAGIC_MASK = 0xFFFF0000, TYPE_MASK = 0x00000FFF, DEPTH_MASK = 7 };
+
+ /*! includes several bit-fields:
+ - the magic signature
+ - continuity flag
+ - depth
+ - number of channels
+ */
+ int flags;
+ //! the matrix dimensionality, >= 2
+ int dims;
+ //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
+ int rows, cols;
+ //! pointer to the data
+ uchar* data;
+
+ //! helper fields used in locateROI and adjustROI
+ const uchar* datastart;
+ const uchar* dataend;
+ const uchar* datalimit;
+
+ //! custom allocator
+ MatAllocator* allocator;
+ //! and the standard allocator
+ static MatAllocator* getStdAllocator();
+
+ //! interaction with UMat
+ UMatData* u;
+
+ MatSize size;
+ MatStep step;
+
+protected:
+ template<typename _Tp, typename Functor> void forEach_impl(const Functor& operation);
+};
-template<typename _Tp> inline MatIterator_<_Tp> Mat::begin()
-{
- CV_DbgAssert( elemSize() == sizeof(_Tp) );
- return MatIterator_<_Tp>((Mat_<_Tp>*)this);
-}
-template<typename _Tp> inline MatIterator_<_Tp> Mat::end()
-{
- CV_DbgAssert( elemSize() == sizeof(_Tp) );
- MatIterator_<_Tp> it((Mat_<_Tp>*)this);
- it += total();
- return it;
-}
+///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
-template<typename _Tp> inline Mat::operator vector<_Tp>() const
+/*!
+ Template matrix class derived from Mat
+
+ The class Mat_ is a "thin" template wrapper on top of cv::Mat. It does not have any extra data fields,
+ nor it or cv::Mat have any virtual methods and thus references or pointers to these two classes
+ can be safely converted one to another. But do it with care, for example:
+
+ \code
+ // create 100x100 8-bit matrix
+ Mat M(100,100,CV_8U);
+ // this will compile fine. no any data conversion will be done.
+ Mat_<float>& M1 = (Mat_<float>&)M;
+ // the program will likely crash at the statement below
+ M1(99,99) = 1.f;
+ \endcode
+
+ While cv::Mat is sufficient in most cases, cv::Mat_ can be more convenient if you use a lot of element
+ access operations and if you know matrix type at compile time. Note that cv::Mat::at and
+ cv::Mat::operator() do absolutely the same thing and run at the same speed, but the latter is certainly shorter:
+
+ \code
+ Mat_<double> M(20,20);
+ for(int i = 0; i < M.rows; i++)
+ for(int j = 0; j < M.cols; j++)
+ M(i,j) = 1./(i+j+1);
+ Mat E, V;
+ eigen(M,E,V);
+ cout << E.at<double>(0,0)/E.at<double>(M.rows-1,0);
+ \endcode
+
+ It is easy to use Mat_ for multi-channel images/matrices - just pass cv::Vec as cv::Mat_ template parameter:
+
+ \code
+ // allocate 320x240 color image and fill it with green (in RGB space)
+ Mat_<Vec3b> img(240, 320, Vec3b(0,255,0));
+ // now draw a diagonal white line
+ for(int i = 0; i < 100; i++)
+ img(i,i)=Vec3b(255,255,255);
+ // and now modify the 2nd (red) channel of each pixel
+ for(int i = 0; i < img.rows; i++)
+ for(int j = 0; j < img.cols; j++)
+ img(i,j)[2] ^= (uchar)(i ^ j); // img(y,x)[c] accesses c-th channel of the pixel (x,y)
+ \endcode
+*/
+template<typename _Tp> class Mat_ : public Mat
{
- vector<_Tp> v;
- copyTo(v);
- return v;
-}
+public:
+ typedef _Tp value_type;
+ typedef typename DataType<_Tp>::channel_type channel_type;
+ typedef MatIterator_<_Tp> iterator;
+ typedef MatConstIterator_<_Tp> const_iterator;
+
+ //! default constructor
+ Mat_();
+ //! equivalent to Mat(_rows, _cols, DataType<_Tp>::type)
+ Mat_(int _rows, int _cols);
+ //! constructor that sets each matrix element to specified value
+ Mat_(int _rows, int _cols, const _Tp& value);
+ //! equivalent to Mat(_size, DataType<_Tp>::type)
+ explicit Mat_(Size _size);
+ //! constructor that sets each matrix element to specified value
+ Mat_(Size _size, const _Tp& value);
+ //! n-dim array constructor
+ Mat_(int _ndims, const int* _sizes);
+ //! n-dim array constructor that sets each matrix element to specified value
+ Mat_(int _ndims, const int* _sizes, const _Tp& value);
+ //! copy/conversion contructor. If m is of different type, it's converted
+ Mat_(const Mat& m);
+ //! copy constructor
+ Mat_(const Mat_& m);
+ //! constructs a matrix on top of user-allocated data. step is in bytes(!!!), regardless of the type
+ Mat_(int _rows, int _cols, _Tp* _data, size_t _step=AUTO_STEP);
+ //! constructs n-dim matrix on top of user-allocated data. steps are in bytes(!!!), regardless of the type
+ Mat_(int _ndims, const int* _sizes, _Tp* _data, const size_t* _steps=0);
+ //! selects a submatrix
+ Mat_(const Mat_& m, const Range& rowRange, const Range& colRange=Range::all());
+ //! selects a submatrix
+ Mat_(const Mat_& m, const Rect& roi);
+ //! selects a submatrix, n-dim version
+ Mat_(const Mat_& m, const Range* ranges);
+ //! from a matrix expression
+ explicit Mat_(const MatExpr& e);
+ //! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column
+ explicit Mat_(const std::vector<_Tp>& vec, bool copyData=false);
+ template<int n> explicit Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData=true);
+ template<int m, int n> explicit Mat_(const Matx<typename DataType<_Tp>::channel_type, m, n>& mtx, bool copyData=true);
+ explicit Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
+ explicit Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
+ explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
+
+ Mat_& operator = (const Mat& m);
+ Mat_& operator = (const Mat_& m);
+ //! set all the elements to s.
+ Mat_& operator = (const _Tp& s);
+ //! assign a matrix expression
+ Mat_& operator = (const MatExpr& e);
+
+ //! iterators; they are smart enough to skip gaps in the end of rows
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ //! template methods for for operation over all matrix elements.
+ // the operations take care of skipping gaps in the end of rows (if any)
+ template<typename Functor> void forEach(const Functor& operation);
+ template<typename Functor> void forEach(const Functor& operation) const;
+
+ //! equivalent to Mat::create(_rows, _cols, DataType<_Tp>::type)
+ void create(int _rows, int _cols);
+ //! equivalent to Mat::create(_size, DataType<_Tp>::type)
+ void create(Size _size);
+ //! equivalent to Mat::create(_ndims, _sizes, DatType<_Tp>::type)
+ void create(int _ndims, const int* _sizes);
+ //! cross-product
+ Mat_ cross(const Mat_& m) const;
+ //! data type conversion
+ template<typename T2> operator Mat_<T2>() const;
+ //! overridden forms of Mat::row() etc.
+ Mat_ row(int y) const;
+ Mat_ col(int x) const;
+ Mat_ diag(int d=0) const;
+ Mat_ clone() const;
+
+ //! overridden forms of Mat::elemSize() etc.
+ size_t elemSize() const;
+ size_t elemSize1() const;
+ int type() const;
+ int depth() const;
+ int channels() const;
+ size_t step1(int i=0) const;
+ //! returns step()/sizeof(_Tp)
+ size_t stepT(int i=0) const;
+
+ //! overridden forms of Mat::zeros() etc. Data type is omitted, of course
+ static MatExpr zeros(int rows, int cols);
+ static MatExpr zeros(Size size);
+ static MatExpr zeros(int _ndims, const int* _sizes);
+ static MatExpr ones(int rows, int cols);
+ static MatExpr ones(Size size);
+ static MatExpr ones(int _ndims, const int* _sizes);
+ static MatExpr eye(int rows, int cols);
+ static MatExpr eye(Size size);
+
+ //! some more overriden methods
+ Mat_& adjustROI( int dtop, int dbottom, int dleft, int dright );
+ Mat_ operator()( const Range& rowRange, const Range& colRange ) const;
+ Mat_ operator()( const Rect& roi ) const;
+ Mat_ operator()( const Range* ranges ) const;
+
+ //! more convenient forms of row and element access operators
+ _Tp* operator [](int y);
+ const _Tp* operator [](int y) const;
+
+ //! returns reference to the specified element
+ _Tp& operator ()(const int* idx);
+ //! returns read-only reference to the specified element
+ const _Tp& operator ()(const int* idx) const;
+
+ //! returns reference to the specified element
+ template<int n> _Tp& operator ()(const Vec<int, n>& idx);
+ //! returns read-only reference to the specified element
+ template<int n> const _Tp& operator ()(const Vec<int, n>& idx) const;
+
+ //! returns reference to the specified element (1D case)
+ _Tp& operator ()(int idx0);
+ //! returns read-only reference to the specified element (1D case)
+ const _Tp& operator ()(int idx0) const;
+ //! returns reference to the specified element (2D case)
+ _Tp& operator ()(int idx0, int idx1);
+ //! returns read-only reference to the specified element (2D case)
+ const _Tp& operator ()(int idx0, int idx1) const;
+ //! returns reference to the specified element (3D case)
+ _Tp& operator ()(int idx0, int idx1, int idx2);
+ //! returns read-only reference to the specified element (3D case)
+ const _Tp& operator ()(int idx0, int idx1, int idx2) const;
+
+ _Tp& operator ()(Point pt);
+ const _Tp& operator ()(Point pt) const;
+
+ //! conversion to vector.
+ operator std::vector<_Tp>() const;
+ //! conversion to Vec
+ template<int n> operator Vec<typename DataType<_Tp>::channel_type, n>() const;
+ //! conversion to Matx
+ template<int m, int n> operator Matx<typename DataType<_Tp>::channel_type, m, n>() const;
+};
-template<typename _Tp, int n> inline Mat::operator Vec<_Tp, n>() const
-{
- CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
- rows + cols - 1 == n && channels() == 1 );
+typedef Mat_<uchar> Mat1b;
+typedef Mat_<Vec2b> Mat2b;
+typedef Mat_<Vec3b> Mat3b;
+typedef Mat_<Vec4b> Mat4b;
- if( isContinuous() && type() == DataType<_Tp>::type )
- return Vec<_Tp, n>((_Tp*)data);
- Vec<_Tp, n> v; Mat tmp(rows, cols, DataType<_Tp>::type, v.val);
- convertTo(tmp, tmp.type());
- return v;
-}
+typedef Mat_<short> Mat1s;
+typedef Mat_<Vec2s> Mat2s;
+typedef Mat_<Vec3s> Mat3s;
+typedef Mat_<Vec4s> Mat4s;
-template<typename _Tp, int m, int n> inline Mat::operator Matx<_Tp, m, n>() const
-{
- CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
+typedef Mat_<ushort> Mat1w;
+typedef Mat_<Vec2w> Mat2w;
+typedef Mat_<Vec3w> Mat3w;
+typedef Mat_<Vec4w> Mat4w;
- if( isContinuous() && type() == DataType<_Tp>::type )
- return Matx<_Tp, m, n>((_Tp*)data);
- Matx<_Tp, m, n> mtx; Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val);
- convertTo(tmp, tmp.type());
- return mtx;
-}
+typedef Mat_<int> Mat1i;
+typedef Mat_<Vec2i> Mat2i;
+typedef Mat_<Vec3i> Mat3i;
+typedef Mat_<Vec4i> Mat4i;
+typedef Mat_<float> Mat1f;
+typedef Mat_<Vec2f> Mat2f;
+typedef Mat_<Vec3f> Mat3f;
+typedef Mat_<Vec4f> Mat4f;
-template<typename _Tp> inline void Mat::push_back(const _Tp& elem)
-{
- if( !data )
- {
- *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone();
- return;
- }
- CV_Assert(DataType<_Tp>::type == type() && cols == 1
- /* && dims == 2 (cols == 1 implies dims == 2) */);
- uchar* tmp = dataend + step[0];
- if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
- {
- *(_Tp*)(data + (size.p[0]++)*step.p[0]) = elem;
- dataend = tmp;
- }
- else
- push_back_(&elem);
-}
-
-template<typename _Tp> inline void Mat::push_back(const Mat_<_Tp>& m)
-{
- push_back((const Mat&)m);
-}
+typedef Mat_<double> Mat1d;
+typedef Mat_<Vec2d> Mat2d;
+typedef Mat_<Vec3d> Mat3d;
+typedef Mat_<Vec4d> Mat4d;
-inline Mat::MSize::MSize(int* _p) : p(_p) {}
-inline Size Mat::MSize::operator()() const
-{
- CV_DbgAssert(p[-1] <= 2);
- return Size(p[1], p[0]);
-}
-inline const int& Mat::MSize::operator[](int i) const { return p[i]; }
-inline int& Mat::MSize::operator[](int i) { return p[i]; }
-inline Mat::MSize::operator const int*() const { return p; }
-
-inline bool Mat::MSize::operator == (const MSize& sz) const
-{
- int d = p[-1], dsz = sz.p[-1];
- if( d != dsz )
- return false;
- if( d == 2 )
- return p[0] == sz.p[0] && p[1] == sz.p[1];
-
- for( int i = 0; i < d; i++ )
- if( p[i] != sz.p[i] )
- return false;
- return true;
-}
-
-inline bool Mat::MSize::operator != (const MSize& sz) const
-{
- return !(*this == sz);
-}
-
-inline Mat::MStep::MStep() { p = buf; p[0] = p[1] = 0; }
-inline Mat::MStep::MStep(size_t s) { p = buf; p[0] = s; p[1] = 0; }
-inline const size_t& Mat::MStep::operator[](int i) const { return p[i]; }
-inline size_t& Mat::MStep::operator[](int i) { return p[i]; }
-inline Mat::MStep::operator size_t() const
-{
- CV_DbgAssert( p == buf );
- return buf[0];
-}
-inline Mat::MStep& Mat::MStep::operator = (size_t s)
+class CV_EXPORTS UMat
{
- CV_DbgAssert( p == buf );
- buf[0] = s;
- return *this;
-}
+public:
+ //! default constructor
+ UMat(UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ //! constructs 2D matrix of the specified size and type
+ // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
+ UMat(int rows, int cols, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ UMat(Size size, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ //! constucts 2D matrix and fills it with the specified value _s.
+ UMat(int rows, int cols, int type, const Scalar& s, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ UMat(Size size, int type, const Scalar& s, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+
+ //! constructs n-dimensional matrix
+ UMat(int ndims, const int* sizes, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ UMat(int ndims, const int* sizes, int type, const Scalar& s, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+
+ //! copy constructor
+ UMat(const UMat& m);
+
+ //! creates a matrix header for a part of the bigger matrix
+ UMat(const UMat& m, const Range& rowRange, const Range& colRange=Range::all());
+ UMat(const UMat& m, const Rect& roi);
+ UMat(const UMat& m, const Range* ranges);
+ //! builds matrix from std::vector with or without copying the data
+ template<typename _Tp> explicit UMat(const std::vector<_Tp>& vec, bool copyData=false);
+ //! builds matrix from cv::Vec; the data is copied by default
+ template<typename _Tp, int n> explicit UMat(const Vec<_Tp, n>& vec, bool copyData=true);
+ //! builds matrix from cv::Matx; the data is copied by default
+ template<typename _Tp, int m, int n> explicit UMat(const Matx<_Tp, m, n>& mtx, bool copyData=true);
+ //! builds matrix from a 2D point
+ template<typename _Tp> explicit UMat(const Point_<_Tp>& pt, bool copyData=true);
+ //! builds matrix from a 3D point
+ template<typename _Tp> explicit UMat(const Point3_<_Tp>& pt, bool copyData=true);
+ //! builds matrix from comma initializer
+ template<typename _Tp> explicit UMat(const MatCommaInitializer_<_Tp>& commaInitializer);
+
+ //! destructor - calls release()
+ ~UMat();
+ //! assignment operators
+ UMat& operator = (const UMat& m);
+
+ Mat getMat(int flags) const;
+
+ //! returns a new matrix header for the specified row
+ UMat row(int y) const;
+ //! returns a new matrix header for the specified column
+ UMat col(int x) const;
+ //! ... for the specified row span
+ UMat rowRange(int startrow, int endrow) const;
+ UMat rowRange(const Range& r) const;
+ //! ... for the specified column span
+ UMat colRange(int startcol, int endcol) const;
+ UMat colRange(const Range& r) const;
+ //! ... for the specified diagonal
+ // (d=0 - the main diagonal,
+ // >0 - a diagonal from the lower half,
+ // <0 - a diagonal from the upper half)
+ UMat diag(int d=0) const;
+ //! constructs a square diagonal matrix which main diagonal is vector "d"
+ static UMat diag(const UMat& d);
+
+ //! returns deep copy of the matrix, i.e. the data is copied
+ UMat clone() const;
+ //! copies the matrix content to "m".
+ // It calls m.create(this->size(), this->type()).
+ void copyTo( OutputArray m ) const;
+ //! copies those matrix elements to "m" that are marked with non-zero mask elements.
+ void copyTo( OutputArray m, InputArray mask ) const;
+ //! converts matrix to another datatype with optional scalng. See cvConvertScale.
+ void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
+
+ void assignTo( UMat& m, int type=-1 ) const;
+
+ //! sets every matrix element to s
+ UMat& operator = (const Scalar& s);
+ //! sets some of the matrix elements to s, according to the mask
+ UMat& setTo(InputArray value, InputArray mask=noArray());
+ //! creates alternative matrix header for the same data, with different
+ // number of channels and/or different number of rows. see cvReshape.
+ UMat reshape(int cn, int rows=0) const;
+ UMat reshape(int cn, int newndims, const int* newsz) const;
+
+ //! matrix transposition by means of matrix expressions
+ UMat t() const;
+ //! matrix inversion by means of matrix expressions
+ UMat inv(int method=DECOMP_LU) const;
+ //! per-element matrix multiplication by means of matrix expressions
+ UMat mul(InputArray m, double scale=1) const;
+
+ //! computes dot-product
+ double dot(InputArray m) const;
+
+ //! Matlab-style matrix initialization
+ static UMat zeros(int rows, int cols, int type);
+ static UMat zeros(Size size, int type);
+ static UMat zeros(int ndims, const int* sz, int type);
+ static UMat ones(int rows, int cols, int type);
+ static UMat ones(Size size, int type);
+ static UMat ones(int ndims, const int* sz, int type);
+ static UMat eye(int rows, int cols, int type);
+ static UMat eye(Size size, int type);
+
+ //! allocates new matrix data unless the matrix already has specified size and type.
+ // previous data is unreferenced if needed.
+ void create(int rows, int cols, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ void create(Size size, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+ void create(int ndims, const int* sizes, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+
+ //! increases the reference counter; use with care to avoid memleaks
+ void addref();
+ //! decreases reference counter;
+ // deallocates the data when reference counter reaches 0.
+ void release();
+
+ //! deallocates the matrix data
+ void deallocate();
+ //! internal use function; properly re-allocates _size, _step arrays
+ void copySize(const UMat& m);
+
+ //! locates matrix header within a parent matrix. See below
+ void locateROI( Size& wholeSize, Point& ofs ) const;
+ //! moves/resizes the current matrix ROI inside the parent matrix.
+ UMat& adjustROI( int dtop, int dbottom, int dleft, int dright );
+ //! extracts a rectangular sub-matrix
+ // (this is a generalized form of row, rowRange etc.)
+ UMat operator()( Range rowRange, Range colRange ) const;
+ UMat operator()( const Rect& roi ) const;
+ UMat operator()( const Range* ranges ) const;
+
+ //! returns true iff the matrix data is continuous
+ // (i.e. when there are no gaps between successive rows).
+ // similar to CV_IS_MAT_CONT(cvmat->type)
+ bool isContinuous() const;
+
+ //! returns true if the matrix is a submatrix of another matrix
+ bool isSubmatrix() const;
+
+ //! returns element size in bytes,
+ // similar to CV_ELEM_SIZE(cvmat->type)
+ size_t elemSize() const;
+ //! returns the size of element channel in bytes.
+ size_t elemSize1() const;
+ //! returns element type, similar to CV_MAT_TYPE(cvmat->type)
+ int type() const;
+ //! returns element type, similar to CV_MAT_DEPTH(cvmat->type)
+ int depth() const;
+ //! returns element type, similar to CV_MAT_CN(cvmat->type)
+ int channels() const;
+ //! returns step/elemSize1()
+ size_t step1(int i=0) const;
+ //! returns true if matrix data is NULL
+ bool empty() const;
+ //! returns the total number of matrix elements
+ size_t total() const;
+
+ //! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise
+ int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const;
+
+ void* handle(int accessFlags) const;
+ void ndoffset(size_t* ofs) const;
+
+ enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };
+ enum { MAGIC_MASK = 0xFFFF0000, TYPE_MASK = 0x00000FFF, DEPTH_MASK = 7 };
+
+ /*! includes several bit-fields:
+ - the magic signature
+ - continuity flag
+ - depth
+ - number of channels
+ */
+ int flags;
+ //! the matrix dimensionality, >= 2
+ int dims;
+ //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
+ int rows, cols;
-static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0)
-{
- return cvarrToMat(arr, copyData, true, coiMode);
-}
+ //! custom allocator
+ MatAllocator* allocator;
+ UMatUsageFlags usageFlags; // usage flags for allocator
+ //! and the standard allocator
+ static MatAllocator* getStdAllocator();
-///////////////////////////////////////////// SVD //////////////////////////////////////////////////////
+ // black-box container of UMat data
+ UMatData* u;
-inline SVD::SVD() {}
-inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); }
-inline void SVD::solveZ( InputArray m, OutputArray _dst )
-{
- Mat mtx = m.getMat();
- SVD svd(mtx, (mtx.rows >= mtx.cols ? 0 : SVD::FULL_UV));
- _dst.create(svd.vt.cols, 1, svd.vt.type());
- Mat dst = _dst.getMat();
- svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
-}
-
-template<typename _Tp, int m, int n, int nm> inline void
- SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt )
-{
- assert( nm == MIN(m, n));
- Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false);
- SVD::compute(_a, _w, _u, _vt);
- CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]);
-}
-
-template<typename _Tp, int m, int n, int nm> inline void
-SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w )
-{
- assert( nm == MIN(m, n));
- Mat _a(a, false), _w(w, false);
- SVD::compute(_a, _w);
- CV_Assert(_w.data == (uchar*)&w.val[0]);
-}
-
-template<typename _Tp, int m, int n, int nm, int nb> inline void
-SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u,
- const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs,
- Matx<_Tp, n, nb>& dst )
-{
- assert( nm == MIN(m, n));
- Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false);
- SVD::backSubst(_w, _u, _vt, _rhs, _dst);
- CV_Assert(_dst.data == (uchar*)&dst.val[0]);
-}
+ // offset of the submatrix (or 0)
+ size_t offset;
-///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
+ MatSize size;
+ MatStep step;
-template<typename _Tp> inline Mat_<_Tp>::Mat_()
- : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; }
+protected:
+};
-template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols)
- : Mat(_rows, _cols, DataType<_Tp>::type) {}
-template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
- : Mat(_rows, _cols, DataType<_Tp>::type) { *this = value; }
+/////////////////////////// multi-dimensional sparse matrix //////////////////////////
+
+/*!
+ Sparse matrix class.
+
+ The class represents multi-dimensional sparse numerical arrays. Such a sparse array can store elements
+ of any type that cv::Mat is able to store. "Sparse" means that only non-zero elements
+ are stored (though, as a result of some operations on a sparse matrix, some of its stored elements
+ can actually become 0. It's user responsibility to detect such elements and delete them using cv::SparseMat::erase().
+ The non-zero elements are stored in a hash table that grows when it's filled enough,
+ so that the search time remains O(1) in average. Elements can be accessed using the following methods:
+
+ <ol>
+ <li>Query operations: cv::SparseMat::ptr() and the higher-level cv::SparseMat::ref(),
+ cv::SparseMat::value() and cv::SparseMat::find, for example:
+ \code
+ const int dims = 5;
+ int size[] = {10, 10, 10, 10, 10};
+ SparseMat sparse_mat(dims, size, CV_32F);
+ for(int i = 0; i < 1000; i++)
+ {
+ int idx[dims];
+ for(int k = 0; k < dims; k++)
+ idx[k] = rand()%sparse_mat.size(k);
+ sparse_mat.ref<float>(idx) += 1.f;
+ }
+ \endcode
+
+ <li>Sparse matrix iterators. Like cv::Mat iterators and unlike cv::Mat iterators, the sparse matrix iterators are STL-style,
+ that is, the iteration is done as following:
+ \code
+ // prints elements of a sparse floating-point matrix and the sum of elements.
+ SparseMatConstIterator_<float>
+ it = sparse_mat.begin<float>(),
+ it_end = sparse_mat.end<float>();
+ double s = 0;
+ int dims = sparse_mat.dims();
+ for(; it != it_end; ++it)
+ {
+ // print element indices and the element value
+ const Node* n = it.node();
+ printf("(")
+ for(int i = 0; i < dims; i++)
+ printf("%3d%c", n->idx[i], i < dims-1 ? ',' : ')');
+ printf(": %f\n", *it);
+ s += *it;
+ }
+ printf("Element sum is %g\n", s);
+ \endcode
+ If you run this loop, you will notice that elements are enumerated
+ in no any logical order (lexicographical etc.),
+ they come in the same order as they stored in the hash table, i.e. semi-randomly.
+
+ You may collect pointers to the nodes and sort them to get the proper ordering.
+ Note, however, that pointers to the nodes may become invalid when you add more
+ elements to the matrix; this is because of possible buffer reallocation.
+
+ <li>A combination of the above 2 methods when you need to process 2 or more sparse
+ matrices simultaneously, e.g. this is how you can compute unnormalized
+ cross-correlation of the 2 floating-point sparse matrices:
+ \code
+ double crossCorr(const SparseMat& a, const SparseMat& b)
+ {
+ const SparseMat *_a = &a, *_b = &b;
+ // if b contains less elements than a,
+ // it's faster to iterate through b
+ if(_a->nzcount() > _b->nzcount())
+ std::swap(_a, _b);
+ SparseMatConstIterator_<float> it = _a->begin<float>(),
+ it_end = _a->end<float>();
+ double ccorr = 0;
+ for(; it != it_end; ++it)
+ {
+ // take the next element from the first matrix
+ float avalue = *it;
+ const Node* anode = it.node();
+ // and try to find element with the same index in the second matrix.
+ // since the hash value depends only on the element index,
+ // we reuse hashvalue stored in the node
+ float bvalue = _b->value<float>(anode->idx,&anode->hashval);
+ ccorr += avalue*bvalue;
+ }
+ return ccorr;
+ }
+ \endcode
+ </ol>
+*/
+class CV_EXPORTS SparseMat
+{
+public:
+ typedef SparseMatIterator iterator;
+ typedef SparseMatConstIterator const_iterator;
-template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz)
- : Mat(_sz.height, _sz.width, DataType<_Tp>::type) {}
+ enum { MAGIC_VAL=0x42FD0000, MAX_DIM=32, HASH_SCALE=0x5bd1e995, HASH_BIT=0x80000000 };
-template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
- : Mat(_sz.height, _sz.width, DataType<_Tp>::type) { *this = value; }
+ //! the sparse matrix header
+ struct CV_EXPORTS Hdr
+ {
+ Hdr(int _dims, const int* _sizes, int _type);
+ void clear();
+ int refcount;
+ int dims;
+ int valueOffset;
+ size_t nodeSize;
+ size_t nodeCount;
+ size_t freeList;
+ std::vector<uchar> pool;
+ std::vector<size_t> hashtab;
+ int size[MAX_DIM];
+ };
+
+ //! sparse matrix node - element of a hash table
+ struct CV_EXPORTS Node
+ {
+ //! hash value
+ size_t hashval;
+ //! index of the next node in the same hash table entry
+ size_t next;
+ //! index of the matrix element
+ int idx[MAX_DIM];
+ };
+
+ //! default constructor
+ SparseMat();
+ //! creates matrix of the specified size and type
+ SparseMat(int dims, const int* _sizes, int _type);
+ //! copy constructor
+ SparseMat(const SparseMat& m);
+ //! converts dense 2d matrix to the sparse form
+ /*!
+ \param m the input matrix
+ */
+ explicit SparseMat(const Mat& m);
+ //! converts old-style sparse matrix to the new-style. All the data is copied
+ //SparseMat(const CvSparseMat* m);
+ //! the destructor
+ ~SparseMat();
+
+ //! assignment operator. This is O(1) operation, i.e. no data is copied
+ SparseMat& operator = (const SparseMat& m);
+ //! equivalent to the corresponding constructor
+ SparseMat& operator = (const Mat& m);
+
+ //! creates full copy of the matrix
+ SparseMat clone() const;
+
+ //! copies all the data to the destination matrix. All the previous content of m is erased
+ void copyTo( SparseMat& m ) const;
+ //! converts sparse matrix to dense matrix.
+ void copyTo( Mat& m ) const;
+ //! multiplies all the matrix elements by the specified scale factor alpha and converts the results to the specified data type
+ void convertTo( SparseMat& m, int rtype, double alpha=1 ) const;
+ //! converts sparse matrix to dense n-dim matrix with optional type conversion and scaling.
+ /*!
+ @param [out] m - output matrix; if it does not have a proper size or type before the operation,
+ it is reallocated
+ @param [in] rtype – desired output matrix type or, rather, the depth since the number of channels
+ are the same as the input has; if rtype is negative, the output matrix will have the
+ same type as the input.
+ @param [in] alpha – optional scale factor
+ @param [in] beta – optional delta added to the scaled values
+ */
+ void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const;
+
+ // not used now
+ void assignTo( SparseMat& m, int type=-1 ) const;
+
+ //! reallocates sparse matrix.
+ /*!
+ If the matrix already had the proper size and type,
+ it is simply cleared with clear(), otherwise,
+ the old matrix is released (using release()) and the new one is allocated.
+ */
+ void create(int dims, const int* _sizes, int _type);
+ //! sets all the sparse matrix elements to 0, which means clearing the hash table.
+ void clear();
+ //! manually increments the reference counter to the header.
+ void addref();
+ // decrements the header reference counter. When the counter reaches 0, the header and all the underlying data are deallocated.
+ void release();
+
+ //! converts sparse matrix to the old-style representation; all the elements are copied.
+ //operator CvSparseMat*() const;
+ //! returns the size of each element in bytes (not including the overhead - the space occupied by SparseMat::Node elements)
+ size_t elemSize() const;
+ //! returns elemSize()/channels()
+ size_t elemSize1() const;
+
+ //! returns type of sparse matrix elements
+ int type() const;
+ //! returns the depth of sparse matrix elements
+ int depth() const;
+ //! returns the number of channels
+ int channels() const;
+
+ //! returns the array of sizes, or NULL if the matrix is not allocated
+ const int* size() const;
+ //! returns the size of i-th matrix dimension (or 0)
+ int size(int i) const;
+ //! returns the matrix dimensionality
+ int dims() const;
+ //! returns the number of non-zero elements (=the number of hash table nodes)
+ size_t nzcount() const;
+
+ //! computes the element hash value (1D case)
+ size_t hash(int i0) const;
+ //! computes the element hash value (2D case)
+ size_t hash(int i0, int i1) const;
+ //! computes the element hash value (3D case)
+ size_t hash(int i0, int i1, int i2) const;
+ //! computes the element hash value (nD case)
+ size_t hash(const int* idx) const;
+
+ //@{
+ /*!
+ specialized variants for 1D, 2D, 3D cases and the generic_type one for n-D case.
+
+ return pointer to the matrix element.
+ <ul>
+ <li>if the element is there (it's non-zero), the pointer to it is returned
+ <li>if it's not there and createMissing=false, NULL pointer is returned
+ <li>if it's not there and createMissing=true, then the new element
+ is created and initialized with 0. Pointer to it is returned
+ <li>if the optional hashval pointer is not NULL, the element hash value is
+ not computed, but *hashval is taken instead.
+ </ul>
+ */
+ //! returns pointer to the specified element (1D case)
+ uchar* ptr(int i0, bool createMissing, size_t* hashval=0);
+ //! returns pointer to the specified element (2D case)
+ uchar* ptr(int i0, int i1, bool createMissing, size_t* hashval=0);
+ //! returns pointer to the specified element (3D case)
+ uchar* ptr(int i0, int i1, int i2, bool createMissing, size_t* hashval=0);
+ //! returns pointer to the specified element (nD case)
+ uchar* ptr(const int* idx, bool createMissing, size_t* hashval=0);
+ //@}
+
+ //@{
+ /*!
+ return read-write reference to the specified sparse matrix element.
+
+ ref<_Tp>(i0,...[,hashval]) is equivalent to *(_Tp*)ptr(i0,...,true[,hashval]).
+ The methods always return a valid reference.
+ If the element did not exist, it is created and initialiazed with 0.
+ */
+ //! returns reference to the specified element (1D case)
+ template<typename _Tp> _Tp& ref(int i0, size_t* hashval=0);
+ //! returns reference to the specified element (2D case)
+ template<typename _Tp> _Tp& ref(int i0, int i1, size_t* hashval=0);
+ //! returns reference to the specified element (3D case)
+ template<typename _Tp> _Tp& ref(int i0, int i1, int i2, size_t* hashval=0);
+ //! returns reference to the specified element (nD case)
+ template<typename _Tp> _Tp& ref(const int* idx, size_t* hashval=0);
+ //@}
+
+ //@{
+ /*!
+ return value of the specified sparse matrix element.
+
+ value<_Tp>(i0,...[,hashval]) is equivalent
+
+ \code
+ { const _Tp* p = find<_Tp>(i0,...[,hashval]); return p ? *p : _Tp(); }
+ \endcode
+
+ That is, if the element did not exist, the methods return 0.
+ */
+ //! returns value of the specified element (1D case)
+ template<typename _Tp> _Tp value(int i0, size_t* hashval=0) const;
+ //! returns value of the specified element (2D case)
+ template<typename _Tp> _Tp value(int i0, int i1, size_t* hashval=0) const;
+ //! returns value of the specified element (3D case)
+ template<typename _Tp> _Tp value(int i0, int i1, int i2, size_t* hashval=0) const;
+ //! returns value of the specified element (nD case)
+ template<typename _Tp> _Tp value(const int* idx, size_t* hashval=0) const;
+ //@}
+
+ //@{
+ /*!
+ Return pointer to the specified sparse matrix element if it exists
+
+ find<_Tp>(i0,...[,hashval]) is equivalent to (_const Tp*)ptr(i0,...false[,hashval]).
+
+ If the specified element does not exist, the methods return NULL.
+ */
+ //! returns pointer to the specified element (1D case)
+ template<typename _Tp> const _Tp* find(int i0, size_t* hashval=0) const;
+ //! returns pointer to the specified element (2D case)
+ template<typename _Tp> const _Tp* find(int i0, int i1, size_t* hashval=0) const;
+ //! returns pointer to the specified element (3D case)
+ template<typename _Tp> const _Tp* find(int i0, int i1, int i2, size_t* hashval=0) const;
+ //! returns pointer to the specified element (nD case)
+ template<typename _Tp> const _Tp* find(const int* idx, size_t* hashval=0) const;
+
+ //! erases the specified element (2D case)
+ void erase(int i0, int i1, size_t* hashval=0);
+ //! erases the specified element (3D case)
+ void erase(int i0, int i1, int i2, size_t* hashval=0);
+ //! erases the specified element (nD case)
+ void erase(const int* idx, size_t* hashval=0);
+
+ //@{
+ /*!
+ return the sparse matrix iterator pointing to the first sparse matrix element
+ */
+ //! returns the sparse matrix iterator at the matrix beginning
+ SparseMatIterator begin();
+ //! returns the sparse matrix iterator at the matrix beginning
+ template<typename _Tp> SparseMatIterator_<_Tp> begin();
+ //! returns the read-only sparse matrix iterator at the matrix beginning
+ SparseMatConstIterator begin() const;
+ //! returns the read-only sparse matrix iterator at the matrix beginning
+ template<typename _Tp> SparseMatConstIterator_<_Tp> begin() const;
+ //@}
+ /*!
+ return the sparse matrix iterator pointing to the element following the last sparse matrix element
+ */
+ //! returns the sparse matrix iterator at the matrix end
+ SparseMatIterator end();
+ //! returns the read-only sparse matrix iterator at the matrix end
+ SparseMatConstIterator end() const;
+ //! returns the typed sparse matrix iterator at the matrix end
+ template<typename _Tp> SparseMatIterator_<_Tp> end();
+ //! returns the typed read-only sparse matrix iterator at the matrix end
+ template<typename _Tp> SparseMatConstIterator_<_Tp> end() const;
+
+ //! returns the value stored in the sparse martix node
+ template<typename _Tp> _Tp& value(Node* n);
+ //! returns the value stored in the sparse martix node
+ template<typename _Tp> const _Tp& value(const Node* n) const;
+
+ ////////////// some internal-use methods ///////////////
+ Node* node(size_t nidx);
+ const Node* node(size_t nidx) const;
+
+ uchar* newNode(const int* idx, size_t hashval);
+ void removeNode(size_t hidx, size_t nidx, size_t previdx);
+ void resizeHashTab(size_t newsize);
-template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz)
- : Mat(_dims, _sz, DataType<_Tp>::type) {}
+ int flags;
+ Hdr* hdr;
+};
-template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s)
- : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s)) {}
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
- : Mat(m, ranges) {}
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat& m)
- : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; *this = m; }
+///////////////////////////////// SparseMat_<_Tp> ////////////////////////////////////
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m)
- : Mat(m) {}
+/*!
+ The Template Sparse Matrix class derived from cv::SparseMat
-template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
- : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps) {}
+ The class provides slightly more convenient operations for accessing elements.
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& _rowRange, const Range& _colRange)
- : Mat(m, _rowRange, _colRange) {}
+ \code
+ SparseMat m;
+ ...
+ SparseMat_<int> m_ = (SparseMat_<int>&)m;
+ m_.ref(1)++; // equivalent to m.ref<int>(1)++;
+ m_.ref(2) += m_(3); // equivalent to m.ref<int>(2) += m.value<int>(3);
+ \endcode
+*/
+template<typename _Tp> class SparseMat_ : public SparseMat
+{
+public:
+ typedef SparseMatIterator_<_Tp> iterator;
+ typedef SparseMatConstIterator_<_Tp> const_iterator;
+
+ //! the default constructor
+ SparseMat_();
+ //! the full constructor equivelent to SparseMat(dims, _sizes, DataType<_Tp>::type)
+ SparseMat_(int dims, const int* _sizes);
+ //! the copy constructor. If DataType<_Tp>.type != m.type(), the m elements are converted
+ SparseMat_(const SparseMat& m);
+ //! the copy constructor. This is O(1) operation - no data is copied
+ SparseMat_(const SparseMat_& m);
+ //! converts dense matrix to the sparse form
+ SparseMat_(const Mat& m);
+ //! converts the old-style sparse matrix to the C++ class. All the elements are copied
+ //SparseMat_(const CvSparseMat* m);
+ //! the assignment operator. If DataType<_Tp>.type != m.type(), the m elements are converted
+ SparseMat_& operator = (const SparseMat& m);
+ //! the assignment operator. This is O(1) operation - no data is copied
+ SparseMat_& operator = (const SparseMat_& m);
+ //! converts dense matrix to the sparse form
+ SparseMat_& operator = (const Mat& m);
+
+ //! makes full copy of the matrix. All the elements are duplicated
+ SparseMat_ clone() const;
+ //! equivalent to cv::SparseMat::create(dims, _sizes, DataType<_Tp>::type)
+ void create(int dims, const int* _sizes);
+ //! converts sparse matrix to the old-style CvSparseMat. All the elements are copied
+ //operator CvSparseMat*() const;
+
+ //! returns type of the matrix elements
+ int type() const;
+ //! returns depth of the matrix elements
+ int depth() const;
+ //! returns the number of channels in each matrix element
+ int channels() const;
+
+ //! equivalent to SparseMat::ref<_Tp>(i0, hashval)
+ _Tp& ref(int i0, size_t* hashval=0);
+ //! equivalent to SparseMat::ref<_Tp>(i0, i1, hashval)
+ _Tp& ref(int i0, int i1, size_t* hashval=0);
+ //! equivalent to SparseMat::ref<_Tp>(i0, i1, i2, hashval)
+ _Tp& ref(int i0, int i1, int i2, size_t* hashval=0);
+ //! equivalent to SparseMat::ref<_Tp>(idx, hashval)
+ _Tp& ref(const int* idx, size_t* hashval=0);
+
+ //! equivalent to SparseMat::value<_Tp>(i0, hashval)
+ _Tp operator()(int i0, size_t* hashval=0) const;
+ //! equivalent to SparseMat::value<_Tp>(i0, i1, hashval)
+ _Tp operator()(int i0, int i1, size_t* hashval=0) const;
+ //! equivalent to SparseMat::value<_Tp>(i0, i1, i2, hashval)
+ _Tp operator()(int i0, int i1, int i2, size_t* hashval=0) const;
+ //! equivalent to SparseMat::value<_Tp>(idx, hashval)
+ _Tp operator()(const int* idx, size_t* hashval=0) const;
+
+ //! returns sparse matrix iterator pointing to the first sparse matrix element
+ SparseMatIterator_<_Tp> begin();
+ //! returns read-only sparse matrix iterator pointing to the first sparse matrix element
+ SparseMatConstIterator_<_Tp> begin() const;
+ //! returns sparse matrix iterator pointing to the element following the last sparse matrix element
+ SparseMatIterator_<_Tp> end();
+ //! returns read-only sparse matrix iterator pointing to the element following the last sparse matrix element
+ SparseMatConstIterator_<_Tp> end() const;
+};
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
- : Mat(m, roi) {}
-template<typename _Tp> template<int n> inline
- Mat_<_Tp>::Mat_(const Vec<typename DataType<_Tp>::channel_type, n>& vec, bool copyData)
- : Mat(n/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec)
-{
- CV_Assert(n%DataType<_Tp>::channels == 0);
- if( copyData )
- *this = clone();
-}
-
-template<typename _Tp> template<int m, int n> inline
- Mat_<_Tp>::Mat_(const Matx<typename DataType<_Tp>::channel_type,m,n>& M, bool copyData)
- : Mat(m, n/DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M)
-{
- CV_Assert(n % DataType<_Tp>::channels == 0);
- if( copyData )
- *this = clone();
-}
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
- : Mat(2/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
-{
- CV_Assert(2 % DataType<_Tp>::channels == 0);
- if( copyData )
- *this = clone();
-}
+////////////////////////////////// MatConstIterator //////////////////////////////////
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData)
- : Mat(3/DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt)
+class CV_EXPORTS MatConstIterator
{
- CV_Assert(3 % DataType<_Tp>::channels == 0);
- if( copyData )
- *this = clone();
-}
+public:
+ typedef uchar* value_type;
+ typedef ptrdiff_t difference_type;
+ typedef const uchar** pointer;
+ typedef uchar* reference;
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
- : Mat(commaInitializer) {}
+#ifndef OPENCV_NOSTL
+ typedef std::random_access_iterator_tag iterator_category;
+#endif
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const vector<_Tp>& vec, bool copyData)
- : Mat(vec, copyData) {}
+ //! default constructor
+ MatConstIterator();
+ //! constructor that sets the iterator to the beginning of the matrix
+ MatConstIterator(const Mat* _m);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator(const Mat* _m, int _row, int _col=0);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator(const Mat* _m, Point _pt);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator(const Mat* _m, const int* _idx);
+ //! copy constructor
+ MatConstIterator(const MatConstIterator& it);
+
+ //! copy operator
+ MatConstIterator& operator = (const MatConstIterator& it);
+ //! returns the current matrix element
+ const uchar* operator *() const;
+ //! returns the i-th matrix element, relative to the current
+ const uchar* operator [](ptrdiff_t i) const;
+
+ //! shifts the iterator forward by the specified number of elements
+ MatConstIterator& operator += (ptrdiff_t ofs);
+ //! shifts the iterator backward by the specified number of elements
+ MatConstIterator& operator -= (ptrdiff_t ofs);
+ //! decrements the iterator
+ MatConstIterator& operator --();
+ //! decrements the iterator
+ MatConstIterator operator --(int);
+ //! increments the iterator
+ MatConstIterator& operator ++();
+ //! increments the iterator
+ MatConstIterator operator ++(int);
+ //! returns the current iterator position
+ Point pos() const;
+ //! returns the current iterator position
+ void pos(int* _idx) const;
+
+ ptrdiff_t lpos() const;
+ void seek(ptrdiff_t ofs, bool relative = false);
+ void seek(const int* _idx, bool relative = false);
+
+ const Mat* m;
+ size_t elemSize;
+ const uchar* ptr;
+ const uchar* sliceStart;
+ const uchar* sliceEnd;
+};
-template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
-{
- if( DataType<_Tp>::type == m.type() )
- {
- Mat::operator = (m);
- return *this;
- }
- if( DataType<_Tp>::depth == m.depth() )
- {
- return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
- }
- CV_DbgAssert(DataType<_Tp>::channels == m.channels());
- m.convertTo(*this, type());
- return *this;
-}
-
-template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
-{
- Mat::operator=(m);
- return *this;
-}
-template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
-{
- typedef typename DataType<_Tp>::vec_type VT;
- Mat::operator=(Scalar((const VT&)s));
- return *this;
-}
-template<typename _Tp> inline void Mat_<_Tp>::create(int _rows, int _cols)
-{
- Mat::create(_rows, _cols, DataType<_Tp>::type);
-}
+////////////////////////////////// MatConstIterator_ /////////////////////////////////
-template<typename _Tp> inline void Mat_<_Tp>::create(Size _sz)
+/*!
+ Matrix read-only iterator
+ */
+template<typename _Tp>
+class MatConstIterator_ : public MatConstIterator
{
- Mat::create(_sz, DataType<_Tp>::type);
-}
+public:
+ typedef _Tp value_type;
+ typedef ptrdiff_t difference_type;
+ typedef const _Tp* pointer;
+ typedef const _Tp& reference;
-template<typename _Tp> inline void Mat_<_Tp>::create(int _dims, const int* _sz)
-{
- Mat::create(_dims, _sz, DataType<_Tp>::type);
-}
+#ifndef OPENCV_NOSTL
+ typedef std::random_access_iterator_tag iterator_category;
+#endif
+ //! default constructor
+ MatConstIterator_();
+ //! constructor that sets the iterator to the beginning of the matrix
+ MatConstIterator_(const Mat_<_Tp>* _m);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col=0);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator_(const Mat_<_Tp>* _m, Point _pt);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatConstIterator_(const Mat_<_Tp>* _m, const int* _idx);
+ //! copy constructor
+ MatConstIterator_(const MatConstIterator_& it);
+
+ //! copy operator
+ MatConstIterator_& operator = (const MatConstIterator_& it);
+ //! returns the current matrix element
+ _Tp operator *() const;
+ //! returns the i-th matrix element, relative to the current
+ _Tp operator [](ptrdiff_t i) const;
+
+ //! shifts the iterator forward by the specified number of elements
+ MatConstIterator_& operator += (ptrdiff_t ofs);
+ //! shifts the iterator backward by the specified number of elements
+ MatConstIterator_& operator -= (ptrdiff_t ofs);
+ //! decrements the iterator
+ MatConstIterator_& operator --();
+ //! decrements the iterator
+ MatConstIterator_ operator --(int);
+ //! increments the iterator
+ MatConstIterator_& operator ++();
+ //! increments the iterator
+ MatConstIterator_ operator ++(int);
+ //! returns the current iterator position
+ Point pos() const;
+};
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
-{ return Mat_<_Tp>(Mat::cross(m)); }
-template<typename _Tp> template<typename T2> inline Mat_<_Tp>::operator Mat_<T2>() const
-{ return Mat_<T2>(*this); }
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::row(int y) const
-{ return Mat_(*this, Range(y, y+1), Range::all()); }
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::col(int x) const
-{ return Mat_(*this, Range::all(), Range(x, x+1)); }
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::diag(int d) const
-{ return Mat_(Mat::diag(d)); }
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::clone() const
-{ return Mat_(Mat::clone()); }
+//////////////////////////////////// MatIterator_ ////////////////////////////////////
-template<typename _Tp> inline size_t Mat_<_Tp>::elemSize() const
+/*!
+ Matrix read-write iterator
+*/
+template<typename _Tp>
+class MatIterator_ : public MatConstIterator_<_Tp>
{
- CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
- return sizeof(_Tp);
-}
+public:
+ typedef _Tp* pointer;
+ typedef _Tp& reference;
-template<typename _Tp> inline size_t Mat_<_Tp>::elemSize1() const
-{
- CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp)/DataType<_Tp>::channels );
- return sizeof(_Tp)/DataType<_Tp>::channels;
-}
-template<typename _Tp> inline int Mat_<_Tp>::type() const
-{
- CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
- return DataType<_Tp>::type;
-}
-template<typename _Tp> inline int Mat_<_Tp>::depth() const
-{
- CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
- return DataType<_Tp>::depth;
-}
-template<typename _Tp> inline int Mat_<_Tp>::channels() const
-{
- CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
- return DataType<_Tp>::channels;
-}
-template<typename _Tp> inline size_t Mat_<_Tp>::stepT(int i) const { return step.p[i]/elemSize(); }
-template<typename _Tp> inline size_t Mat_<_Tp>::step1(int i) const { return step.p[i]/elemSize1(); }
+#ifndef OPENCV_NOSTL
+ typedef std::random_access_iterator_tag iterator_category;
+#endif
-template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
-{ return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright)); }
+ //! the default constructor
+ MatIterator_();
+ //! constructor that sets the iterator to the beginning of the matrix
+ MatIterator_(Mat_<_Tp>* _m);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatIterator_(Mat_<_Tp>* _m, int _row, int _col=0);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatIterator_(Mat_<_Tp>* _m, Point _pt);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatIterator_(Mat_<_Tp>* _m, const int* _idx);
+ //! copy constructor
+ MatIterator_(const MatIterator_& it);
+ //! copy operator
+ MatIterator_& operator = (const MatIterator_<_Tp>& it );
+
+ //! returns the current matrix element
+ _Tp& operator *() const;
+ //! returns the i-th matrix element, relative to the current
+ _Tp& operator [](ptrdiff_t i) const;
+
+ //! shifts the iterator forward by the specified number of elements
+ MatIterator_& operator += (ptrdiff_t ofs);
+ //! shifts the iterator backward by the specified number of elements
+ MatIterator_& operator -= (ptrdiff_t ofs);
+ //! decrements the iterator
+ MatIterator_& operator --();
+ //! decrements the iterator
+ MatIterator_ operator --(int);
+ //! increments the iterator
+ MatIterator_& operator ++();
+ //! increments the iterator
+ MatIterator_ operator ++(int);
+};
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range& _rowRange, const Range& _colRange ) const
-{ return Mat_<_Tp>(*this, _rowRange, _colRange); }
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
-{ return Mat_<_Tp>(*this, roi); }
-template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
-{ return Mat_<_Tp>(*this, ranges); }
+/////////////////////////////// SparseMatConstIterator ///////////////////////////////
-template<typename _Tp> inline _Tp* Mat_<_Tp>::operator [](int y)
-{ return (_Tp*)ptr(y); }
-template<typename _Tp> inline const _Tp* Mat_<_Tp>::operator [](int y) const
-{ return (const _Tp*)ptr(y); }
+/*!
+ Read-Only Sparse Matrix Iterator.
+ Here is how to use the iterator to compute the sum of floating-point sparse matrix elements:
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1)
-{
- CV_DbgAssert( dims <= 2 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] &&
- type() == DataType<_Tp>::type );
- return ((_Tp*)(data + step.p[0]*i0))[i1];
-}
-
-template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const
-{
- CV_DbgAssert( dims <= 2 && data &&
- (unsigned)i0 < (unsigned)size.p[0] &&
- (unsigned)i1 < (unsigned)size.p[1] &&
- type() == DataType<_Tp>::type );
- return ((const _Tp*)(data + step.p[0]*i0))[i1];
-}
-
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(Point pt)
-{
- CV_DbgAssert( dims <= 2 && data &&
- (unsigned)pt.y < (unsigned)size.p[0] &&
- (unsigned)pt.x < (unsigned)size.p[1] &&
- type() == DataType<_Tp>::type );
- return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
-}
-
-template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(Point pt) const
-{
- CV_DbgAssert( dims <= 2 && data &&
- (unsigned)pt.y < (unsigned)size.p[0] &&
- (unsigned)pt.x < (unsigned)size.p[1] &&
- type() == DataType<_Tp>::type );
- return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
-}
-
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(const int* idx)
+ \code
+ SparseMatConstIterator it = m.begin(), it_end = m.end();
+ double s = 0;
+ CV_Assert( m.type() == CV_32F );
+ for( ; it != it_end; ++it )
+ s += it.value<float>();
+ \endcode
+*/
+class CV_EXPORTS SparseMatConstIterator
{
- return Mat::at<_Tp>(idx);
-}
+public:
+ //! the default constructor
+ SparseMatConstIterator();
+ //! the full constructor setting the iterator to the first sparse matrix element
+ SparseMatConstIterator(const SparseMat* _m);
+ //! the copy constructor
+ SparseMatConstIterator(const SparseMatConstIterator& it);
+
+ //! the assignment operator
+ SparseMatConstIterator& operator = (const SparseMatConstIterator& it);
+
+ //! template method returning the current matrix element
+ template<typename _Tp> const _Tp& value() const;
+ //! returns the current node of the sparse matrix. it.node->idx is the current element index
+ const SparseMat::Node* node() const;
+
+ //! moves iterator to the previous element
+ SparseMatConstIterator& operator --();
+ //! moves iterator to the previous element
+ SparseMatConstIterator operator --(int);
+ //! moves iterator to the next element
+ SparseMatConstIterator& operator ++();
+ //! moves iterator to the next element
+ SparseMatConstIterator operator ++(int);
+
+ //! moves iterator to the element after the last element
+ void seekEnd();
+
+ const SparseMat* m;
+ size_t hashidx;
+ uchar* ptr;
+};
-template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
-{
- return Mat::at<_Tp>(idx);
-}
-template<typename _Tp> template<int n> inline _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx)
-{
- return Mat::at<_Tp>(idx);
-}
-template<typename _Tp> template<int n> inline const _Tp& Mat_<_Tp>::operator ()(const Vec<int, n>& idx) const
-{
- return Mat::at<_Tp>(idx);
-}
+////////////////////////////////// SparseMatIterator /////////////////////////////////
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0)
-{
- return this->at<_Tp>(i0);
-}
+/*!
+ Read-write Sparse Matrix Iterator
-template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0) const
+ The class is similar to cv::SparseMatConstIterator,
+ but can be used for in-place modification of the matrix elements.
+*/
+class CV_EXPORTS SparseMatIterator : public SparseMatConstIterator
{
- return this->at<_Tp>(i0);
-}
+public:
+ //! the default constructor
+ SparseMatIterator();
+ //! the full constructor setting the iterator to the first sparse matrix element
+ SparseMatIterator(SparseMat* _m);
+ //! the full constructor setting the iterator to the specified sparse matrix element
+ SparseMatIterator(SparseMat* _m, const int* idx);
+ //! the copy constructor
+ SparseMatIterator(const SparseMatIterator& it);
+
+ //! the assignment operator
+ SparseMatIterator& operator = (const SparseMatIterator& it);
+ //! returns read-write reference to the current sparse matrix element
+ template<typename _Tp> _Tp& value() const;
+ //! returns pointer to the current sparse matrix node. it.node->idx is the index of the current element (do not modify it!)
+ SparseMat::Node* node() const;
+
+ //! moves iterator to the next element
+ SparseMatIterator& operator ++();
+ //! moves iterator to the next element
+ SparseMatIterator operator ++(int);
+};
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2)
-{
- return this->at<_Tp>(i0, i1, i2);
-}
-template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0, int i1, int i2) const
-{
- return this->at<_Tp>(i0, i1, i2);
-}
+/////////////////////////////// SparseMatConstIterator_ //////////////////////////////
-template<typename _Tp> inline Mat_<_Tp>::operator vector<_Tp>() const
-{
- vector<_Tp> v;
- copyTo(v);
- return v;
-}
+/*!
+ Template Read-Only Sparse Matrix Iterator Class.
-template<typename _Tp> template<int n> inline Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
+ This is the derived from SparseMatConstIterator class that
+ introduces more convenient operator *() for accessing the current element.
+*/
+template<typename _Tp> class SparseMatConstIterator_ : public SparseMatConstIterator
{
- CV_Assert(n % DataType<_Tp>::channels == 0);
- return this->Mat::operator Vec<typename DataType<_Tp>::channel_type, n>();
-}
+public:
-template<typename _Tp> template<int m, int n> inline Mat_<_Tp>::operator Matx<typename DataType<_Tp>::channel_type, m, n>() const
-{
- CV_Assert(n % DataType<_Tp>::channels == 0);
+#ifndef OPENCV_NOSTL
+ typedef std::forward_iterator_tag iterator_category;
+#endif
- Matx<typename DataType<_Tp>::channel_type, m, n> res = this->Mat::operator Matx<typename DataType<_Tp>::channel_type, m, n>();
- return res;
-}
+ //! the default constructor
+ SparseMatConstIterator_();
+ //! the full constructor setting the iterator to the first sparse matrix element
+ SparseMatConstIterator_(const SparseMat_<_Tp>* _m);
+ SparseMatConstIterator_(const SparseMat* _m);
+ //! the copy constructor
+ SparseMatConstIterator_(const SparseMatConstIterator_& it);
+
+ //! the assignment operator
+ SparseMatConstIterator_& operator = (const SparseMatConstIterator_& it);
+ //! the element access operator
+ const _Tp& operator *() const;
+
+ //! moves iterator to the next element
+ SparseMatConstIterator_& operator ++();
+ //! moves iterator to the next element
+ SparseMatConstIterator_ operator ++(int);
+};
-template<typename T1, typename T2, typename Op> inline void
-process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
-{
- int y, x, rows = m1.rows, cols = m1.cols;
- CV_DbgAssert( m1.size() == m2.size() );
- for( y = 0; y < rows; y++ )
- {
- const T1* src = m1[y];
- T2* dst = m2[y];
+///////////////////////////////// SparseMatIterator_ /////////////////////////////////
- for( x = 0; x < cols; x++ )
- dst[x] = op(src[x]);
- }
-}
+/*!
+ Template Read-Write Sparse Matrix Iterator Class.
-template<typename T1, typename T2, typename T3, typename Op> inline void
-process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
+ This is the derived from cv::SparseMatConstIterator_ class that
+ introduces more convenient operator *() for accessing the current element.
+*/
+template<typename _Tp> class SparseMatIterator_ : public SparseMatConstIterator_<_Tp>
{
- int y, x, rows = m1.rows, cols = m1.cols;
-
- CV_DbgAssert( m1.size() == m2.size() );
-
- for( y = 0; y < rows; y++ )
- {
- const T1* src1 = m1[y];
- const T2* src2 = m2[y];
- T3* dst = m3[y];
-
- for( x = 0; x < cols; x++ )
- dst[x] = op( src1[x], src2[x] );
- }
-}
-
-
-/////////////////////////////// Input/Output Arrays /////////////////////////////////
-
-template<typename _Tp> inline _InputArray::_InputArray(const vector<_Tp>& vec)
- : flags(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
-
-template<typename _Tp> inline _InputArray::_InputArray(const vector<vector<_Tp> >& vec)
- : flags(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type), obj((void*)&vec) {}
-
-template<typename _Tp> inline _InputArray::_InputArray(const vector<Mat_<_Tp> >& vec)
- : flags(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type), obj((void*)&vec) {}
+public:
-template<typename _Tp, int m, int n> inline _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
- : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)&mtx), sz(n, m) {}
+#ifndef OPENCV_NOSTL
+ typedef std::forward_iterator_tag iterator_category;
+#endif
-template<typename _Tp> inline _InputArray::_InputArray(const _Tp* vec, int n)
- : flags(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type), obj((void*)vec), sz(n, 1) {}
+ //! the default constructor
+ SparseMatIterator_();
+ //! the full constructor setting the iterator to the first sparse matrix element
+ SparseMatIterator_(SparseMat_<_Tp>* _m);
+ SparseMatIterator_(SparseMat* _m);
+ //! the copy constructor
+ SparseMatIterator_(const SparseMatIterator_& it);
+
+ //! the assignment operator
+ SparseMatIterator_& operator = (const SparseMatIterator_& it);
+ //! returns the reference to the current element
+ _Tp& operator *() const;
+
+ //! moves the iterator to the next element
+ SparseMatIterator_& operator ++();
+ //! moves the iterator to the next element
+ SparseMatIterator_ operator ++(int);
+};
-inline _InputArray::_InputArray(const Scalar& s)
- : flags(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F), obj((void*)&s), sz(1, 4) {}
-template<typename _Tp> inline _InputArray::_InputArray(const Mat_<_Tp>& m)
- : flags(FIXED_TYPE + MAT + DataType<_Tp>::type), obj((void*)&m) {}
-template<typename _Tp> inline _OutputArray::_OutputArray(vector<_Tp>& vec)
- : _InputArray(vec) {}
-template<typename _Tp> inline _OutputArray::_OutputArray(vector<vector<_Tp> >& vec)
- : _InputArray(vec) {}
-template<typename _Tp> inline _OutputArray::_OutputArray(vector<Mat_<_Tp> >& vec)
- : _InputArray(vec) {}
-template<typename _Tp> inline _OutputArray::_OutputArray(Mat_<_Tp>& m)
- : _InputArray(m) {}
-template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx)
- : _InputArray(mtx) {}
-template<typename _Tp> inline _OutputArray::_OutputArray(_Tp* vec, int n)
- : _InputArray(vec, n) {}
+/////////////////////////////////// NAryMatIterator //////////////////////////////////
+
+/*!
+ n-Dimensional Dense Matrix Iterator Class.
+
+ The class cv::NAryMatIterator is used for iterating over one or more n-dimensional dense arrays (cv::Mat's).
+
+ The iterator is completely different from cv::Mat_ and cv::SparseMat_ iterators.
+ It iterates through the slices (or planes), not the elements, where "slice" is a continuous part of the arrays.
+
+ Here is the example on how the iterator can be used to normalize 3D histogram:
+
+ \code
+ void normalizeColorHist(Mat& hist)
+ {
+ #if 1
+ // intialize iterator (the style is different from STL).
+ // after initialization the iterator will contain
+ // the number of slices or planes
+ // the iterator will go through
+ Mat* arrays[] = { &hist, 0 };
+ Mat planes[1];
+ NAryMatIterator it(arrays, planes);
+ double s = 0;
+ // iterate through the matrix. on each iteration
+ // it.planes[i] (of type Mat) will be set to the current plane of
+ // i-th n-dim matrix passed to the iterator constructor.
+ for(int p = 0; p < it.nplanes; p++, ++it)
+ s += sum(it.planes[0])[0];
+ it = NAryMatIterator(hist);
+ s = 1./s;
+ for(int p = 0; p < it.nplanes; p++, ++it)
+ it.planes[0] *= s;
+ #elif 1
+ // this is a shorter implementation of the above
+ // using built-in operations on Mat
+ double s = sum(hist)[0];
+ hist.convertTo(hist, hist.type(), 1./s, 0);
+ #else
+ // and this is even shorter one
+ // (assuming that the histogram elements are non-negative)
+ normalize(hist, hist, 1, 0, NORM_L1);
+ #endif
+ }
+ \endcode
+
+ You can iterate through several matrices simultaneously as long as they have the same geometry
+ (dimensionality and all the dimension sizes are the same), which is useful for binary
+ and n-ary operations on such matrices. Just pass those matrices to cv::MatNDIterator.
+ Then, during the iteration it.planes[0], it.planes[1], ... will
+ be the slices of the corresponding matrices
+*/
+class CV_EXPORTS NAryMatIterator
+{
+public:
+ //! the default constructor
+ NAryMatIterator();
+ //! the full constructor taking arbitrary number of n-dim matrices
+ NAryMatIterator(const Mat** arrays, uchar** ptrs, int narrays=-1);
+ //! the full constructor taking arbitrary number of n-dim matrices
+ NAryMatIterator(const Mat** arrays, Mat* planes, int narrays=-1);
+ //! the separate iterator initialization method
+ void init(const Mat** arrays, Mat* planes, uchar** ptrs, int narrays=-1);
+
+ //! proceeds to the next plane of every iterated matrix
+ NAryMatIterator& operator ++();
+ //! proceeds to the next plane of every iterated matrix (postfix increment operator)
+ NAryMatIterator operator ++(int);
+
+ //! the iterated arrays
+ const Mat** arrays;
+ //! the current planes
+ Mat* planes;
+ //! data pointers
+ uchar** ptrs;
+ //! the number of arrays
+ int narrays;
+ //! the number of hyper-planes that the iterator steps through
+ size_t nplanes;
+ //! the size of each segment (in elements)
+ size_t size;
+protected:
+ int iterdepth;
+ size_t idx;
+};
-template<typename _Tp> inline _OutputArray::_OutputArray(const vector<_Tp>& vec)
- : _InputArray(vec) {flags |= FIXED_SIZE;}
-template<typename _Tp> inline _OutputArray::_OutputArray(const vector<vector<_Tp> >& vec)
- : _InputArray(vec) {flags |= FIXED_SIZE;}
-template<typename _Tp> inline _OutputArray::_OutputArray(const vector<Mat_<_Tp> >& vec)
- : _InputArray(vec) {flags |= FIXED_SIZE;}
-template<typename _Tp> inline _OutputArray::_OutputArray(const Mat_<_Tp>& m)
- : _InputArray(m) {flags |= FIXED_SIZE;}
-template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx)
- : _InputArray(mtx) {}
-template<typename _Tp> inline _OutputArray::_OutputArray(const _Tp* vec, int n)
- : _InputArray(vec, n) {}
-//////////////////////////////////// Matrix Expressions /////////////////////////////////////////
+///////////////////////////////// Matrix Expressions /////////////////////////////////
class CV_EXPORTS MatOp
{
public:
- MatOp() {};
- virtual ~MatOp() {};
+ MatOp();
+ virtual ~MatOp();
virtual bool elementWise(const MatExpr& expr) const;
virtual void assign(const MatExpr& expr, Mat& m, int type=-1) const = 0;
class CV_EXPORTS MatExpr
{
public:
- MatExpr() : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s(Scalar()) {}
- MatExpr(const MatOp* _op, int _flags, const Mat& _a=Mat(), const Mat& _b=Mat(),
- const Mat& _c=Mat(), double _alpha=1, double _beta=1, const Scalar& _s=Scalar())
- : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s) {}
+ MatExpr();
explicit MatExpr(const Mat& m);
- operator Mat() const
- {
- Mat m;
- op->assign(*this, m);
- return m;
- }
- template<typename _Tp> operator Mat_<_Tp>() const
- {
- Mat_<_Tp> m;
- op->assign(*this, m, DataType<_Tp>::type);
- return m;
- }
+ MatExpr(const MatOp* _op, int _flags, const Mat& _a = Mat(), const Mat& _b = Mat(),
+ const Mat& _c = Mat(), double _alpha = 1, double _beta = 1, const Scalar& _s = Scalar());
+
+ operator Mat() const;
+ template<typename _Tp> operator Mat_<_Tp>() const;
+
+ Size size() const;
+ int type() const;
MatExpr row(int y) const;
MatExpr col(int x) const;
- MatExpr diag(int d=0) const;
+ MatExpr diag(int d = 0) const;
MatExpr operator()( const Range& rowRange, const Range& colRange ) const;
MatExpr operator()( const Rect& roi ) const;
- Mat cross(const Mat& m) const;
- double dot(const Mat& m) const;
-
MatExpr t() const;
MatExpr inv(int method = DECOMP_LU) const;
MatExpr mul(const MatExpr& e, double scale=1) const;
MatExpr mul(const Mat& m, double scale=1) const;
- Size size() const;
- int type() const;
+ Mat cross(const Mat& m) const;
+ double dot(const Mat& m) const;
const MatOp* op;
int flags;
CV_EXPORTS MatExpr operator > (const Mat& a, double s);
CV_EXPORTS MatExpr operator > (double s, const Mat& a);
-CV_EXPORTS MatExpr min(const Mat& a, const Mat& b);
-CV_EXPORTS MatExpr min(const Mat& a, double s);
-CV_EXPORTS MatExpr min(double s, const Mat& a);
-
-CV_EXPORTS MatExpr max(const Mat& a, const Mat& b);
-CV_EXPORTS MatExpr max(const Mat& a, double s);
-CV_EXPORTS MatExpr max(double s, const Mat& a);
-
-template<typename _Tp> static inline MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
-{
- return cv::min((const Mat&)a, (const Mat&)b);
-}
-
-template<typename _Tp> static inline MatExpr min(const Mat_<_Tp>& a, double s)
-{
- return cv::min((const Mat&)a, s);
-}
-
-template<typename _Tp> static inline MatExpr min(double s, const Mat_<_Tp>& a)
-{
- return cv::min((const Mat&)a, s);
-}
-
-template<typename _Tp> static inline MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
-{
- return cv::max((const Mat&)a, (const Mat&)b);
-}
-
-template<typename _Tp> static inline MatExpr max(const Mat_<_Tp>& a, double s)
-{
- return cv::max((const Mat&)a, s);
-}
-
-template<typename _Tp> static inline MatExpr max(double s, const Mat_<_Tp>& a)
-{
- return cv::max((const Mat&)a, s);
-}
-
-template<typename _Tp> static inline void min(const Mat_<_Tp>& a, const Mat_<_Tp>& b, Mat_<_Tp>& c)
-{
- cv::min((const Mat&)a, (const Mat&)b, (Mat&)c);
-}
-
-template<typename _Tp> static inline void min(const Mat_<_Tp>& a, double s, Mat_<_Tp>& c)
-{
- cv::min((const Mat&)a, s, (Mat&)c);
-}
-
-template<typename _Tp> static inline void min(double s, const Mat_<_Tp>& a, Mat_<_Tp>& c)
-{
- cv::min((const Mat&)a, s, (Mat&)c);
-}
-
-template<typename _Tp> static inline void max(const Mat_<_Tp>& a, const Mat_<_Tp>& b, Mat_<_Tp>& c)
-{
- cv::max((const Mat&)a, (const Mat&)b, (Mat&)c);
-}
-
-template<typename _Tp> static inline void max(const Mat_<_Tp>& a, double s, Mat_<_Tp>& c)
-{
- cv::max((const Mat&)a, s, (Mat&)c);
-}
-
-template<typename _Tp> static inline void max(double s, const Mat_<_Tp>& a, Mat_<_Tp>& c)
-{
- cv::max((const Mat&)a, s, (Mat&)c);
-}
-
-
CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator & (const Mat& a, const Scalar& s);
CV_EXPORTS MatExpr operator & (const Scalar& s, const Mat& a);
CV_EXPORTS MatExpr operator ~(const Mat& m);
-CV_EXPORTS MatExpr abs(const Mat& m);
-CV_EXPORTS MatExpr abs(const MatExpr& e);
-
-template<typename _Tp> static inline MatExpr abs(const Mat_<_Tp>& m)
-{
- return cv::abs((const Mat&)m);
-}
-
-////////////////////////////// Augmenting algebraic operations //////////////////////////////////
-
-inline Mat& Mat::operator = (const MatExpr& e)
-{
- e.op->assign(e, *this);
- return *this;
-}
-
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatExpr& e)
-{
- e.op->assign(e, *this, DataType<_Tp>::type);
-}
-
-template<typename _Tp> Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e)
-{
- e.op->assign(e, *this, DataType<_Tp>::type);
- return *this;
-}
-
-static inline Mat& operator += (const Mat& a, const Mat& b)
-{
- add(a, b, (Mat&)a);
- return (Mat&)a;
-}
+CV_EXPORTS MatExpr min(const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr min(const Mat& a, double s);
+CV_EXPORTS MatExpr min(double s, const Mat& a);
-static inline Mat& operator += (const Mat& a, const Scalar& s)
-{
- add(a, s, (Mat&)a);
- return (Mat&)a;
-}
+CV_EXPORTS MatExpr max(const Mat& a, const Mat& b);
+CV_EXPORTS MatExpr max(const Mat& a, double s);
+CV_EXPORTS MatExpr max(double s, const Mat& a);
-template<typename _Tp> static inline
-Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
-{
- add(a, b, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
+CV_EXPORTS MatExpr abs(const Mat& m);
+CV_EXPORTS MatExpr abs(const MatExpr& e);
-template<typename _Tp> static inline
-Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Scalar& s)
-{
- add(a, s, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
+} // cv
-static inline Mat& operator += (const Mat& a, const MatExpr& b)
-{
- b.op->augAssignAdd(b, (Mat&)a);
- return (Mat&)a;
-}
+#include "opencv2/core/mat.inl.hpp"
-template<typename _Tp> static inline
-Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b)
-{
- b.op->augAssignAdd(b, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-static inline Mat& operator -= (const Mat& a, const Mat& b)
-{
- subtract(a, b, (Mat&)a);
- return (Mat&)a;
-}
-
-static inline Mat& operator -= (const Mat& a, const Scalar& s)
-{
- subtract(a, s, (Mat&)a);
- return (Mat&)a;
-}
-
-template<typename _Tp> static inline
-Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
-{
- subtract(a, b, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-template<typename _Tp> static inline
-Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Scalar& s)
-{
- subtract(a, s, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-static inline Mat& operator -= (const Mat& a, const MatExpr& b)
-{
- b.op->augAssignSubtract(b, (Mat&)a);
- return (Mat&)a;
-}
-
-template<typename _Tp> static inline
-Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b)
-{
- b.op->augAssignSubtract(b, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-static inline Mat& operator *= (const Mat& a, const Mat& b)
-{
- gemm(a, b, 1, Mat(), 0, (Mat&)a, 0);
- return (Mat&)a;
-}
-
-static inline Mat& operator *= (const Mat& a, double s)
-{
- a.convertTo((Mat&)a, -1, s);
- return (Mat&)a;
-}
-
-template<typename _Tp> static inline
-Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
-{
- gemm(a, b, 1, Mat(), 0, (Mat&)a, 0);
- return (Mat_<_Tp>&)a;
-}
-
-template<typename _Tp> static inline
-Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, double s)
-{
- a.convertTo((Mat&)a, -1, s);
- return (Mat_<_Tp>&)a;
-}
-
-static inline Mat& operator *= (const Mat& a, const MatExpr& b)
-{
- b.op->augAssignMultiply(b, (Mat&)a);
- return (Mat&)a;
-}
-
-template<typename _Tp> static inline
-Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b)
-{
- b.op->augAssignMultiply(b, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-static inline Mat& operator /= (const Mat& a, const Mat& b)
-{
- divide(a, b, (Mat&)a);
- return (Mat&)a;
-}
-
-static inline Mat& operator /= (const Mat& a, double s)
-{
- a.convertTo((Mat&)a, -1, 1./s);
- return (Mat&)a;
-}
-
-template<typename _Tp> static inline
-Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
-{
- divide(a, b, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-template<typename _Tp> static inline
-Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, double s)
-{
- a.convertTo((Mat&)a, -1, 1./s);
- return (Mat_<_Tp>&)a;
-}
-
-static inline Mat& operator /= (const Mat& a, const MatExpr& b)
-{
- b.op->augAssignDivide(b, (Mat&)a);
- return (Mat&)a;
-}
-
-template<typename _Tp> static inline
-Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b)
-{
- b.op->augAssignDivide(b, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-////////////////////////////// Logical operations ///////////////////////////////
-
-static inline Mat& operator &= (const Mat& a, const Mat& b)
-{
- bitwise_and(a, b, (Mat&)a);
- return (Mat&)a;
-}
-
-static inline Mat& operator &= (const Mat& a, const Scalar& s)
-{
- bitwise_and(a, s, (Mat&)a);
- return (Mat&)a;
-}
-
-template<typename _Tp> static inline Mat_<_Tp>&
-operator &= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
-{
- bitwise_and(a, b, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-template<typename _Tp> static inline Mat_<_Tp>&
-operator &= (const Mat_<_Tp>& a, const Scalar& s)
-{
- bitwise_and(a, s, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-static inline Mat& operator |= (const Mat& a, const Mat& b)
-{
- bitwise_or(a, b, (Mat&)a);
- return (Mat&)a;
-}
-
-static inline Mat& operator |= (const Mat& a, const Scalar& s)
-{
- bitwise_or(a, s, (Mat&)a);
- return (Mat&)a;
-}
-
-template<typename _Tp> static inline Mat_<_Tp>&
-operator |= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
-{
- bitwise_or(a, b, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-template<typename _Tp> static inline Mat_<_Tp>&
-operator |= (const Mat_<_Tp>& a, const Scalar& s)
-{
- bitwise_or(a, s, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-static inline Mat& operator ^= (const Mat& a, const Mat& b)
-{
- bitwise_xor(a, b, (Mat&)a);
- return (Mat&)a;
-}
-
-static inline Mat& operator ^= (const Mat& a, const Scalar& s)
-{
- bitwise_xor(a, s, (Mat&)a);
- return (Mat&)a;
-}
-
-template<typename _Tp> static inline Mat_<_Tp>&
-operator ^= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
-{
- bitwise_xor(a, b, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-template<typename _Tp> static inline Mat_<_Tp>&
-operator ^= (const Mat_<_Tp>& a, const Scalar& s)
-{
- bitwise_xor(a, s, (Mat&)a);
- return (Mat_<_Tp>&)a;
-}
-
-/////////////////////////////// Miscellaneous operations //////////////////////////////
-
-template<typename _Tp> void split(const Mat& src, vector<Mat_<_Tp> >& mv)
-{ split(src, (vector<Mat>&)mv ); }
-
-//////////////////////////////////////////////////////////////
-
-template<typename _Tp> inline MatExpr Mat_<_Tp>::zeros(int rows, int cols)
-{
- return Mat::zeros(rows, cols, DataType<_Tp>::type);
-}
-
-template<typename _Tp> inline MatExpr Mat_<_Tp>::zeros(Size sz)
-{
- return Mat::zeros(sz, DataType<_Tp>::type);
-}
-
-template<typename _Tp> inline MatExpr Mat_<_Tp>::ones(int rows, int cols)
-{
- return Mat::ones(rows, cols, DataType<_Tp>::type);
-}
-
-template<typename _Tp> inline MatExpr Mat_<_Tp>::ones(Size sz)
-{
- return Mat::ones(sz, DataType<_Tp>::type);
-}
-
-template<typename _Tp> inline MatExpr Mat_<_Tp>::eye(int rows, int cols)
-{
- return Mat::eye(rows, cols, DataType<_Tp>::type);
-}
-
-template<typename _Tp> inline MatExpr Mat_<_Tp>::eye(Size sz)
-{
- return Mat::eye(sz, DataType<_Tp>::type);
-}
-
-//////////////////////////////// Iterators & Comma initializers //////////////////////////////////
-
-inline MatConstIterator::MatConstIterator()
- : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0) {}
-
-inline MatConstIterator::MatConstIterator(const Mat* _m)
- : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
-{
- if( m && m->isContinuous() )
- {
- sliceStart = m->data;
- sliceEnd = sliceStart + m->total()*elemSize;
- }
- seek((const int*)0);
-}
-
-inline MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col)
- : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
-{
- CV_Assert(m && m->dims <= 2);
- if( m->isContinuous() )
- {
- sliceStart = m->data;
- sliceEnd = sliceStart + m->total()*elemSize;
- }
- int idx[]={_row, _col};
- seek(idx);
-}
-
-inline MatConstIterator::MatConstIterator(const Mat* _m, Point _pt)
- : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
-{
- CV_Assert(m && m->dims <= 2);
- if( m->isContinuous() )
- {
- sliceStart = m->data;
- sliceEnd = sliceStart + m->total()*elemSize;
- }
- int idx[]={_pt.y, _pt.x};
- seek(idx);
-}
-
-inline MatConstIterator::MatConstIterator(const MatConstIterator& it)
- : m(it.m), elemSize(it.elemSize), ptr(it.ptr), sliceStart(it.sliceStart), sliceEnd(it.sliceEnd)
-{}
-
-inline MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it )
-{
- m = it.m; elemSize = it.elemSize; ptr = it.ptr;
- sliceStart = it.sliceStart; sliceEnd = it.sliceEnd;
- return *this;
-}
-
-inline uchar* MatConstIterator::operator *() const { return ptr; }
-
-inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs)
-{
- if( !m || ofs == 0 )
- return *this;
- ptrdiff_t ofsb = ofs*elemSize;
- ptr += ofsb;
- if( ptr < sliceStart || sliceEnd <= ptr )
- {
- ptr -= ofsb;
- seek(ofs, true);
- }
- return *this;
-}
-
-inline MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs)
-{ return (*this += -ofs); }
-
-inline MatConstIterator& MatConstIterator::operator --()
-{
- if( m && (ptr -= elemSize) < sliceStart )
- {
- ptr += elemSize;
- seek(-1, true);
- }
- return *this;
-}
-
-inline MatConstIterator MatConstIterator::operator --(int)
-{
- MatConstIterator b = *this;
- *this += -1;
- return b;
-}
-
-inline MatConstIterator& MatConstIterator::operator ++()
-{
- if( m && (ptr += elemSize) >= sliceEnd )
- {
- ptr -= elemSize;
- seek(1, true);
- }
- return *this;
-}
-
-inline MatConstIterator MatConstIterator::operator ++(int)
-{
- MatConstIterator b = *this;
- *this += 1;
- return b;
-}
-
-template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_() {}
-
-template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m)
- : MatConstIterator(_m) {}
-
-template<typename _Tp> inline MatConstIterator_<_Tp>::
- MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col)
- : MatConstIterator(_m, _row, _col) {}
-
-template<typename _Tp> inline MatConstIterator_<_Tp>::
- MatConstIterator_(const Mat_<_Tp>* _m, Point _pt)
- : MatConstIterator(_m, _pt) {}
-
-template<typename _Tp> inline MatConstIterator_<_Tp>::
- MatConstIterator_(const MatConstIterator_& it)
- : MatConstIterator(it) {}
-
-template<typename _Tp> inline MatConstIterator_<_Tp>&
- MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
-{
- MatConstIterator::operator = (it);
- return *this;
-}
-
-template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator *() const { return *(_Tp*)(this->ptr); }
-
-template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs)
-{
- MatConstIterator::operator += (ofs);
- return *this;
-}
-
-template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (ptrdiff_t ofs)
-{ return (*this += -ofs); }
-
-template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
-{
- MatConstIterator::operator --();
- return *this;
-}
-
-template<typename _Tp> inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int)
-{
- MatConstIterator_ b = *this;
- MatConstIterator::operator --();
- return b;
-}
-
-template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
-{
- MatConstIterator::operator ++();
- return *this;
-}
-
-template<typename _Tp> inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int)
-{
- MatConstIterator_ b = *this;
- MatConstIterator::operator ++();
- return b;
-}
-
-template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_() : MatConstIterator_<_Tp>() {}
-
-template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
- : MatConstIterator_<_Tp>(_m) {}
-
-template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
- : MatConstIterator_<_Tp>(_m, _row, _col) {}
-
-template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, Point _pt)
- : MatConstIterator_<_Tp>(_m, _pt) {}
-
-template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, const int* _idx)
- : MatConstIterator_<_Tp>(_m, _idx) {}
-
-template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
- : MatConstIterator_<_Tp>(it) {}
-
-template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
-{
- MatConstIterator::operator = (it);
- return *this;
-}
-
-template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator *() const { return *(_Tp*)(this->ptr); }
-
-template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (ptrdiff_t ofs)
-{
- MatConstIterator::operator += (ofs);
- return *this;
-}
-
-template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (ptrdiff_t ofs)
-{
- MatConstIterator::operator += (-ofs);
- return *this;
-}
-
-template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
-{
- MatConstIterator::operator --();
- return *this;
-}
-
-template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
-{
- MatIterator_ b = *this;
- MatConstIterator::operator --();
- return b;
-}
-
-template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
-{
- MatConstIterator::operator ++();
- return *this;
-}
-
-template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
-{
- MatIterator_ b = *this;
- MatConstIterator::operator ++();
- return b;
-}
-
-template<typename _Tp> inline Point MatConstIterator_<_Tp>::pos() const
-{
- if( !m )
- return Point();
- CV_DbgAssert( m->dims <= 2 );
- if( m->isContinuous() )
- {
- ptrdiff_t ofs = (const _Tp*)ptr - (const _Tp*)m->data;
- int y = (int)(ofs / m->cols), x = (int)(ofs - (ptrdiff_t)y*m->cols);
- return Point(x, y);
- }
- else
- {
- ptrdiff_t ofs = (uchar*)ptr - m->data;
- int y = (int)(ofs / m->step), x = (int)((ofs - y*m->step)/sizeof(_Tp));
- return Point(x, y);
- }
-}
-
-static inline bool
-operator == (const MatConstIterator& a, const MatConstIterator& b)
-{ return a.m == b.m && a.ptr == b.ptr; }
-
-template<typename _Tp> static inline bool
-operator != (const MatConstIterator& a, const MatConstIterator& b)
-{ return !(a == b); }
-
-template<typename _Tp> static inline bool
-operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
-{ return a.m == b.m && a.ptr == b.ptr; }
-
-template<typename _Tp> static inline bool
-operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
-{ return a.m != b.m || a.ptr != b.ptr; }
-
-template<typename _Tp> static inline bool
-operator == (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
-{ return a.m == b.m && a.ptr == b.ptr; }
-
-template<typename _Tp> static inline bool
-operator != (const MatIterator_<_Tp>& a, const MatIterator_<_Tp>& b)
-{ return a.m != b.m || a.ptr != b.ptr; }
-
-static inline bool
-operator < (const MatConstIterator& a, const MatConstIterator& b)
-{ return a.ptr < b.ptr; }
-
-static inline bool
-operator > (const MatConstIterator& a, const MatConstIterator& b)
-{ return a.ptr > b.ptr; }
-
-static inline bool
-operator <= (const MatConstIterator& a, const MatConstIterator& b)
-{ return a.ptr <= b.ptr; }
-
-static inline bool
-operator >= (const MatConstIterator& a, const MatConstIterator& b)
-{ return a.ptr >= b.ptr; }
-
-CV_EXPORTS ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a);
-
-static inline MatConstIterator operator + (const MatConstIterator& a, ptrdiff_t ofs)
-{ MatConstIterator b = a; return b += ofs; }
-
-static inline MatConstIterator operator + (ptrdiff_t ofs, const MatConstIterator& a)
-{ MatConstIterator b = a; return b += ofs; }
-
-static inline MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
-{ MatConstIterator b = a; return b += -ofs; }
-
-template<typename _Tp> static inline MatConstIterator_<_Tp>
-operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
-{ MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatConstIterator_<_Tp>&)t; }
-
-template<typename _Tp> static inline MatConstIterator_<_Tp>
-operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a)
-{ MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatConstIterator_<_Tp>&)t; }
-
-template<typename _Tp> static inline MatConstIterator_<_Tp>
-operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
-{ MatConstIterator t = (const MatConstIterator&)a - ofs; return (MatConstIterator_<_Tp>&)t; }
-
-inline uchar* MatConstIterator::operator [](ptrdiff_t i) const
-{ return *(*this + i); }
-
-template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator [](ptrdiff_t i) const
-{ return *(_Tp*)MatConstIterator::operator [](i); }
-
-template<typename _Tp> static inline MatIterator_<_Tp>
-operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
-{ MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatIterator_<_Tp>&)t; }
-
-template<typename _Tp> static inline MatIterator_<_Tp>
-operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a)
-{ MatConstIterator t = (const MatConstIterator&)a + ofs; return (MatIterator_<_Tp>&)t; }
-
-template<typename _Tp> static inline MatIterator_<_Tp>
-operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
-{ MatConstIterator t = (const MatConstIterator&)a - ofs; return (MatIterator_<_Tp>&)t; }
-
-template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator [](ptrdiff_t i) const
-{ return *(*this + i); }
-
-template<typename _Tp> inline MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
-{ return Mat::begin<_Tp>(); }
-
-template<typename _Tp> inline MatConstIterator_<_Tp> Mat_<_Tp>::end() const
-{ return Mat::end<_Tp>(); }
-
-template<typename _Tp> inline MatIterator_<_Tp> Mat_<_Tp>::begin()
-{ return Mat::begin<_Tp>(); }
-
-template<typename _Tp> inline MatIterator_<_Tp> Mat_<_Tp>::end()
-{ return Mat::end<_Tp>(); }
-
-template<typename _Tp> inline MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m) : it(_m) {}
-
-template<typename _Tp> template<typename T2> inline MatCommaInitializer_<_Tp>&
-MatCommaInitializer_<_Tp>::operator , (T2 v)
-{
- CV_DbgAssert( this->it < ((const Mat_<_Tp>*)this->it.m)->end() );
- *this->it = _Tp(v); ++this->it;
- return *this;
-}
-
-template<typename _Tp> inline Mat_<_Tp> MatCommaInitializer_<_Tp>::operator *() const
-{
- CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
- return Mat_<_Tp>(*this->it.m);
-}
-
-template<typename _Tp> inline MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
-{
- CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
- return Mat_<_Tp>(*this->it.m);
-}
-
-template<typename _Tp, typename T2> static inline MatCommaInitializer_<_Tp>
-operator << (const Mat_<_Tp>& m, T2 val)
-{
- MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
- return (commaInitializer, val);
-}
-
-//////////////////////////////// SparseMat ////////////////////////////////
-
-inline SparseMat::SparseMat()
-: flags(MAGIC_VAL), hdr(0)
-{
-}
-
-inline SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
-: flags(MAGIC_VAL), hdr(0)
-{
- create(_dims, _sizes, _type);
-}
-
-inline SparseMat::SparseMat(const SparseMat& m)
-: flags(m.flags), hdr(m.hdr)
-{
- addref();
-}
-
-inline SparseMat::~SparseMat()
-{
- release();
-}
-
-inline SparseMat& SparseMat::operator = (const SparseMat& m)
-{
- if( this != &m )
- {
- if( m.hdr )
- CV_XADD(&m.hdr->refcount, 1);
- release();
- flags = m.flags;
- hdr = m.hdr;
- }
- return *this;
-}
-
-inline SparseMat& SparseMat::operator = (const Mat& m)
-{ return (*this = SparseMat(m)); }
-
-inline SparseMat SparseMat::clone() const
-{
- SparseMat temp;
- this->copyTo(temp);
- return temp;
-}
-
-
-inline void SparseMat::assignTo( SparseMat& m, int _type ) const
-{
- if( _type < 0 )
- m = *this;
- else
- convertTo(m, _type);
-}
-
-inline void SparseMat::addref()
-{ if( hdr ) CV_XADD(&hdr->refcount, 1); }
-
-inline void SparseMat::release()
-{
- if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
- delete hdr;
- hdr = 0;
-}
-
-inline size_t SparseMat::elemSize() const
-{ return CV_ELEM_SIZE(flags); }
-
-inline size_t SparseMat::elemSize1() const
-{ return CV_ELEM_SIZE1(flags); }
-
-inline int SparseMat::type() const
-{ return CV_MAT_TYPE(flags); }
-
-inline int SparseMat::depth() const
-{ return CV_MAT_DEPTH(flags); }
-
-inline int SparseMat::channels() const
-{ return CV_MAT_CN(flags); }
-
-inline const int* SparseMat::size() const
-{
- return hdr ? hdr->size : 0;
-}
-
-inline int SparseMat::size(int i) const
-{
- if( hdr )
- {
- CV_DbgAssert((unsigned)i < (unsigned)hdr->dims);
- return hdr->size[i];
- }
- return 0;
-}
-
-inline int SparseMat::dims() const
-{
- return hdr ? hdr->dims : 0;
-}
-
-inline size_t SparseMat::nzcount() const
-{
- return hdr ? hdr->nodeCount : 0;
-}
-
-inline size_t SparseMat::hash(int i0) const
-{
- return (size_t)i0;
-}
-
-inline size_t SparseMat::hash(int i0, int i1) const
-{
- return (size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1;
-}
-
-inline size_t SparseMat::hash(int i0, int i1, int i2) const
-{
- return ((size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1)*HASH_SCALE + (unsigned)i2;
-}
-
-inline size_t SparseMat::hash(const int* idx) const
-{
- size_t h = (unsigned)idx[0];
- if( !hdr )
- return 0;
- int i, d = hdr->dims;
- for( i = 1; i < d; i++ )
- h = h*HASH_SCALE + (unsigned)idx[i];
- return h;
-}
-
-template<typename _Tp> inline _Tp& SparseMat::ref(int i0, size_t* hashval)
-{ return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval); }
-
-template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
-{ return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval); }
-
-template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval)
-{ return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval); }
-
-template<typename _Tp> inline _Tp& SparseMat::ref(const int* idx, size_t* hashval)
-{ return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval); }
-
-template<typename _Tp> inline _Tp SparseMat::value(int i0, size_t* hashval) const
-{
- const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
- return p ? *p : _Tp();
-}
-
-template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, size_t* hashval) const
-{
- const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
- return p ? *p : _Tp();
-}
-
-template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const
-{
- const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
- return p ? *p : _Tp();
-}
-
-template<typename _Tp> inline _Tp SparseMat::value(const int* idx, size_t* hashval) const
-{
- const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
- return p ? *p : _Tp();
-}
-
-template<typename _Tp> inline const _Tp* SparseMat::find(int i0, size_t* hashval) const
-{ return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval); }
-
-template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
-{ return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval); }
-
-template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const
-{ return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval); }
-
-template<typename _Tp> inline const _Tp* SparseMat::find(const int* idx, size_t* hashval) const
-{ return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval); }
-
-template<typename _Tp> inline _Tp& SparseMat::value(Node* n)
-{ return *(_Tp*)((uchar*)n + hdr->valueOffset); }
-
-template<typename _Tp> inline const _Tp& SparseMat::value(const Node* n) const
-{ return *(const _Tp*)((const uchar*)n + hdr->valueOffset); }
-
-inline SparseMat::Node* SparseMat::node(size_t nidx)
-{ return (Node*)(void*)&hdr->pool[nidx]; }
-
-inline const SparseMat::Node* SparseMat::node(size_t nidx) const
-{ return (const Node*)(void*)&hdr->pool[nidx]; }
-
-inline SparseMatIterator SparseMat::begin()
-{ return SparseMatIterator(this); }
-
-inline SparseMatConstIterator SparseMat::begin() const
-{ return SparseMatConstIterator(this); }
-
-inline SparseMatIterator SparseMat::end()
-{ SparseMatIterator it(this); it.seekEnd(); return it; }
-
-inline SparseMatConstIterator SparseMat::end() const
-{ SparseMatConstIterator it(this); it.seekEnd(); return it; }
-
-template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::begin()
-{ return SparseMatIterator_<_Tp>(this); }
-
-template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::begin() const
-{ return SparseMatConstIterator_<_Tp>(this); }
-
-template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::end()
-{ SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
-
-template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::end() const
-{ SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
-
-
-inline SparseMatConstIterator::SparseMatConstIterator()
-: m(0), hashidx(0), ptr(0)
-{
-}
-
-inline SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it)
-: m(it.m), hashidx(it.hashidx), ptr(it.ptr)
-{
-}
-
-static inline bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
-{ return it1.m == it2.m && it1.ptr == it2.ptr; }
-
-static inline bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
-{ return !(it1 == it2); }
-
-
-inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it)
-{
- if( this != &it )
- {
- m = it.m;
- hashidx = it.hashidx;
- ptr = it.ptr;
- }
- return *this;
-}
-
-template<typename _Tp> inline const _Tp& SparseMatConstIterator::value() const
-{ return *(_Tp*)ptr; }
-
-inline const SparseMat::Node* SparseMatConstIterator::node() const
-{
- return ptr && m && m->hdr ?
- (const SparseMat::Node*)(void*)(ptr - m->hdr->valueOffset) : 0;
-}
-
-inline SparseMatConstIterator SparseMatConstIterator::operator ++(int)
-{
- SparseMatConstIterator it = *this;
- ++*this;
- return it;
-}
-
-
-inline void SparseMatConstIterator::seekEnd()
-{
- if( m && m->hdr )
- {
- hashidx = m->hdr->hashtab.size();
- ptr = 0;
- }
-}
-
-inline SparseMatIterator::SparseMatIterator()
-{}
-
-inline SparseMatIterator::SparseMatIterator(SparseMat* _m)
-: SparseMatConstIterator(_m)
-{}
-
-inline SparseMatIterator::SparseMatIterator(const SparseMatIterator& it)
-: SparseMatConstIterator(it)
-{
-}
-
-inline SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it)
-{
- (SparseMatConstIterator&)*this = it;
- return *this;
-}
-
-template<typename _Tp> inline _Tp& SparseMatIterator::value() const
-{ return *(_Tp*)ptr; }
-
-inline SparseMat::Node* SparseMatIterator::node() const
-{
- return (SparseMat::Node*)SparseMatConstIterator::node();
-}
-
-inline SparseMatIterator& SparseMatIterator::operator ++()
-{
- SparseMatConstIterator::operator ++();
- return *this;
-}
-
-inline SparseMatIterator SparseMatIterator::operator ++(int)
-{
- SparseMatIterator it = *this;
- ++*this;
- return it;
-}
-
-
-template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_()
-{ flags = MAGIC_VAL | DataType<_Tp>::type; }
-
-template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
-: SparseMat(_dims, _sizes, DataType<_Tp>::type)
-{}
-
-template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
-{
- if( m.type() == DataType<_Tp>::type )
- *this = (const SparseMat_<_Tp>&)m;
- else
- m.convertTo(*this, DataType<_Tp>::type);
-}
-
-template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m)
-{
- this->flags = m.flags;
- this->hdr = m.hdr;
- if( this->hdr )
- CV_XADD(&this->hdr->refcount, 1);
-}
-
-template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const Mat& m)
-{
- SparseMat sm(m);
- *this = sm;
-}
-
-template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const CvSparseMat* m)
-{
- SparseMat sm(m);
- *this = sm;
-}
-
-template<typename _Tp> inline SparseMat_<_Tp>&
-SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m)
-{
- if( this != &m )
- {
- if( m.hdr ) CV_XADD(&m.hdr->refcount, 1);
- release();
- flags = m.flags;
- hdr = m.hdr;
- }
- return *this;
-}
-
-template<typename _Tp> inline SparseMat_<_Tp>&
-SparseMat_<_Tp>::operator = (const SparseMat& m)
-{
- if( m.type() == DataType<_Tp>::type )
- return (*this = (const SparseMat_<_Tp>&)m);
- m.convertTo(*this, DataType<_Tp>::type);
- return *this;
-}
-
-template<typename _Tp> inline SparseMat_<_Tp>&
-SparseMat_<_Tp>::operator = (const Mat& m)
-{ return (*this = SparseMat(m)); }
-
-template<typename _Tp> inline SparseMat_<_Tp>
-SparseMat_<_Tp>::clone() const
-{
- SparseMat_<_Tp> m;
- this->copyTo(m);
- return m;
-}
-
-template<typename _Tp> inline void
-SparseMat_<_Tp>::create(int _dims, const int* _sizes)
-{
- SparseMat::create(_dims, _sizes, DataType<_Tp>::type);
-}
-
-template<typename _Tp> inline
-SparseMat_<_Tp>::operator CvSparseMat*() const
-{
- return SparseMat::operator CvSparseMat*();
-}
-
-template<typename _Tp> inline int SparseMat_<_Tp>::type() const
-{ return DataType<_Tp>::type; }
-
-template<typename _Tp> inline int SparseMat_<_Tp>::depth() const
-{ return DataType<_Tp>::depth; }
-
-template<typename _Tp> inline int SparseMat_<_Tp>::channels() const
-{ return DataType<_Tp>::channels; }
-
-template<typename _Tp> inline _Tp&
-SparseMat_<_Tp>::ref(int i0, size_t* hashval)
-{ return SparseMat::ref<_Tp>(i0, hashval); }
-
-template<typename _Tp> inline _Tp
-SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
-{ return SparseMat::value<_Tp>(i0, hashval); }
-
-template<typename _Tp> inline _Tp&
-SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
-{ return SparseMat::ref<_Tp>(i0, i1, hashval); }
-
-template<typename _Tp> inline _Tp
-SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const
-{ return SparseMat::value<_Tp>(i0, i1, hashval); }
-
-template<typename _Tp> inline _Tp&
-SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval)
-{ return SparseMat::ref<_Tp>(i0, i1, i2, hashval); }
-
-template<typename _Tp> inline _Tp
-SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const
-{ return SparseMat::value<_Tp>(i0, i1, i2, hashval); }
-
-template<typename _Tp> inline _Tp&
-SparseMat_<_Tp>::ref(const int* idx, size_t* hashval)
-{ return SparseMat::ref<_Tp>(idx, hashval); }
-
-template<typename _Tp> inline _Tp
-SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const
-{ return SparseMat::value<_Tp>(idx, hashval); }
-
-template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
-{ return SparseMatIterator_<_Tp>(this); }
-
-template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
-{ return SparseMatConstIterator_<_Tp>(this); }
-
-template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
-{ SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
-
-template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
-{ SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
-
-template<typename _Tp> inline
-SparseMatConstIterator_<_Tp>::SparseMatConstIterator_()
-{}
-
-template<typename _Tp> inline
-SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m)
-: SparseMatConstIterator(_m)
-{}
-
-template<typename _Tp> inline
-SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat* _m)
-: SparseMatConstIterator(_m)
-{
- CV_Assert( _m->type() == DataType<_Tp>::type );
-}
-
-template<typename _Tp> inline
-SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it)
-: SparseMatConstIterator(it)
-{}
-
-template<typename _Tp> inline SparseMatConstIterator_<_Tp>&
-SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it)
-{ return reinterpret_cast<SparseMatConstIterator_<_Tp>&>
- (*reinterpret_cast<SparseMatConstIterator*>(this) =
- reinterpret_cast<const SparseMatConstIterator&>(it)); }
-
-template<typename _Tp> inline const _Tp&
-SparseMatConstIterator_<_Tp>::operator *() const
-{ return *(const _Tp*)this->ptr; }
-
-template<typename _Tp> inline SparseMatConstIterator_<_Tp>&
-SparseMatConstIterator_<_Tp>::operator ++()
-{
- SparseMatConstIterator::operator ++();
- return *this;
-}
-
-template<typename _Tp> inline SparseMatConstIterator_<_Tp>
-SparseMatConstIterator_<_Tp>::operator ++(int)
-{
- SparseMatConstIterator_<_Tp> it = *this;
- SparseMatConstIterator::operator ++();
- return it;
-}
-
-template<typename _Tp> inline
-SparseMatIterator_<_Tp>::SparseMatIterator_()
-{}
-
-template<typename _Tp> inline
-SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m)
-: SparseMatConstIterator_<_Tp>(_m)
-{}
-
-template<typename _Tp> inline
-SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat* _m)
-: SparseMatConstIterator_<_Tp>(_m)
-{}
-
-template<typename _Tp> inline
-SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it)
-: SparseMatConstIterator_<_Tp>(it)
-{}
-
-template<typename _Tp> inline SparseMatIterator_<_Tp>&
-SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it)
-{ return reinterpret_cast<SparseMatIterator_<_Tp>&>
- (*reinterpret_cast<SparseMatConstIterator*>(this) =
- reinterpret_cast<const SparseMatConstIterator&>(it)); }
-
-template<typename _Tp> inline _Tp&
-SparseMatIterator_<_Tp>::operator *() const
-{ return *(_Tp*)this->ptr; }
-
-template<typename _Tp> inline SparseMatIterator_<_Tp>&
-SparseMatIterator_<_Tp>::operator ++()
-{
- SparseMatConstIterator::operator ++();
- return *this;
-}
-
-template<typename _Tp> inline SparseMatIterator_<_Tp>
-SparseMatIterator_<_Tp>::operator ++(int)
-{
- SparseMatIterator_<_Tp> it = *this;
- SparseMatConstIterator::operator ++();
- return it;
-}
-
-}
-
-#endif
-#endif
+#endif // __OPENCV_CORE_MAT_HPP__