typedef std::basic_string<wchar_t> WString;
class Mat;
-class MatND;
+class SparseMat;
+typedef Mat MatND;
+
class CV_EXPORTS MatExpr;
class CV_EXPORTS MatOp_Base;
+class CV_EXPORTS VectorArg;
+class CV_EXPORTS MatArg;
+class CV_EXPORTS MatConstIterator;
template<typename _Tp> class CV_EXPORTS MatIterator_;
template<typename _Tp> class CV_EXPORTS MatConstIterator_;
protected:
_Tp* obj; //< the object pointer.
- int* refcount; //< the associated reference counter
+ int* refcount; //< the associated bbbbbbbbbbbbbbbbbb reference counter
};
//////////////////////////////// Mat ////////////////////////////////
static inline size_t getElemSize(int type) { return CV_ELEM_SIZE(type); }
/*!
- The matrix class.
+ Custom array allocator
+
+*/
+class CV_EXPORTS ArrayAllocator
+{
+public:
+ ArrayAllocator() {}
+ virtual ~ArrayAllocator() {}
+ 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;
+};
+
+/*!
+ The n-dimensional matrix class.
- The class represents a 2D numerical array that can act as a matrix, image, optical flow map etc.
- It is very similar to CvMat type from earlier versions of OpenCV, and similarly to CvMat,
- the matrix can be multi-channel. It also fully supports ROI mechanism.
+ 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>
public:
//! default constructor
Mat();
- //! constructs matrix of the specified size and type
+ //! 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 matrix and fills it with the specified value _s.
+ //! 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);
+ 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);
//! converts old-style CvMat to the new matrix; the data is not copied by default
Mat(const CvMat* m, bool copyData=false);
+ //! converts old-style CvMatND to the new matrix; the data is not copied by default
+ Mat(const CvMatND* m, bool copyData=false);
//! converts old-style IplImage to the new matrix; the data is not copied by default
Mat(const IplImage* img, bool copyData=false);
//! builds matrix from std::vector with or without copying the data
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);
+ 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);
+ 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);
//! destructor - calls release()
//! 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;
//! 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);
// 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;
- // deallocate the data when reference counter reaches 0.
+ // 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);
//! locates matrix header within a parent matrix. See below
void locateROI( Size& wholeSize, Point& ofs ) const;
// (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;
//! returns element type, similar to CV_MAT_CN(cvmat->type)
int channels() const;
//! returns step/elemSize1()
- size_t step1() const;
- //! returns matrix size:
- // width == number of columns, height == number of rows
- Size size() const;
+ 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 pointer to y-th row
- uchar* ptr(int y=0);
- const uchar* ptr(int y=0) 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 y=0);
- template<typename _Tp> const _Tp* ptr(int y=0) const;
+ 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 methods for read-write or read-only element access.
- // note that _Tp must match the actual matrix type -
- // the functions do not do any on-fly type conversion
- template<typename _Tp> _Tp& at(int y, int x);
+ 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(int y, int x) const;
template<typename _Tp> const _Tp& at(Point pt) const;
- template<typename _Tp> _Tp& at(int i);
- template<typename _Tp> const _Tp& at(int i) const;
//! template methods for iteration over matrix elements.
// the iterators take care of skipping gaps in the end of rows (if any)
- number of channels
*/
int flags;
- //! the number of rows and columns
+ //! the matrix dimensionality
+ int dims;
+ //! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
int rows, cols;
- //! a distance between successive rows in bytes; includes the gap if any
- size_t step;
//! pointer to the data
uchar* data;
//! helper fields used in locateROI and adjustROI
uchar* datastart;
uchar* dataend;
+ //! custom allocator
+ ArrayAllocator* allocator;
+
+ struct CV_EXPORTS MSize
+ {
+ MSize(int* _p);
+ Size operator()() const;
+ int operator[](int i) const;
+ int& operator[](int i);
+ operator const int*() const;
+ bool operator == (const MSize& sz) const;
+ bool operator != (const MSize& sz) const;
+
+ int* p;
+ };
+
+ struct CV_EXPORTS MStep
+ {
+ MStep();
+ MStep(size_t s);
+ size_t operator[](int i) const;
+ size_t& operator[](int i);
+ operator size_t() const;
+ MStep& operator = (size_t s);
+
+ size_t* p;
+ size_t buf[2];
+ protected:
+ MStep& operator = (const MStep&);
+ };
+
+ MSize size;
+ MStep step;
};
//! returns uniformly distributed double-precision floating-point random number from [a,b) range
double uniform(double a, double b);
void fill( Mat& mat, int distType, const Scalar& a, const Scalar& b );
- void fill( MatND& mat, int distType, const Scalar& a, const Scalar& b );
//! returns Gaussian random variate with mean zero.
double gaussian(double sigma);
double epsilon; // the desired accuracy
};
+//! swaps two matrices
+CV_EXPORTS void swap(Mat& a, Mat& b);
+
//! converts array (CvMat or IplImage) to cv::Mat
-CV_EXPORTS Mat cvarrToMat(const CvArr* arr, bool copyData,
- bool allowND, int coiMode);
+CV_EXPORTS Mat cvarrToMat(const CvArr* arr, bool copyData=false,
+ bool allowND=true, int coiMode=0);
//! extracts Channel of Interest from CvMat or IplImage and makes cv::Mat out of it.
-CV_EXPORTS void extractImageCOI(const CvArr* arr, Mat& coiimg, int coi=-1);
+CV_EXPORTS void extractImageCOI(const CvArr* arr, CV_OUT Mat& coiimg, int coi=-1);
//! inserts single-channel cv::Mat into a multi-channel CvMat or IplImage
CV_EXPORTS void insertImageCOI(const Mat& coiimg, CvArr* arr, int coi=-1);
-//! adds one matrix to another (c = a + b)
-CV_EXPORTS void add(const Mat& a, const Mat& b, Mat& c, const Mat& mask);
-//! subtracts one matrix from another (c = a - b)
-CV_EXPORTS void subtract(const Mat& a, const Mat& b, Mat& c, const Mat& mask);
-//! adds one matrix to another (c = a + b)
-CV_EXPORTS void add(const Mat& a, const Mat& b, Mat& c);
-//! subtracts one matrix from another (c = a - b)
-CV_EXPORTS void subtract(const Mat& a, const Mat& b, Mat& c);
-//! adds scalar to a matrix (c = a + s)
-CV_EXPORTS void add(const Mat& a, const Scalar& s, Mat& c, const Mat& mask=Mat());
-//! subtracts scalar from a matrix (c = a - s)
-CV_EXPORTS void subtract(const Mat& a, const Scalar& s, Mat& c, const Mat& mask=Mat());
-//! subtracts matrix from scalar (c = s - a)
-CV_EXPORTS void subtract(const Scalar& s, const Mat& a, Mat& c, const Mat& mask=Mat());
-
-//! computes element-wise weighted product of the two arrays (c = scale*a*b)
-CV_EXPORTS void multiply(const Mat& a, const Mat& b, Mat& c, double scale=1);
-//! computes element-wise weighted quotient of the two arrays (c = scale*a/b)
-CV_EXPORTS void divide(const Mat& a, const Mat& b, Mat& c, double scale=1);
-//! computes element-wise weighted reciprocal of an array (c = scale/b)
-CV_EXPORTS void divide(double scale, const Mat& b, Mat& c);
-
-//! adds scaled array to another one (c = a*alpha + b)
-CV_EXPORTS void scaleAdd(const Mat& a, double alpha, const Mat& b, Mat& c);
-//! computes weighted sum of two arrays (c=alpha*a + beta*b + gamma)
-CV_EXPORTS void addWeighted(const Mat& a, double alpha, const Mat& b,
- double beta, double gamma, Mat& c);
-//! scales array elements, computes absolute values and converts the results to 8-bit unsigned integers: c(i)=saturate_cast<uchar>abs(a(i)*alpha+beta)
-CV_EXPORTS void convertScaleAbs(const Mat& a, Mat& c, double alpha=1, double beta=0);
-//! transforms 8-bit unsigned integers using lookup table: b(i)=lut(a(i))
-CV_EXPORTS void LUT(const Mat& a, const Mat& lut, Mat& b);
+//! adds one matrix to another (dst = src1 + src2)
+CV_EXPORTS void add(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, const Mat& mask);
+//! subtracts one matrix from another (dst = src1 - src2)
+CV_EXPORTS void subtract(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, const Mat& mask);
+//! adds one matrix to another (dst = src1 + src2)
+CV_EXPORTS void add(const Mat& src1, const Mat& src2, CV_OUT Mat& dst);
+//! subtracts one matrix from another (dst = src1 - src2)
+CV_EXPORTS void subtract(const Mat& src1, const Mat& src2, CV_OUT Mat& dst);
+//! adds scalar to a matrix (dst = src1 + src2)
+CV_EXPORTS void add(const Mat& src1, const Scalar& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+//! subtracts scalar from a matrix (dst = src1 - src2)
+CV_EXPORTS void subtract(const Mat& src1, const Scalar& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+//! subtracts matrix from scalar (dst = src1 - src2)
+CV_EXPORTS void subtract(const Scalar& src1, const Mat& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+
+//! computes element-wise weighted product of the two arrays (dst = scale*src1*src2)
+CV_EXPORTS void multiply(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, double scale=1);
+//! computes element-wise weighted quotient of the two arrays (dst = scale*src1/src2)
+CV_EXPORTS void divide(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, double scale=1);
+//! computes element-wise weighted reciprocal of an array (dst = scale/src2)
+CV_EXPORTS void divide(double scale, const Mat& src2, CV_OUT Mat& dst);
+
+//! adds scaled array to another one (dst = alpha*src1 + src2)
+CV_EXPORTS void scaleAdd(const Mat& src1, double alpha, const Mat& src2, CV_OUT Mat& dst);
+//! computes weighted sum of two arrays (dst = alpha*src1 + beta*src2 + gamma)
+CV_EXPORTS void addWeighted(const Mat& src1, double alpha, const Mat& src2,
+ double beta, double gamma, CV_OUT Mat& dst);
+//! scales array elements, computes absolute values and converts the results to 8-bit unsigned integers: dst(i)=saturate_cast<uchar>abs(src(i)*alpha+beta)
+CV_EXPORTS void convertScaleAbs(const Mat& src, CV_OUT Mat& dst, double alpha=1, double beta=0);
+//! transforms 8-bit unsigned integers using lookup table: dst(i)=lut(src(i))
+CV_EXPORTS void LUT(const Mat& src, const Mat& lut, CV_OUT Mat& dst);
//! computes sum of array elements
-CV_EXPORTS Scalar sum(const Mat& m);
+CV_EXPORTS Scalar sum(const Mat& src);
//! computes the number of nonzero array elements
-CV_EXPORTS int countNonZero( const Mat& m );
+CV_EXPORTS int countNonZero( const Mat& src );
//! computes mean value of array elements
-CV_EXPORTS Scalar mean(const Mat& m);
+CV_EXPORTS Scalar mean(const Mat& src);
//! computes mean value of selected array elements
-CV_EXPORTS Scalar mean(const Mat& m, const Mat& mask);
+CV_EXPORTS Scalar mean(const Mat& src, const Mat& mask);
//! computes mean value and standard deviation of all or selected array elements
-CV_EXPORTS void meanStdDev(const Mat& m, Scalar& mean, Scalar& stddev, const Mat& mask=Mat());
+CV_EXPORTS void meanStdDev(const Mat& src, CV_OUT Scalar& mean, CV_OUT Scalar& stddev, const Mat& mask=Mat());
//! computes norm of array
-CV_EXPORTS double norm(const Mat& a, int normType=NORM_L2);
+CV_EXPORTS double norm(const Mat& src, int normType=NORM_L2);
//! computes norm of the difference between two arrays
-CV_EXPORTS double norm(const Mat& a, const Mat& b, int normType=NORM_L2);
+CV_EXPORTS double norm(const Mat& src1, const Mat& src2, int normType=NORM_L2);
//! computes norm of the selected array part
-CV_EXPORTS double norm(const Mat& a, int normType, const Mat& mask);
+CV_EXPORTS double norm(const Mat& src, int normType, const Mat& mask);
//! computes norm of selected part of the difference between two arrays
-CV_EXPORTS double norm(const Mat& a, const Mat& b,
+CV_EXPORTS double norm(const Mat& src1, const Mat& src2,
int normType, const Mat& mask);
//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values
-CV_EXPORTS void normalize( const Mat& a, Mat& b, double alpha=1, double beta=0,
- int norm_type=NORM_L2, int rtype=-1, const Mat& mask=Mat());
+CV_EXPORTS void normalize( const Mat& src, CV_OUT Mat& dst, double alpha=1, double beta=0,
+ int norm_type=NORM_L2, int rtype=-1, const Mat& mask=Mat());
//! finds global minimum and maximum array elements and returns their values and their locations
-CV_EXPORTS void minMaxLoc(const Mat& a, double* minVal,
- double* maxVal=0, Point* minLoc=0,
- Point* maxLoc=0, const Mat& mask=Mat());
+CV_EXPORTS void minMaxLoc(const Mat& src, CV_OUT double* minVal,
+ CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0,
+ CV_OUT Point* maxLoc=0, const Mat& mask=Mat());
+CV_EXPORTS void minMaxIdx(const Mat& src, double* minVal,
+ double* maxVal,
+ CV_OUT CV_CARRAY(src.dims) int* minIdx=0,
+ CV_OUT CV_CARRAY(src.dims) int* maxIdx=0,
+ const Mat& mask=Mat());
+
//! transforms 2D matrix to 1D row or column vector by taking sum, minimum, maximum or mean value over all the rows
-CV_EXPORTS void reduce(const Mat& m, Mat& dst, int dim, int rtype, int dtype=-1);
+CV_EXPORTS void reduce(const Mat& src, CV_OUT Mat& dst, int dim, int rtype, int dtype=-1);
//! makes multi-channel array out of several single-channel arrays
-CV_EXPORTS void merge(const Mat* mv, size_t count, Mat& dst);
+CV_EXPORTS void merge(CV_CARRAY(count) const Mat* mv, size_t count, CV_OUT Mat& dst);
//! copies each plane of a multi-channel array to a dedicated array
-CV_EXPORTS void split(const Mat& m, Mat* mvbegin);
+CV_EXPORTS void split(const Mat& src, CV_OUT CV_CARRAY(src.channels()) Mat* mvbegin);
//! copies selected channels from the input arrays to the selected channels of the output arrays
-CV_EXPORTS void mixChannels(const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts,
- const int* fromTo, size_t npairs);
+CV_EXPORTS void mixChannels(CV_CARRAY(nsrcs) const Mat* src, size_t nsrcs, CV_CARRAY(ndsts) Mat* dst, size_t ndsts,
+ CV_CARRAY(npairs*2) const int* fromTo, size_t npairs);
//! reverses the order of the rows, columns or both in a matrix
-CV_EXPORTS void flip(const Mat& a, Mat& b, int flipCode);
+CV_EXPORTS void flip(const Mat& src, CV_OUT Mat& dst, int flipCode);
//! replicates the input matrix the specified number of times in the horizontal and/or vertical direction
-CV_EXPORTS void repeat(const Mat& a, int ny, int nx, Mat& b);
+CV_EXPORTS void repeat(const Mat& src, int ny, int nx, CV_OUT Mat& dst);
static inline Mat repeat(const Mat& src, int ny, int nx)
{
if( nx == 1 && ny == 1 ) return src;
Mat dst; repeat(src, ny, nx, dst); return dst;
}
-//! computes bitwise conjunction of the two arrays (c = a & b)
-CV_EXPORTS void bitwise_and(const Mat& a, const Mat& b, Mat& c, const Mat& mask=Mat());
-//! computes bitwise disjunction of the two arrays (c = a | b)
-CV_EXPORTS void bitwise_or(const Mat& a, const Mat& b, Mat& c, const Mat& mask=Mat());
-//! computes bitwise exclusive-or of the two arrays (c = a ^ b)
-CV_EXPORTS void bitwise_xor(const Mat& a, const Mat& b, Mat& c, const Mat& mask=Mat());
-//! computes bitwise conjunction of an array and scalar (c = a & s)
-CV_EXPORTS void bitwise_and(const Mat& a, const Scalar& s, Mat& c, const Mat& mask=Mat());
-//! computes bitwise disjunction of an array and scalar (c = a | s)
-CV_EXPORTS void bitwise_or(const Mat& a, const Scalar& s, Mat& c, const Mat& mask=Mat());
-//! computes bitwise exclusive-or of an array and scalar (c = a ^ s)
-CV_EXPORTS void bitwise_xor(const Mat& a, const Scalar& s, Mat& c, const Mat& mask=Mat());
-//! inverts each bit of a (c = ~a)
-CV_EXPORTS void bitwise_not(const Mat& a, Mat& c);
-//! computes element-wise absolute difference of two arrays (c = abs(a - b))
-CV_EXPORTS void absdiff(const Mat& a, const Mat& b, Mat& c);
-//! computes element-wise absolute difference of array and scalar (c = abs(a - s))
-CV_EXPORTS void absdiff(const Mat& a, const Scalar& s, Mat& c);
+//! computes bitwise conjunction of the two arrays (dst = src1 & src2)
+CV_EXPORTS void bitwise_and(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+//! computes bitwise disjunction of the two arrays (dst = src1 | src2)
+CV_EXPORTS void bitwise_or(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+//! computes bitwise exclusive-or of the two arrays (dst = src1 ^ src2)
+CV_EXPORTS void bitwise_xor(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+//! computes bitwise conjunction of an array and scalar (dst = src1 & src2)
+CV_EXPORTS void bitwise_and(const Mat& src1, const Scalar& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+//! computes bitwise disjunction of an array and scalar (dst = src1 | src2)
+CV_EXPORTS void bitwise_or(const Mat& src1, const Scalar& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+//! computes bitwise exclusive-or of an array and scalar (dst = src1 ^ src2)
+CV_EXPORTS void bitwise_xor(const Mat& src1, const Scalar& src2, CV_OUT Mat& dst, const Mat& mask=Mat());
+//! inverts each bit of array (dst = ~src)
+CV_EXPORTS void bitwise_not(const Mat& src, CV_OUT Mat& dst);
+//! computes element-wise absolute difference of two arrays (dst = abs(src1 - src2))
+CV_EXPORTS void absdiff(const Mat& src1, const Mat& src2, CV_OUT Mat& dst);
+//! computes element-wise absolute difference of array and scalar (dst = abs(src1 - src2))
+CV_EXPORTS void absdiff(const Mat& src1, const Scalar& src2, CV_OUT Mat& dst);
//! set mask elements for those array elements which are within the element-specific bounding box (dst = lowerb <= src && src < upperb)
CV_EXPORTS void inRange(const Mat& src, const Mat& lowerb,
- const Mat& upperb, Mat& dst);
+ const Mat& upperb, CV_OUT Mat& dst);
//! set mask elements for those array elements which are within the fixed bounding box (dst = lowerb <= src && src < upperb)
CV_EXPORTS void inRange(const Mat& src, const Scalar& lowerb,
- const Scalar& upperb, Mat& dst);
-//! compares elements of two arrays (c = a <cmpop> b)
-CV_EXPORTS void compare(const Mat& a, const Mat& b, Mat& c, int cmpop);
-//! compares elements of array with scalar (c = a <cmpop> s)
-CV_EXPORTS void compare(const Mat& a, double s, Mat& c, int cmpop);
-//! computes per-element minimum of two arrays (c = min(a, b))
-CV_EXPORTS void min(const Mat& a, const Mat& b, Mat& c);
-//! computes per-element minimum of array and scalar (c = min(a, alpha))
-CV_EXPORTS void min(const Mat& a, double alpha, Mat& c);
-//! computes per-element maximum of two arrays (c = max(a, b))
-CV_EXPORTS void max(const Mat& a, const Mat& b, Mat& c);
-//! computes per-element maximum of array and scalar (c = max(a, alpha))
-CV_EXPORTS void max(const Mat& a, double alpha, Mat& c);
-
-//! computes square root of each matrix element (b = a**0.5)
-CV_EXPORTS void sqrt(const Mat& a, Mat& b);
+ const Scalar& upperb, CV_OUT Mat& dst);
+//! compares elements of two arrays (dst = src1 <cmpop> src2)
+CV_EXPORTS void compare(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, int cmpop);
+//! compares elements of array with scalar (dst = src1 <cmpop> src2)
+CV_EXPORTS void compare(const Mat& src1, double s, CV_OUT Mat& dst, int cmpop);
+//! computes per-element minimum of two arrays (dst = min(src1, src2))
+CV_EXPORTS void min(const Mat& src1, const Mat& src2, CV_OUT Mat& dst);
+//! computes per-element minimum of array and scalar (dst = min(src1, src2))
+CV_EXPORTS void min(const Mat& src1, double src2, CV_OUT Mat& dst);
+//! computes per-element maximum of two arrays (dst = max(src1, src2))
+CV_EXPORTS void max(const Mat& src1, const Mat& src2, CV_OUT Mat& dst);
+//! computes per-element maximum of array and scalar (dst = max(src1, src2))
+CV_EXPORTS void max(const Mat& src1, double src2, CV_OUT Mat& dst);
+
+//! computes square root of each matrix element (dst = src**0.5)
+CV_EXPORTS void sqrt(const Mat& src, CV_OUT Mat& dst);
//! raises the input matrix elements to the specified power (b = a**power)
-CV_EXPORTS void pow(const Mat& a, double power, Mat& b);
-//! computes exponent of each matrix element (b = e**a)
-CV_EXPORTS void exp(const Mat& a, Mat& b);
-//! computes natural logarithm of absolute value of each matrix element: b = log(abs(a))
-CV_EXPORTS void log(const Mat& a, Mat& b);
+CV_EXPORTS void pow(const Mat& src, double power, CV_OUT Mat& dst);
+//! computes exponent of each matrix element (dst = e**src)
+CV_EXPORTS void exp(const Mat& src, CV_OUT Mat& dst);
+//! computes natural logarithm of absolute value of each matrix element: dst = log(abs(src))
+CV_EXPORTS void log(const Mat& src, CV_OUT Mat& dst);
//! computes cube root of the argument
CV_EXPORTS float cubeRoot(float val);
//! computes the angle in degrees (0..360) of the vector (x,y)
CV_EXPORTS float fastAtan2(float y, float x);
//! converts polar coordinates to Cartesian
CV_EXPORTS void polarToCart(const Mat& magnitude, const Mat& angle,
- Mat& x, Mat& y, bool angleInDegrees=false);
+ CV_OUT Mat& x, CV_OUT Mat& y, bool angleInDegrees=false);
//! converts Cartesian coordinates to polar
CV_EXPORTS void cartToPolar(const Mat& x, const Mat& y,
- Mat& magnitude, Mat& angle,
+ CV_OUT Mat& magnitude, CV_OUT Mat& angle,
bool angleInDegrees=false);
//! computes angle (angle(i)) of each (x(i), y(i)) vector
-CV_EXPORTS void phase(const Mat& x, const Mat& y, Mat& angle,
+CV_EXPORTS void phase(const Mat& x, const Mat& y, CV_OUT Mat& angle,
bool angleInDegrees=false);
//! computes magnitude (magnitude(i)) of each (x(i), y(i)) vector
-CV_EXPORTS void magnitude(const Mat& x, const Mat& y, Mat& magnitude);
+CV_EXPORTS void magnitude(const Mat& x, const Mat& y, CV_OUT Mat& magnitude);
//! checks that each matrix element is within the specified range.
-CV_EXPORTS bool checkRange(const Mat& a, bool quiet=true, Point* pt=0,
+CV_EXPORTS bool checkRange(const Mat& a, bool quiet=true, CV_OUT Point* pt=0,
double minVal=-DBL_MAX, double maxVal=DBL_MAX);
//! implements generalized matrix product algorithm GEMM from BLAS
-CV_EXPORTS void gemm(const Mat& a, const Mat& b, double alpha,
- const Mat& c, double gamma, Mat& d, int flags=0);
+CV_EXPORTS void gemm(const Mat& src1, const Mat& src2, double alpha,
+ const Mat& src3, double gamma, CV_OUT Mat& dst, int flags=0);
//! multiplies matrix by its transposition from the left or from the right
-CV_EXPORTS void mulTransposed( const Mat& a, Mat& c, bool aTa,
+CV_EXPORTS void mulTransposed( const Mat& src, CV_OUT Mat& dst, bool aTa,
const Mat& delta=Mat(),
double scale=1, int rtype=-1 );
//! transposes the matrix
-CV_EXPORTS void transpose(const Mat& a, Mat& b);
+CV_EXPORTS void transpose(const Mat& src, CV_OUT Mat& dst);
//! performs affine transformation of each element of multi-channel input matrix
-CV_EXPORTS void transform(const Mat& src, Mat& dst, const Mat& m );
+CV_EXPORTS void transform(const Mat& src, CV_OUT Mat& dst, const Mat& m );
//! performs perspective transformation of each element of multi-channel input matrix
-CV_EXPORTS void perspectiveTransform(const Mat& src, Mat& dst, const Mat& m );
+CV_EXPORTS void perspectiveTransform(const Mat& src, CV_OUT Mat& dst, const Mat& m );
//! extends the symmetrical matrix from the lower half or from the upper half
-CV_EXPORTS void completeSymm(Mat& a, bool lowerToUpper=false);
+CV_EXPORTS void completeSymm(Mat& mtx, bool lowerToUpper=false);
//! initializes scaled identity matrix
-CV_EXPORTS void setIdentity(Mat& c, const Scalar& s=Scalar(1));
+CV_EXPORTS void setIdentity(Mat& mtx, const Scalar& s=Scalar(1));
//! computes determinant of a square matrix
-CV_EXPORTS double determinant(const Mat& m);
+CV_EXPORTS double determinant(const Mat& mtx);
//! computes trace of a matrix
-CV_EXPORTS Scalar trace(const Mat& m);
+CV_EXPORTS Scalar trace(const Mat& mtx);
//! computes inverse or pseudo-inverse matrix
-CV_EXPORTS double invert(const Mat& a, Mat& c, int flags=DECOMP_LU);
+CV_EXPORTS double invert(const Mat& src, CV_OUT Mat& dst, int flags=DECOMP_LU);
//! solves linear system or a least-square problem
-CV_EXPORTS bool solve(const Mat& a, const Mat& b, Mat& x, int flags=DECOMP_LU);
+CV_EXPORTS bool solve(const Mat& src1, const Mat& src2, CV_OUT Mat& dst, int flags=DECOMP_LU);
//! sorts independently each matrix row or each matrix column
-CV_EXPORTS void sort(const Mat& a, Mat& b, int flags);
+CV_EXPORTS void sort(const Mat& src, CV_OUT Mat& dst, int flags);
//! sorts independently each matrix row or each matrix column
-CV_EXPORTS void sortIdx(const Mat& a, Mat& b, int flags);
+CV_EXPORTS void sortIdx(const Mat& src, CV_OUT Mat& dst, int flags);
//! finds real roots of a cubic polynomial
-CV_EXPORTS int solveCubic(const Mat& coeffs, Mat& roots);
+CV_EXPORTS int solveCubic(const Mat& coeffs, CV_OUT Mat& roots);
//! finds real and complex roots of a polynomial
-CV_EXPORTS double solvePoly(const Mat& coeffs, Mat& roots, int maxIters=300);
+CV_EXPORTS double solvePoly(const Mat& coeffs, CV_OUT Mat& roots, int maxIters=300);
//! finds eigenvalues of a symmetric matrix
-CV_EXPORTS bool eigen(const Mat& a, Mat& eigenvalues, int lowindex=-1,
+CV_EXPORTS bool eigen(const Mat& src, CV_OUT Mat& eigenvalues, int lowindex=-1,
int highindex=-1);
//! finds eigenvalues and eigenvectors of a symmetric matrix
-CV_EXPORTS bool eigen(const Mat& a, Mat& eigenvalues, Mat& eigenvectors,
+CV_EXPORTS bool eigen(const Mat& src, CV_OUT Mat& eigenvalues, CV_OUT Mat& eigenvectors,
int lowindex=-1, int highindex=-1);
//! computes covariation matrix of a set of samples
-CV_EXPORTS void calcCovarMatrix( const Mat* samples, int nsamples,
- Mat& covar, Mat& mean,
+CV_EXPORTS void calcCovarMatrix( CV_CARRAY(nsamples) const Mat* samples, int nsamples,
+ CV_OUT Mat& covar, CV_OUT Mat& mean,
int flags, int ctype=CV_64F);
//! computes covariation matrix of a set of samples
-CV_EXPORTS void calcCovarMatrix( const Mat& samples, Mat& covar, Mat& mean,
+CV_EXPORTS void calcCovarMatrix( const Mat& samples, CV_OUT Mat& covar, CV_OUT Mat& mean,
int flags, int ctype=CV_64F);
/*!
//! projects vector from the original space to the principal components subspace
Mat project(const Mat& vec) const;
//! projects vector from the original space to the principal components subspace
- void project(const Mat& vec, Mat& result) const;
+ void project(const Mat& vec, CV_OUT Mat& result) const;
//! reconstructs the original vector from the projection
Mat backProject(const Mat& vec) const;
//! reconstructs the original vector from the projection
- void backProject(const Mat& vec, Mat& result) const;
+ void backProject(const Mat& vec, CV_OUT Mat& result) const;
Mat eigenvectors; //!< eigenvectors of the covariation matrix
Mat eigenvalues; //!< eigenvalues of the covariation matrix
//! the default constructor
SVD();
//! the constructor that performs SVD
- SVD( const Mat& m, int flags=0 );
+ SVD( const Mat& src, int flags=0 );
//! the operator that performs SVD. The previously allocated SVD::u, SVD::w are SVD::vt are released.
- SVD& operator ()( const Mat& m, int flags=0 );
+ SVD& operator ()( const Mat& src, int flags=0 );
//! decomposes matrix and stores the results to user-provided matrices
- static void compute( const Mat& m, Mat& w, Mat& u, Mat& vt, int flags=0 );
+ static void compute( const Mat& src, CV_OUT Mat& w, CV_OUT Mat& u, CV_OUT Mat& vt, int flags=0 );
//! computes singular values of a matrix
- static void compute( const Mat& m, Mat& w, int flags=0 );
+ static void compute( const Mat& src, CV_OUT Mat& w, int flags=0 );
//! performs back substitution
static void backSubst( const Mat& w, const Mat& u, const Mat& vt,
- const Mat& rhs, Mat& dst );
+ const Mat& rhs, CV_OUT Mat& dst );
template<typename _Tp, int m, int n, int nm> static void compute( const Matx<_Tp, m, n>& a,
Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt );
const Matx<_Tp, m, nm>& u, const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs, Matx<_Tp, n, nb>& dst );
//! finds dst = arg min_{|dst|=1} |m*dst|
- static void solveZ( const Mat& m, Mat& dst );
+ static void solveZ( const Mat& src, CV_OUT Mat& dst );
//! performs back substitution, so that dst is the solution or pseudo-solution of m*dst = rhs, where m is the decomposed matrix
- void backSubst( const Mat& rhs, Mat& dst ) const;
+ void backSubst( const Mat& rhs, CV_OUT Mat& dst ) const;
Mat u, w, vt;
};
{ return Mahalanobis(v1, v2, icovar); }
//! performs forward or inverse 1D or 2D Discrete Fourier Transformation
-CV_EXPORTS void dft(const Mat& src, Mat& dst, int flags=0, int nonzeroRows=0);
+CV_EXPORTS void dft(const Mat& src, CV_OUT Mat& dst, int flags=0, int nonzeroRows=0);
//! performs inverse 1D or 2D Discrete Fourier Transformation
-CV_EXPORTS void idft(const Mat& src, Mat& dst, int flags=0, int nonzeroRows=0);
+CV_EXPORTS void idft(const Mat& src, CV_OUT Mat& dst, int flags=0, int nonzeroRows=0);
//! performs forward or inverse 1D or 2D Discrete Cosine Transformation
-CV_EXPORTS void dct(const Mat& src, Mat& dst, int flags=0);
+CV_EXPORTS void dct(const Mat& src, CV_OUT Mat& dst, int flags=0);
//! performs inverse 1D or 2D Discrete Cosine Transformation
-CV_EXPORTS void idct(const Mat& src, Mat& dst, int flags=0);
+CV_EXPORTS void idct(const Mat& src, CV_OUT Mat& dst, int flags=0);
//! computes element-wise product of the two Fourier spectrums. The second spectrum can optionally be conjugated before the multiplication
-CV_EXPORTS void mulSpectrums(const Mat& a, const Mat& b, Mat& c,
+CV_EXPORTS void mulSpectrums(const Mat& a, const Mat& b, CV_OUT Mat& c,
int flags, bool conjB=false);
//! computes the minimal vector size vecsize1 >= vecsize so that the dft() of the vector of length vecsize1 can be computed efficiently
CV_EXPORTS int getOptimalDFTSize(int vecsize);
KMEANS_USE_INITIAL_LABELS=1 // Uses the user-provided labels for K-Means initialization
};
//! clusters the input data using k-Means algorithm
-CV_EXPORTS double kmeans( const Mat& data, int K, Mat& bestLabels,
+CV_EXPORTS double kmeans( const Mat& data, int K, CV_OUT Mat& bestLabels,
TermCriteria criteria, int attempts,
- int flags, Mat* centers );
+ int flags, CV_OUT Mat* centers=0 );
//! returns the thread-local Random number generator
CV_EXPORTS RNG& theRNG();
template<typename _Tp> static inline _Tp randu() { return (_Tp)theRNG(); }
//! fills array with uniformly-distributed random numbers from the range [low, high)
-static inline void randu(Mat& dst, const Scalar& low, const Scalar& high)
+static inline void randu(CV_OUT Mat& dst, const Scalar& low, const Scalar& high)
{ theRNG().fill(dst, RNG::UNIFORM, low, high); }
//! fills array with normally-distributed random numbers with the specified mean and the standard deviation
-static inline void randn(Mat& dst, const Scalar& mean, const Scalar& stddev)
+static inline void randn(CV_OUT Mat& dst, const Scalar& mean, const Scalar& stddev)
{ theRNG().fill(dst, RNG::NORMAL, mean, stddev); }
//! shuffles the input array elements
int thickness=1, int lineType=8);
//! draws a filled convex polygon in the image
-CV_EXPORTS void fillConvexPoly(Mat& img, const Point* pts, int npts,
+CV_EXPORTS void fillConvexPoly(Mat& img, CV_CARRAY(npts) const Point* pts, int npts,
const Scalar& color, int lineType=8,
int shift=0);
//! fills an area bounded by one or more polygons
-CV_EXPORTS void fillPoly(Mat& img, const Point** pts, const int* npts, int ncontours,
+CV_EXPORTS void fillPoly(Mat& img, CV_CARRAY(ncontours) const Point** pts,
+ CV_CARRAY(ncontours) const int* npts, int ncontours,
const Scalar& color, int lineType=8, int shift=0,
Point offset=Point() );
//! draws one or more polygonal curves
-CV_EXPORTS void polylines(Mat& img, const Point** pts, const int* npts, int ncontours, bool isClosed,
- const Scalar& color, int thickness=1, int lineType=8, int shift=0 );
+CV_EXPORTS void polylines(Mat& img, CV_CARRAY(ncontours) const Point** pts, CV_CARRAY(ncontours) const int* npts,
+ int ncontours, bool isClosed, const Scalar& color,
+ int thickness=1, int lineType=8, int shift=0 );
//! clips the line segment by the rectangle Rect(0, 0, imgSize.width, imgSize.height)
CV_EXPORTS bool clipLine(Size imgSize, Point& pt1, Point& pt2);
{
public:
//! intializes the iterator
- LineIterator(const Mat& img, Point pt1, Point pt2,
- int connectivity=8, bool leftToRight=false);
+ LineIterator( const Mat& img, Point pt1, Point pt2,
+ int connectivity=8, bool leftToRight=false );
//! returns pointer to the current pixel
uchar* operator *();
//! prefix increment operator (++it). shifts iterator to the next pixel
//! converts elliptic arc to a polygonal curve
CV_EXPORTS void ellipse2Poly( Point center, Size axes, int angle,
- int arcStart, int arcEnd, int delta, vector<Point>& pts );
+ int arcStart, int arcEnd, int delta, CV_OUT vector<Point>& pts );
enum
{
//! returns bounding box of the text string
CV_EXPORTS Size getTextSize(const string& text, int fontFace,
double fontScale, int thickness,
- int* baseLine);
+ CV_OUT int* baseLine);
///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
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);
+ 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);
//! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column
explicit Mat_(const vector<_Tp>& vec, bool copyData=false);
template<int n> explicit Mat_(const Vec<_Tp, n>& vec, bool copyData=true);
template<int m, int n> explicit Mat_(const Matx<_Tp, m, n>& mtx, bool copyData=true);
- explicit Mat_(const Point_<_Tp>& pt);
- explicit Mat_(const Point3_<_Tp>& pt);
+ explicit Mat_(const Point_<_Tp>& pt, bool copyData=true);
+ explicit Mat_(const Point3_<_Tp>& pt, bool copyData=true);
explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
Mat_& operator = (const Mat& m);
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;
//! to support complex matrix expressions
int type() const;
int depth() const;
int channels() const;
- size_t step1() const;
+ size_t step1(int i=0) const;
//! returns step()/sizeof(_Tp)
- size_t stepT() const;
+ 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);
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;
- _Tp& operator ()(int row, int col);
- const _Tp& operator ()(int row, int col) 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;
- _Tp& operator ()(int i);
- const _Tp& operator ()(int i) const;
//! conversion to vector.
operator vector<_Tp>() const;
//////////// Iterators & Comma initializers //////////////////
+class CV_EXPORTS MatConstIterator
+{
+public:
+ typedef uchar* value_type;
+ typedef ptrdiff_t difference_type;
+ typedef const uchar** pointer;
+ typedef uchar* reference;
+ typedef std::random_access_iterator_tag iterator_category;
+
+ //! 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
+ uchar* operator *() const;
+ //! returns the i-th matrix element, relative to the current
+ 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;
+ uchar* ptr;
+ uchar* sliceStart;
+ uchar* sliceEnd;
+};
+
/*!
Matrix read-only iterator
- */
+ */
template<typename _Tp>
-class CV_EXPORTS MatConstIterator_
+class CV_EXPORTS MatConstIterator_ : public MatConstIterator
{
public:
typedef _Tp value_type;
- typedef int difference_type;
+ typedef ptrdiff_t difference_type;
typedef const _Tp* pointer;
typedef const _Tp& reference;
typedef std::random_access_iterator_tag iterator_category;
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);
//! returns the current matrix element
_Tp operator *() const;
//! returns the i-th matrix element, relative to the current
- _Tp operator [](int i) const;
+ _Tp operator [](ptrdiff_t i) const;
//! shifts the iterator forward by the specified number of elements
- MatConstIterator_& operator += (int ofs);
+ MatConstIterator_& operator += (ptrdiff_t ofs);
//! shifts the iterator backward by the specified number of elements
- MatConstIterator_& operator -= (int ofs);
+ MatConstIterator_& operator -= (ptrdiff_t ofs);
//! decrements the iterator
MatConstIterator_& operator --();
//! decrements the iterator
MatConstIterator_ operator ++(int);
//! returns the current iterator position
Point pos() const;
-
- const Mat_<_Tp>* m;
- _Tp* ptr;
- _Tp* sliceEnd;
};
MatIterator_(Mat_<_Tp>* _m, int _row, int _col=0);
//! constructor that sets the iterator to the specified element of the matrix
MatIterator_(const Mat_<_Tp>* _m, Point _pt);
+ //! constructor that sets the iterator to the specified element of the matrix
+ MatIterator_(const Mat_<_Tp>* _m, const int* _idx);
//! copy constructor
MatIterator_(const MatIterator_& it);
//! copy operator
//! returns the current matrix element
_Tp& operator *() const;
//! returns the i-th matrix element, relative to the current
- _Tp& operator [](int i) const;
+ _Tp& operator [](ptrdiff_t i) const;
//! shifts the iterator forward by the specified number of elements
- MatIterator_& operator += (int ofs);
+ MatIterator_& operator += (ptrdiff_t ofs);
//! shifts the iterator backward by the specified number of elements
- MatIterator_& operator -= (int ofs);
+ MatIterator_& operator -= (ptrdiff_t ofs);
//! decrements the iterator
MatIterator_& operator --();
//! decrements the iterator
/////////////////////////// multi-dimensional dense matrix //////////////////////////
-class MatND;
-class SparseMat;
-
-/*!
- n-Dimensional Dense Matrix Class.
-
- The class cv::MatND describes n-dimensional dense numerical single-channel or multi-channel array.
- This is a convenient representation for multi-dimensional histograms
- (when they are not very sparse, otherwise cv::SparseMat will do better),
- voxel volumes, stacked motion fields etc. The data layout of matrix M is defined by the array of M.step[],
- so that the address of element (i_0,...,i_{M.dims-1}), where 0 <= i_k < M.size[k] is computed as:
-
- addr(M_{i_0,...,i_{M.dims-1}}) = M.data + M.step[0]*i_0 + M.step[1]*i_1 + ... + M.step[M.dims-1]*i_{M.dims-1}
-
- which is more general form of the respective formula for cv::Mat, wherein size[0] ~ rows,
- size[1] ~ cols, step[0] was simply called step, and step[1] was not stored at all but computed as Mat::elemSize().
-
- In other aspects cv::MatND is also very similar to cv::Mat, with the following limitations and differences:
- <ul>
- <li> much less operations are implemented for cv::MatND
- <li> currently, algebraic expressions with cv::MatND's are not supported
- <li> the cv::MatND iterator is completely different from cv::Mat_ and cv::SparseMat_ iterators.
- The latter are per-element iterators, while the former is per-slice iterator, see below.
- </ul>
-
- Here is how you can use cv::MatND to compute NxNxN histogram of color 8bpp image
- (i.e. each channel value ranges from 0..255 and we quantize it to 0..N-1):
-
- \code
- void computeColorHist(const Mat& image, MatND& hist, int N)
- {
- const int histSize[] = {N, N, N};
-
- // make sure that the histogram has proper size and type
- hist.create(3, histSize, CV_32F);
-
- // and clear it
- hist = Scalar(0);
-
- // the loop below assumes that the image
- // is 8-bit 3-channel, so let's check it.
- CV_Assert(image.type() == CV_8UC3);
- MatConstIterator_<Vec3b> it = image.begin<Vec3b>(),
- it_end = image.end<Vec3b>();
- for( ; it != it_end; ++it )
- {
- const Vec3b& pix = *it;
-
- // we could have incremented the cells by 1.f/(image.rows*image.cols)
- // instead of 1.f to make the histogram normalized.
- hist.at<float>(pix[0]*N/256, pix[1]*N/256, pix[2]*N/256) += 1.f;
- }
- }
- \endcode
-*/
-class CV_EXPORTS MatND
-{
-public:
- //! default constructor
- MatND();
- //! constructs array with specific size and data type
- MatND(int _ndims, const int* _sizes, int _type);
- //! constructs array and fills it with the specified value
- MatND(int _ndims, const int* _sizes, int _type, const Scalar& _s);
- //! copy constructor. only the header is copied.
- MatND(const MatND& m);
- //! sub-array selection. only the header is copied
- MatND(const MatND& m, const Range* ranges);
- //! converts 2D matrix to ND matrix
- explicit MatND(const Mat& m);
- //! converts old-style nd array to MatND; optionally, copies the data
- MatND(const CvMatND* m, bool copyData=false);
- //! destructor
- ~MatND();
- //! the copy operator
- MatND& operator = (const MatND& m);
-
- //! helper method for matrix expressions
- void assignTo( MatND& m, int type ) const;
-
- //! creates a complete copy of the matrix (all the data is copied)
- MatND clone() const;
- //! sub-array selection; only the header is copied
- MatND operator()(const Range* ranges) const;
-
- //! copies the data to another matrix. Calls m.create(this->size(), this->type()) prior to copying the data
- void copyTo( MatND& m ) const;
- //! copies only the selected elements to another matrix.
- void copyTo( MatND& m, const MatND& mask ) const;
- //! converts data to the specified data type. Calls m.create(this->size(), rtype) prior to the conversion
- void convertTo( MatND& m, int rtype, double alpha=1, double beta=0 ) const;
-
- //! assigns "s" to each array element.
- MatND& operator = (const Scalar& s);
- //! assigns "s" to the selected elements of array (or to all the elements if mask==MatND())
- MatND& setTo(const Scalar& s, const MatND& mask=MatND());
- //! modifies geometry of array without copying the data
- MatND reshape(int _newcn, int _newndims=0, const int* _newsz=0) const;
-
- //! allocates a new buffer for the data unless the current one already has the specified size and type.
- void create(int _ndims, const int* _sizes, int _type);
- //! manually increment reference counter (use with care !!!)
- void addref();
- //! decrements the reference counter. Dealloctes the data when the reference counter reaches zero.
- void release();
-
- //! converts the matrix to 2D Mat without copying the data
- operator Mat() const;
- //! converts the matrix to CvMatND without copying the data
- operator CvMatND() const;
- //! returns true if the array data is stored continuously
- bool isContinuous() const;
- //! returns size of each element in bytes
- size_t elemSize() const;
- //! returns size of each element channel in bytes
- size_t elemSize1() const;
- //! returns OpenCV data type id (CV_8UC1, ... CV_64FC4,...)
- int type() const;
- //! returns depth (CV_8U ... CV_64F)
- int depth() const;
- //! returns the number of channels
- int channels() const;
- //! returns step()/elemSize1()
- size_t step1(int i) const;
-
- //! returns pointer to the element of 1D matrix
- uchar* ptr(int i0);
- //! returns read-only pointer to the element of 1D matrix
- const uchar* ptr(int i0) const;
- //! returns pointer to the element of 2D matrix
- uchar* ptr(int i0, int i1);
- //! returns read-only pointer to the element of 2D matrix
- const uchar* ptr(int i0, int i1) const;
- //! returns pointer to the element of 3D matrix
- uchar* ptr(int i0, int i1, int i2);
- //! returns read-only pointer to the element of 3D matrix
- const uchar* ptr(int i0, int i1, int i2) const;
- //! returns pointer to the element of nD matrix
- uchar* ptr(const int* idx);
- //! returns read-only pointer to the element of nD matrix
- const uchar* ptr(const int* idx) const;
-
- //! returns reference to the element of 1D matrix
- template<typename _Tp> _Tp& at(int i0);
- //! returns read-only reference to the element of 1D matrix
- template<typename _Tp> const _Tp& at(int i0) const;
- //! returns reference to the element of 2D matrix
- template<typename _Tp> _Tp& at(int i0, int i1);
- //! returns read-only reference to the element of 2D matrix
- template<typename _Tp> const _Tp& at(int i0, int i1) const;
- //! returns reference to the element of 3D matrix
- template<typename _Tp> _Tp& at(int i0, int i1, int i2);
- //! returns read-only reference to the element of 3D matrix
- template<typename _Tp> const _Tp& at(int i0, int i1, int i2) const;
- //! returns reference to the element of nD matrix
- template<typename _Tp> _Tp& at(const int* idx);
- //! returns read-only reference to the element of nD matrix
- template<typename _Tp> const _Tp& at(const int* idx) const;
-
- enum { MAGIC_VAL=0x42FE0000, AUTO_STEP=-1,
- CONTINUOUS_FLAG=CV_MAT_CONT_FLAG, MAX_DIM=CV_MAX_DIM };
-
- // combines data type, continuity flag, signature (magic value)
- int flags;
- // the array dimensionality
- int dims;
-
- // data reference counter
- int* refcount;
- // pointer to the data
- uchar* data;
- // and its actual beginning and end
- uchar* datastart;
- uchar* dataend;
-
- // step and size for each dimension, MAX_DIM at max
- int size[MAX_DIM];
- size_t step[MAX_DIM];
-};
-
/*!
n-Dimensional Dense Matrix Iterator Class.
- The class cv::NAryMatNDIterator is used for iterating over one or more n-dimensional dense arrays (cv::MatND's).
+ The class cv::NAryMatNDIterator 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(MatND& hist)
+ 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
- MatNDIterator it(hist);
+ 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 = MatNDIterator(hist);
+ 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 MatND
+ // using built-in operations on Mat
double s = sum(hist)[0];
hist.convertTo(hist, hist.type(), 1./s, 0);
#else
Then, during the iteration it.planes[0], it.planes[1], ... will
be the slices of the corresponding matrices
*/
-class CV_EXPORTS NAryMatNDIterator
+class CV_EXPORTS NAryMatIterator
{
public:
//! the default constructor
- NAryMatNDIterator();
+ NAryMatIterator();
//! the full constructor taking arbitrary number of n-dim matrices
- NAryMatNDIterator(const MatND* arrays, size_t count);
- //! another form of the constructor taking pointers to the headers
- NAryMatNDIterator(const MatND** arrays, size_t count);
- //! the full constructor for iteration through a single n-dim matrix
- NAryMatNDIterator(const MatND& m0);
- //! the full constructor for iteration through 2 n-dim matrices
- NAryMatNDIterator(const MatND& m0, const MatND& m1);
- //! the full constructor for iteration through 3 n-dim matrices
- NAryMatNDIterator(const MatND& m0, const MatND& m1, const MatND& m2);
- //! the full constructor for iteration through 4 n-dim matrices
- NAryMatNDIterator(const MatND& m0, const MatND& m1, const MatND& m2, const MatND& m3);
- //! the full constructor for iteration through 5 n-dim matrices
- NAryMatNDIterator(const MatND& m0, const MatND& m1, const MatND& m2,
- const MatND& m3, const MatND& m4);
- //! the full constructor for iteration through 6 n-dim matrices
- NAryMatNDIterator(const MatND& m0, const MatND& m1, const MatND& m2,
- const MatND& m3, const MatND& m4, const MatND& m5);
+ NAryMatIterator(const Mat** arrays, Mat* planes, int narrays=-1);
//! the separate iterator initialization method
- void init(const MatND** arrays, size_t count);
+ void init(const Mat** arrays, Mat* planes, int narrays=-1);
//! proceeds to the next plane of every iterated matrix
- NAryMatNDIterator& operator ++();
+ NAryMatIterator& operator ++();
//! proceeds to the next plane of every iterated matrix (postfix increment operator)
- NAryMatNDIterator operator ++(int);
-
+ NAryMatIterator operator ++(int);
+
//! the iterated arrays
- vector<MatND> arrays;
+ const Mat** arrays;
//! the current planes
- vector<Mat> planes;
-
+ Mat* planes;
+ //! the number of arrays
+ int narrays;
+ //! the number of planes in each array
int nplanes;
protected:
int iterdepth, idx;
};
-
-//! adds one n-dim array to another
-CV_EXPORTS void add(const MatND& a, const MatND& b, MatND& c, const MatND& mask);
-//! subtracts one n-dim array from another
-CV_EXPORTS void subtract(const MatND& a, const MatND& b, MatND& c, const MatND& mask);
-//! adds one n-dim array to another
-CV_EXPORTS void add(const MatND& a, const MatND& b, MatND& c);
-//! subtracts one n-dim array from another
-CV_EXPORTS void subtract(const MatND& a, const MatND& b, MatND& c);
-//! adds scalar to n-dim array
-CV_EXPORTS void add(const MatND& a, const Scalar& s, MatND& c, const MatND& mask=MatND());
-//! subtracts scalar from n-dim array
-CV_EXPORTS void subtract(const Scalar& s, const MatND& a, MatND& c, const MatND& mask=MatND());
-//! computes element-wise weighted product of the two n-dim arrays (c = scale*a*b)
-CV_EXPORTS void multiply(const MatND& a, const MatND& b, MatND& c, double scale=1);
-//! computes element-wise weighted quotient of the two n-dim arrays (c = scale*a/b)
-CV_EXPORTS void divide(const MatND& a, const MatND& b, MatND& c, double scale=1);
-//! computes element-wise weighted reciprocal of n-dim array (c = scale/b)
-CV_EXPORTS void divide(double scale, const MatND& b, MatND& c);
-//! adds weighted n-dim array to another (c = a*alpha + b)
-CV_EXPORTS void scaleAdd(const MatND& a, double alpha, const MatND& b, MatND& c);
-//! computes weighted sum of 2 n-dim arrays (c = a*alpha + b*beta + gamma)
-CV_EXPORTS void addWeighted(const MatND& a, double alpha, const MatND& b,
- double beta, double gamma, MatND& c);
-//! computes the sum of n-dim array elements
-CV_EXPORTS Scalar sum(const MatND& m);
-//! computes the number of non-zero elements of n-dim array
-CV_EXPORTS int countNonZero( const MatND& m );
-//! computes mean value of n-dim array elements
-CV_EXPORTS Scalar mean(const MatND& m);
-//! computes mean value of selected elements of n-dim array
-CV_EXPORTS Scalar mean(const MatND& m, const MatND& mask);
-//! computes the mean and the standard deviation of n-dim array
-CV_EXPORTS void meanStdDev(const MatND& m, Scalar& mean, Scalar& stddev, const MatND& mask=MatND());
-//! computes norm of n-dim array
-CV_EXPORTS double norm(const MatND& a, int normType=NORM_L2, const MatND& mask=MatND());
-//! computes norm of the difference between 2 n-dim arrays
-CV_EXPORTS double norm(const MatND& a, const MatND& b,
- int normType=NORM_L2, const MatND& mask=MatND());
-//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values
-CV_EXPORTS void normalize( const MatND& a, MatND& b, double alpha=1, double beta=0,
- int norm_type=NORM_L2, int rtype=-1, const MatND& mask=MatND());
-//! finds global minimum and maximum array elements and returns their values and their locations
-CV_EXPORTS void minMaxLoc(const MatND& a, double* minVal,
- double* maxVal, int* minIdx=0, int* maxIdx=0,
- const MatND& mask=MatND());
-//! makes multi-channel n-dim array out of several single-channel n-dim arrays
-CV_EXPORTS void merge(const MatND* mvbegin, size_t count, MatND& dst);
-//! copies each plane of a multi-channel n-dim array to a dedicated array
-CV_EXPORTS void split(const MatND& m, MatND* mv);
-//! copies selected channels from the input arrays to the selected channels of the output arrays
-CV_EXPORTS void mixChannels(const MatND* src, int nsrcs, MatND* dst, int ndsts,
- const int* fromTo, size_t npairs);
-//! computes bitwise conjunction of the two n-dim arrays (c = a & b)
-CV_EXPORTS void bitwise_and(const MatND& a, const MatND& b, MatND& c, const MatND& mask=MatND());
-//! computes bitwise disjunction of the two n-dim arrays (c = a | b)
-CV_EXPORTS void bitwise_or(const MatND& a, const MatND& b, MatND& c, const MatND& mask=MatND());
-//! computes bitwise exclusive-or of the two n-dim arrays (c = a ^ b)
-CV_EXPORTS void bitwise_xor(const MatND& a, const MatND& b, MatND& c, const MatND& mask=MatND());
-//! computes bitwise conjunction of n-dim array and scalar (c = a & s)
-CV_EXPORTS void bitwise_and(const MatND& a, const Scalar& s, MatND& c, const MatND& mask=MatND());
-//! computes bitwise disjunction of n-dim array and scalar (c = a | s)
-CV_EXPORTS void bitwise_or(const MatND& a, const Scalar& s, MatND& c, const MatND& mask=MatND());
-//! computes bitwise exclusive-or of n-dim array and scalar (c = a ^ s)
-CV_EXPORTS void bitwise_xor(const MatND& a, const Scalar& s, MatND& c, const MatND& mask=MatND());
-//! inverts each bit of each n-dim array element (c = ~a)
-CV_EXPORTS void bitwise_not(const MatND& a, MatND& c);
-//! computes element-wise absolute difference of two n-dim arrays (c = abs(a - b))
-CV_EXPORTS void absdiff(const MatND& a, const MatND& b, MatND& c);
-//! computes element-wise absolute difference of n-dim array and scalar (c = abs(a - s))
-CV_EXPORTS void absdiff(const MatND& a, const Scalar& s, MatND& c);
-//! set mask elements for those n-dim array elements which are within the element-specific bounding box (dst = lowerb <= src && src < upperb)
-CV_EXPORTS void inRange(const MatND& src, const MatND& lowerb,
- const MatND& upperb, MatND& dst);
-//! set mask elements for those n-dim array elements which are within the fixed bounding box (dst = lowerb <= src && src < upperb)
-CV_EXPORTS void inRange(const MatND& src, const Scalar& lowerb,
- const Scalar& upperb, MatND& dst);
-//! compares elements of two arrays (c = a <cmpop> b)
-CV_EXPORTS void compare(const MatND& a, const MatND& b, MatND& c, int cmpop);
-//! compares elements of two arrays (c = a <cmpop> b)
-CV_EXPORTS void compare(const MatND& a, double s, MatND& c, int cmpop);
-//! computes per-element minimum of two n-dim arrays (c = min(a, b))
-CV_EXPORTS void min(const MatND& a, const MatND& b, MatND& c);
-//! computes per-element minimum of n-dim array and scalar (c = min(a, s))
-CV_EXPORTS void min(const MatND& a, double alpha, MatND& c);
-//! computes per-element maximum of two n-dim arrays (c = max(a, s))
-CV_EXPORTS void max(const MatND& a, const MatND& b, MatND& c);
-//! computes per-element maximum of n-dim array and scalar (c = min(a, s))
-CV_EXPORTS void max(const MatND& a, double alpha, MatND& c);
-//! computes square root of each element of n-dim array (b = a**0.5)
-CV_EXPORTS void sqrt(const MatND& a, MatND& b);
-//! raises each n-dim array element to the specific power (b = a**power)
-CV_EXPORTS void pow(const MatND& a, double power, MatND& b);
-//! computes exponent of each n-dim array element (b = e**a)
-CV_EXPORTS void exp(const MatND& a, MatND& b);
-//! computes natural logarithm of absolute value of each n-dim array element (b = log(abs(a)))
-CV_EXPORTS void log(const MatND& a, MatND& b);
-//! checks that each matrix element is within the specified range.
-CV_EXPORTS bool checkRange(const MatND& a, bool quiet=true, int* idx=0,
- double minVal=-DBL_MAX, double maxVal=DBL_MAX);
+//typedef NAryMatIterator NAryMatNDIterator;
+
typedef void (*ConvertData)(const void* from, void* to, int cn);
typedef void (*ConvertScaleData)(const void* from, void* to, int cn, double alpha, double beta);
//! returns the function for converting pixels from one data type to another with the optional scaling
CV_EXPORTS ConvertScaleData getConvertScaleElem(int fromType, int toType);
-/*!
- Template n-dimensional dense matrix class derived from cv::MatND
-
- The class relates to cv::MatND almost like cv::Mat_ relates to cv::Mat - it provides
- a bit more convenient element access operations and adds no extra members
- or virtual methods to the base class, thus references/pointers to cv::MatND_ and cv::MatND
- can be easily converted one to another, e.g.
-
- \code
- void computeColorHist(const Mat& image, MatND& hist, int N)
- {
- const int histSize[] = {N, N, N};
-
- // make sure that the histogram has proper size and type
- hist.create(3, histSize, CV_32F);
-
- // and clear it
- hist = Scalar(0);
-
- // the loop below assumes that the image
- // is 8-bit 3-channel, so let's check it.
- CV_Assert(image.type() == CV_8UC3);
- MatConstIterator_<Vec3b> it = image.begin<Vec3b>(),
- it_end = image.end<Vec3b>();
- MatND_<float>& hist_ = (MatND_<float>&)hist;
-
- for( ; it != it_end; ++it )
- {
- const Vec3b& pix = *it;
- hist_(pix[0]*N/256, pix[1]*N/256, pix[2]*N/256) += 1.f;
- }
- }
- \endcode
-*/
-template<typename _Tp> class CV_EXPORTS MatND_ : public MatND
-{
-public:
- typedef _Tp value_type;
- typedef typename DataType<_Tp>::channel_type channel_type;
-
- //! the default constructor
- MatND_();
- //! the full constructor, equivalent to MatND(dims, _sizes, DataType<_Tp>::type)
- MatND_(int dims, const int* _sizes);
- //! the full constructor that sets each matrix element to the specified value
- MatND_(int dims, const int* _sizes, const _Tp& _s);
- //! the copy constructor. If m.type() != DataType<_Tp>::type, all the data is converted
- MatND_(const MatND& m);
- //! the copy constructor.
- MatND_(const MatND_& m);
- //! constructor for the specified subarray. The data is not copied!
- MatND_(const MatND_& m, const Range* ranges);
- //! the conversion constructor
- MatND_(const CvMatND* m, bool copyData=false);
- //! the assignment operator. If m.type() != DataType<_Tp>::type, all the data is converted
- MatND_& operator = (const MatND& m);
- //! the assignment operator. No data is copied
- MatND_& operator = (const MatND_& m);
- //! the assignment operator. All the elements are set to the specified value
- MatND_& operator = (const _Tp& s);
-
- //! equivalent to create(dims, _sizes, DataType<_Tp>::type)
- void create(int dims, const int* _sizes);
- //! conversion to another data type
- template<typename T2> operator MatND_<T2>() const;
- //! creates full copy of the matrix, including the data
- MatND_ clone() const;
- //! creates header for the specified submatrix. No data is copied
- MatND_ operator()(const Range* ranges) const;
- //! returns the element size in bytes
- size_t elemSize() const;
- //! returns the size of each element channel in bytes
- size_t elemSize1() const;
- //! returns DataType<_Tp>::type
- int type() const;
- //! returns DataType<_Tp>::depth
- int depth() const;
- //! returns DataType<_Tp>::channels
- int channels() const;
- //! returns step[i]/elemSize()
- size_t stepT(int i) const;
- //! returns step[i]/elemSize1()
- size_t step1(int i) 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 (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;
-};
-
/////////////////////////// multi-dimensional sparse matrix //////////////////////////
class SparseMatIterator;
Sparse matrix class.
The class represents multi-dimensional sparse numerical arrays. Such a sparse array can store elements
- of any type that cv::Mat and cv::MatND are able to store. "Sparse" means that only non-zero 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,
}
\endcode
- <li>Sparse matrix iterators. Like cv::Mat iterators and unlike cv::MatND iterators, the sparse matrix iterators are STL-style,
+ <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.
\param try1d if true and m is a single-column matrix (Nx1),
then the sparse matrix will be 1-dimensional.
*/
- SparseMat(const Mat& m, bool try1d=false);
- //! converts dense n-dim array to the sparse form
- SparseMat(const MatND& m);
+ SparseMat(const Mat& m);
//! converts old-style sparse matrix to the new-style. All the data is copied
SparseMat(const CvSparseMat* m);
//! the destructor
//! assignment operator. This is O(1) operation, i.e. no data is copied
SparseMat& operator = (const SparseMat& m);
- //! equivalent to the corresponding constructor with try1d=false
+ //! equivalent to the corresponding constructor
SparseMat& operator = (const Mat& m);
- //! converts dense n-dim array to the sparse form
- SparseMat& operator = (const MatND& 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 1D or 2D sparse matrix to dense 2D matrix. If the sparse matrix is 1D, then the result will be a single-column matrix.
+ //! converts sparse matrix to dense matrix.
void copyTo( Mat& m ) const;
- //! converts sparse matrix to the dense form. The output matrix may require a lot of memory!
- void copyTo( MatND& 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 beta The optional delta added to the scaled values before the conversion
*/
void convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const;
- //! converts sparse matrix to dense 2D matrix with optional type conversion and scaling.
- /*!
- \param rtype The output matrix data type. When it is =-1, the output array will have the same data type as (*this)
- \param alpha The scale factor
- \param beta The optional delta added to the scaled values before the conversion
- */
- void convertTo( MatND& m, int rtype, double alpha=1, double beta=0 ) const;
// not used now
void assignTo( SparseMat& m, int type=-1 ) const;
SparseMat_(const SparseMat& m);
//! the copy constructor. This is O(1) operation - no data is copied
SparseMat_(const SparseMat_& m);
- //! converts dense 2D matrix to the sparse form
+ //! converts dense matrix to the sparse form
SparseMat_(const Mat& m);
- //! converts dense n-dim matrix to the sparse form
- SparseMat_(const MatND& 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 2D matrix to the sparse form
+ //! converts dense matrix to the sparse form
SparseMat_& operator = (const Mat& m);
- //! converts dense n-dim matrix to the sparse form
- SparseMat_& operator = (const MatND& m);
//! makes full copy of the matrix. All the elements are duplicated
SparseMat_ clone() const;
//////////////////////////////// Mat ////////////////////////////////
inline Mat::Mat()
- : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) {}
+ : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
+{
+}
inline Mat::Mat(int _rows, int _cols, int _type)
- : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
+ : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
{
- if( _rows > 0 && _cols > 0 )
- create( _rows, _cols, _type );
+ create(_rows, _cols, _type);
}
inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
- : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
- datastart(0), dataend(0)
+ : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
{
- if(_rows > 0 && _cols > 0)
- {
- create(_rows, _cols, _type);
- *this = _s;
- }
+ create(_rows, _cols, _type);
+ *this = _s;
}
-inline Mat::Mat(Size _size, int _type)
- : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
- datastart(0), dataend(0)
+inline Mat::Mat(Size _sz, int _type)
+ : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
{
- if( _size.height > 0 && _size.width > 0 )
- create( _size.height, _size.width, _type );
+ create( _sz.height, _sz.width, _type );
}
-inline Mat::Mat(Size _size, int _type, const Scalar& _s)
- : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
- datastart(0), dataend(0)
+inline Mat::Mat(Size _sz, int _type, const Scalar& _s)
+ : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
{
- if( _size.height > 0 && _size.width > 0 )
- {
- create( _size.height, _size.width, _type );
- *this = _s;
- }
+ create(_sz.height, _sz.width, _type);
+ *this = _s;
+}
+
+inline Mat::Mat(int _dims, const int* _sz, int _type)
+ : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
+{
+ create(_dims, _sz, _type);
+}
+
+inline Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s)
+ : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
+{
+ create(_dims, _sz, _type);
+ *this = _s;
}
inline Mat::Mat(const Mat& m)
- : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data),
- refcount(m.refcount), datastart(m.datastart), dataend(m.dataend)
+ : flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
+ refcount(m.refcount), datastart(m.datastart), dataend(m.dataend),
+ allocator(m.allocator), size(&rows)
{
if( refcount )
CV_XADD(refcount, 1);
-}
-
-inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
- : flags(MAGIC_VAL + (_type & TYPE_MASK)), rows(_rows), cols(_cols),
- step(_step), data((uchar*)_data), refcount(0),
- datastart((uchar*)_data), dataend((uchar*)_data)
-{
- size_t minstep = cols*elemSize();
- if( step == AUTO_STEP )
+ if( m.dims <= 2 )
{
- step = minstep;
- flags |= CONTINUOUS_FLAG;
+ step[0] = m.step[0]; step[1] = m.step[1];
}
else
{
- if( rows == 1 ) step = minstep;
- CV_DbgAssert( step >= minstep );
- flags |= step == minstep ? CONTINUOUS_FLAG : 0;
+ dims = 0;
+ copySize(m);
}
- dataend += step*(rows-1) + minstep;
}
-inline Mat::Mat(Size _size, int _type, void* _data, size_t _step)
- : flags(MAGIC_VAL + (_type & TYPE_MASK)), rows(_size.height), cols(_size.width),
- step(_step), data((uchar*)_data), refcount(0),
- datastart((uchar*)_data), dataend((uchar*)_data)
+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((uchar*)_data),
+ allocator(0), size(&rows)
{
size_t minstep = cols*elemSize();
- if( step == AUTO_STEP )
+ if( _step == AUTO_STEP )
{
- step = minstep;
+ _step = minstep;
flags |= CONTINUOUS_FLAG;
}
else
{
- if( rows == 1 ) step = minstep;
- CV_DbgAssert( step >= minstep );
- flags |= step == minstep ? CONTINUOUS_FLAG : 0;
+ if( rows == 1 ) _step = minstep;
+ CV_DbgAssert( _step >= minstep );
+ flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
}
- dataend += step*(rows-1) + minstep;
+ step[0] = _step; step[1] = elemSize();
+ dataend += _step*(rows-1) + minstep;
}
-inline Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
+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((uchar*)_data),
+ allocator(0), size(&rows)
{
- flags = m.flags;
- step = m.step; refcount = m.refcount;
- data = m.data; datastart = m.datastart; dataend = m.dataend;
-
- if( rowRange == Range::all() )
- rows = m.rows;
- else
+ size_t minstep = cols*elemSize();
+ if( _step == AUTO_STEP )
{
- CV_Assert( 0 <= rowRange.start && rowRange.start <= rowRange.end && rowRange.end <= m.rows );
- rows = rowRange.size();
- data += step*rowRange.start;
+ _step = minstep;
+ flags |= CONTINUOUS_FLAG;
}
-
- if( colRange == Range::all() )
- cols = m.cols;
else
{
- CV_Assert( 0 <= colRange.start && colRange.start <= colRange.end && colRange.end <= m.cols );
- cols = colRange.size();
- data += colRange.start*elemSize();
- flags &= cols < m.cols ? ~CONTINUOUS_FLAG : -1;
+ if( rows == 1 ) _step = minstep;
+ CV_DbgAssert( _step >= minstep );
+ flags |= _step == minstep ? CONTINUOUS_FLAG : 0;
}
-
- if( rows == 1 )
- flags |= CONTINUOUS_FLAG;
-
- if( refcount )
- CV_XADD(refcount, 1);
- if( rows <= 0 || cols <= 0 )
- rows = cols = 0;
-}
-
-inline Mat::Mat(const Mat& m, const Rect& roi)
- : flags(m.flags), rows(roi.height), cols(roi.width),
- step(m.step), data(m.data + roi.y*step), refcount(m.refcount),
- datastart(m.datastart), dataend(m.dataend)
-{
- flags &= roi.width < m.cols ? ~CONTINUOUS_FLAG : -1;
- data += roi.x*elemSize();
- CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
- 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
- if( refcount )
- CV_XADD(refcount, 1);
- if( rows <= 0 || cols <= 0 )
- rows = cols = 0;
+ step[0] = _step; step[1] = elemSize();
+ dataend += _step*(rows-1) + minstep;
}
+
inline Mat::Mat(const CvMat* m, bool copyData)
: flags(MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG))),
- rows(m->rows), cols(m->cols), step(m->step), data(m->data.ptr), refcount(0),
- datastart(m->data.ptr), dataend(m->data.ptr)
+ dims(2), rows(m->rows), cols(m->cols), data(m->data.ptr), refcount(0),
+ datastart(m->data.ptr), dataend(m->data.ptr),
+ allocator(0), size(&rows)
{
- if( step == 0 )
- step = cols*elemSize();
- size_t minstep = cols*elemSize();
- dataend += step*(rows-1) + minstep;
- if( copyData )
+ if( !copyData )
+ {
+ size_t esz = elemSize(), minstep = cols*esz, _step = m->step;
+ if( _step == 0 )
+ _step = minstep;
+ dataend += _step*(rows-1) + minstep;
+ step[0] = _step; step[1] = esz;
+ }
+ else
{
data = datastart = dataend = 0;
Mat(m->rows, m->cols, m->type, m->data.ptr, m->step).copyTo(*this);
}
}
-CV_EXPORTS Mat cvarrToMat(const CvArr* arr, bool copyData=false,
- bool allowND=true, int coiMode=0);
-
template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- rows(0), cols(0), step(0), data(0), refcount(0),
- datastart(0), dataend(0)
+ 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 )
{
- rows = (int)vec.size();
- cols = 1;
- step = sizeof(_Tp);
+ step[0] = step[1] = sizeof(_Tp);
data = datastart = (uchar*)&vec[0];
- dataend = datastart + rows*step;
+ 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),
- rows(0), cols(0), step(0), data(0), refcount(0),
- datastart(0), dataend(0)
+ dims(2), rows(n), cols(1), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
{
if( !copyData )
{
- rows = n;
- cols = 1;
- step = sizeof(_Tp);
+ step[0] = step[1] = sizeof(_Tp);
data = datastart = (uchar*)vec.val;
- dataend = datastart + rows*step;
+ dataend = datastart + rows*step[0];
}
else
- Mat(n, 1, DataType<_Tp>::type, vec.val).copyTo(*this);
+ 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),
- rows(0), cols(0), step(0), data(0), refcount(0),
- datastart(0), dataend(0)
+ dims(2), rows(m), cols(n), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
{
if( !copyData )
{
- rows = m;
- cols = n;
- step = n*sizeof(_Tp);
+ step[0] = cols*sizeof(_Tp);
+ step[1] = sizeof(_Tp);
data = datastart = (uchar*)M.val;
- dataend = datastart + rows*step;
+ 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)
+template<typename _Tp> inline Mat::Mat(const Point_<_Tp>& pt, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- rows(0), cols(0), step(0), data(0), refcount(0),
- datastart(0), dataend(0)
+ dims(2), rows(2), cols(1), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
{
- create(2, 1, DataType<_Tp>::type);
- ((_Tp*)data)[0] = pt.x;
- ((_Tp*)data)[1] = pt.y;
+ if( !copyData )
+ {
+ step[0] = step[1] = sizeof(_Tp);
+ data = datastart = (uchar*)&pt.x;
+ dataend = datastart + rows*step[0];
+ }
+ else
+ {
+ create(2, 1, DataType<_Tp>::type);
+ ((_Tp*)data)[0] = pt.x;
+ ((_Tp*)data)[1] = pt.y;
+ }
}
-template<typename _Tp> inline Mat::Mat(const Point3_<_Tp>& pt)
+template<typename _Tp> inline Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
- rows(0), cols(0), step(0), data(0), refcount(0),
- datastart(0), dataend(0)
+ dims(2), rows(3), cols(1), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
{
- create(3, 1, DataType<_Tp>::type);
- ((_Tp*)data)[0] = pt.x;
- ((_Tp*)data)[1] = pt.y;
- ((_Tp*)data)[2] = pt.z;
+ if( !copyData )
+ {
+ step[0] = step[1] = sizeof(_Tp);
+ data = datastart = (uchar*)&pt.x;
+ 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),
- rows(0), cols(0), step(0), data(0), refcount(0),
- datastart(0), dataend(0)
+ dims(0), rows(0), cols(0), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
{
*this = *commaInitializer;
}
inline Mat::~Mat()
{
release();
+ if( step.p != step.buf )
+ fastFree(step.p);
}
inline Mat& Mat::operator = (const Mat& m)
CV_XADD(m.refcount, 1);
release();
flags = m.flags;
- rows = m.rows; cols = m.cols;
- step = m.step; data = m.data;
+ 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;
refcount = m.refcount;
+ allocator = m.allocator;
}
return *this;
}
inline Mat Mat::colRange(const Range& r) const
{ return Mat(*this, Range::all(), r); }
-inline Mat Mat::diag(int d) const
-{
- Mat m = *this;
- size_t esz = elemSize();
- int len;
-
- if( d >= 0 )
- {
- len = std::min(cols - d, rows);
- m.data += esz*d;
- }
- else
- {
- len = std::min(rows + d, cols);
- m.data -= step*d;
- }
- CV_DbgAssert( len > 0 );
- m.rows = len;
- m.cols = 1;
- m.step += esz;
- if( m.rows > 1 )
- m.flags &= ~CONTINUOUS_FLAG;
- else
- m.flags |= CONTINUOUS_FLAG;
- return m;
-}
-
inline Mat Mat::diag(const Mat& d)
{
Mat m(d.rows, d.rows, d.type(), Scalar(0)), md = m.diag();
inline void Mat::create(int _rows, int _cols, int _type)
{
_type &= TYPE_MASK;
- if( rows == _rows && cols == _cols && type() == _type && data )
+ if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
return;
- if( data )
- release();
- CV_DbgAssert( _rows >= 0 && _cols >= 0 );
- if( _rows > 0 && _cols > 0 )
- {
- flags = MAGIC_VAL + CONTINUOUS_FLAG + _type;
- rows = _rows;
- cols = _cols;
- step = elemSize()*cols;
- int64 _nettosize = (int64)step*rows;
- size_t nettosize = (size_t)_nettosize;
- if( _nettosize != (int64)nettosize )
- CV_Error(CV_StsNoMem, "Too big buffer is allocated");
- size_t datasize = alignSize(nettosize, (int)sizeof(*refcount));
- datastart = data = (uchar*)fastMalloc(datasize + sizeof(*refcount));
- dataend = data + nettosize;
- refcount = (int*)(data + datasize);
- *refcount = 1;
- }
+ int sz[] = {_rows, _cols};
+ create(2, sz, _type);
}
-inline void Mat::create(Size _size, int _type)
+inline void Mat::create(Size _sz, int _type)
{
- create(_size.height, _size.width, _type);
+ create(_sz.height, _sz.width, _type);
}
inline void Mat::addref()
inline void Mat::release()
{
if( refcount && CV_XADD(refcount, -1) == 1 )
- fastFree(datastart);
+ deallocate();
data = datastart = dataend = 0;
- step = rows = cols = 0;
+ rows = cols = 0;
refcount = 0;
}
-inline void Mat::locateROI( Size& wholeSize, Point& ofs ) const
-{
- size_t esz = elemSize(), minstep;
- ptrdiff_t delta1 = data - datastart, delta2 = dataend - datastart;
- CV_DbgAssert( step > 0 );
- if( delta1 == 0 )
- ofs.x = ofs.y = 0;
- else
- {
- ofs.y = (int)(delta1/step);
- ofs.x = (int)((delta1 - step*ofs.y)/esz);
- CV_DbgAssert( data == datastart + ofs.y*step + ofs.x*esz );
- }
- minstep = (ofs.x + cols)*esz;
- wholeSize.height = (int)((delta2 - minstep)/step + 1);
- wholeSize.height = std::max(wholeSize.height, ofs.y + rows);
- wholeSize.width = (int)((delta2 - step*(wholeSize.height-1))/esz);
- wholeSize.width = std::max(wholeSize.width, ofs.x + cols);
-}
-
-inline Mat& Mat::adjustROI( int dtop, int dbottom, int dleft, int dright )
-{
- Size wholeSize; Point ofs;
- size_t esz = elemSize();
- locateROI( wholeSize, ofs );
- int row1 = std::max(ofs.y - dtop, 0), row2 = std::min(ofs.y + rows + dbottom, wholeSize.height);
- int col1 = std::max(ofs.x - dleft, 0), col2 = std::min(ofs.x + cols + dright, wholeSize.width);
- data += (row1 - ofs.y)*step + (col1 - ofs.x)*esz;
- rows = row2 - row1; cols = col2 - col1;
- if( esz*cols == step || rows == 1 )
- flags |= CONTINUOUS_FLAG;
- else
- flags &= ~CONTINUOUS_FLAG;
- return *this;
-}
-
inline Mat Mat::operator()( Range rowRange, Range colRange ) const
{
return Mat(*this, rowRange, colRange);
}
-
+
inline Mat Mat::operator()( const Rect& roi ) const
{ return Mat(*this, roi); }
+inline Mat Mat::operator()(const Range* ranges) const
+{
+ return Mat(*this, ranges);
+}
+
inline Mat::operator CvMat() const
{
- CvMat m = cvMat(rows, cols, type(), data);
- m.step = (int)step;
+ 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 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() const { return step/elemSize1(); }
-inline Size Mat::size() const { return Size(cols, rows); }
+inline size_t Mat::step1(int i) const { return step.p[i]/elemSize1(); }
inline bool Mat::empty() const { return data == 0; }
+inline size_t Mat::total() const
+{
+ if( dims <= 2 )
+ return 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( (unsigned)y < (unsigned)rows );
- return data + step*y;
+ CV_DbgAssert( data && dims >= 1 && (unsigned)y < (unsigned)size.p[0] );
+ return data + step.p[0]*y;
}
inline const uchar* Mat::ptr(int y) const
{
- CV_DbgAssert( (unsigned)y < (unsigned)rows );
- return data + step*y;
+ CV_DbgAssert( 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( (unsigned)y < (unsigned)rows );
- return (_Tp*)(data + step*y);
+ CV_DbgAssert( data && dims >= 1 && (unsigned)y < (unsigned)size.p[0] );
+ return (_Tp*)(data + step.p[0]*y);
}
template<typename _Tp> inline const _Tp* Mat::ptr(int y) const
{
- CV_DbgAssert( (unsigned)y < (unsigned)rows );
- return (const _Tp*)(data + step*y);
+ CV_DbgAssert( dims >= 1 && data && (unsigned)y < (unsigned)size.p[0] );
+ return (const _Tp*)(data + step.p[0]*y);
}
-template<typename _Tp> inline _Tp& Mat::at(int y, int x)
+
+inline uchar* Mat::ptr(int i0, int i1)
{
- CV_DbgAssert( (unsigned)y < (unsigned)rows &&
- (unsigned)(x*DataType<_Tp>::channels) < (unsigned)(cols*channels()) &&
- CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
- return ((_Tp*)(data + step*y))[x];
+ 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];
}
-template<typename _Tp> inline const _Tp& Mat::at(int y, int x) const
+inline const uchar* Mat::ptr(int i0, int i1) const
{
- CV_DbgAssert( (unsigned)y < (unsigned)rows &&
- (unsigned)(x*DataType<_Tp>::channels) < (unsigned)(cols*channels()) &&
- CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
- return ((const _Tp*)(data + step*y))[x];
+ 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];
}
-template<typename _Tp> inline _Tp& Mat::at(int i)
+inline uchar* Mat::ptr(int i0, int i1, int i2)
{
- CV_DbgAssert( CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1() );
-
- if( cols == 1 )
+ 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];
+}
+
+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)i < (unsigned)rows );
- return *(_Tp*)(data + step*i);
+ CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
+ p += idx[i]*step.p[i];
}
-
- CV_DbgAssert( rows == 1 && (unsigned)(i*DataType<_Tp>::channels) < (unsigned)(cols*channels()) );
- return ((_Tp*)data)[i];
+ return p;
}
-template<typename _Tp> inline const _Tp& Mat::at(int i) const
+inline const uchar* Mat::ptr(const int* idx) const
{
- CV_DbgAssert( CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1() );
-
- if( cols == 1 )
+ int i, d = dims;
+ uchar* p = data;
+ CV_DbgAssert( d >= 1 && p );
+ for( i = 0; i < d; i++ )
{
- CV_DbgAssert( (unsigned)i < (unsigned)rows );
- return *(_Tp*)(data + step*i);
+ CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] );
+ p += idx[i]*step.p[i];
}
+ return p;
+}
- CV_DbgAssert( rows == 1 && (unsigned)(i*DataType<_Tp>::channels) < (unsigned)(cols*channels()) );
- return ((_Tp*)data)[i];
+template<typename _Tp> inline _Tp& Mat::at(int i0, int i1)
+{
+ 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];
+}
+
+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)
{
- CV_DbgAssert( (unsigned)pt.y < (unsigned)rows &&
- (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(cols*channels()) &&
+ 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*pt.y))[pt.x];
+ return ((_Tp*)(data + step.p[0]*pt.y))[pt.x];
}
template<typename _Tp> inline const _Tp& Mat::at(Point pt) const
{
- CV_DbgAssert( (unsigned)pt.y < (unsigned)rows &&
- (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(cols*channels()) &&
+ 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*pt.y))[pt.x];
+ return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
}
+
+template<typename _Tp> inline _Tp& Mat::at(int i0)
+{ return *(_Tp*)ptr(i0); }
+template<typename _Tp> inline const _Tp& Mat::at(int i0) const
+{ return *(const _Tp*)ptr(i0); }
+template<typename _Tp> inline _Tp& Mat::at(int i0, int i1, int i2)
+{ return *(_Tp*)ptr(i0, i1, i2); }
+template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1, int i2) const
+{ return *(const _Tp*)ptr(i0, i1, i2); }
+template<typename _Tp> inline _Tp& Mat::at(const int* idx)
+{ return *(_Tp*)ptr(idx); }
+template<typename _Tp> inline const _Tp& Mat::at(const int* idx) const
+{ return *(const _Tp*)ptr(idx); }
+
template<typename _Tp> inline MatConstIterator_<_Tp> Mat::begin() const
{
{
CV_DbgAssert( elemSize() == sizeof(_Tp) );
MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
- it.ptr = it.sliceEnd = (_Tp*)(data + step*(rows-1)) + cols;
+ it += total();
return it;
}
{
CV_DbgAssert( elemSize() == sizeof(_Tp) );
MatIterator_<_Tp> it((Mat_<_Tp>*)this);
- it.ptr = it.sliceEnd = (_Tp*)(data + step*(rows-1)) + cols;
+ it += total();
return it;
}
-
-static inline void swap( Mat& a, Mat& b )
-{
- std::swap( a.flags, b.flags );
- std::swap( a.rows, b.rows ); std::swap( a.cols, b.cols );
- std::swap( a.step, b.step ); std::swap( a.data, b.data );
- std::swap( a.datastart, b.datastart );
- std::swap( a.dataend, b.dataend );
- std::swap( a.refcount, b.refcount );
-}
-
+
template<typename _Tp> inline Mat::operator vector<_Tp>() const
{
- CV_Assert( (rows == 1 || cols == 1) && channels() == DataType<_Tp>::channels );
-
- int n = rows + cols - 1;
- if( isContinuous() && type() == DataType<_Tp>::type )
- return vector<_Tp>((_Tp*)data,(_Tp*)data + n);
- vector<_Tp> v(n); Mat tmp(rows, cols, DataType<_Tp>::type, &v[0]);
- convertTo(tmp, tmp.type());
+ if( !data )
+ return vector<_Tp>();
+ CV_Assert( dims >= 1 && DataType<_Tp>::channels == channels());
+ vector<_Tp> v(total());
+ Mat temp(dims, size.p, type(), &v[0]);
+ convertTo(temp, DataType<_Tp>::type);
return v;
}
template<typename _Tp, int n> inline Mat::operator Vec<_Tp, n>() const
{
- CV_Assert( (rows == 1 || cols == 1) && rows + cols - 1 == n &&
- channels() == DataType<_Tp>::channels );
+ CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) &&
+ rows + cols - 1 == n && channels() == 1 );
if( isContinuous() && type() == DataType<_Tp>::type )
return Vec<_Tp, n>((_Tp*)data);
template<typename _Tp, int m, int n> inline Mat::operator Matx<_Tp, m, n>() const
{
- CV_Assert( rows == m && cols == n &&
- channels() == DataType<_Tp>::channels );
+ CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 );
if( isContinuous() && type() == DataType<_Tp>::type )
return Matx<_Tp, m, n>((_Tp*)data);
convertTo(tmp, tmp.type());
return mtx;
}
+
+inline Mat::MSize::MSize(int* _p) : p(_p) {}
+inline Size Mat::MSize::operator()() const { return Size(p[1], p[0]); }
+inline 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 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 { return p[0]; }
+inline Mat::MStep& Mat::MStep::operator = (size_t s) { p[0] = s; return *this; }
+
+static inline Mat cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0)
+{
+ return cvarrToMat(arr, copyData, true, coiMode);
+}
inline SVD::SVD() {}
inline SVD::SVD( const Mat& m, int flags ) { operator ()(m, flags); }
///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
-template<typename _Tp> inline Mat_<_Tp>::Mat_() :
- Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; }
+template<typename _Tp> inline Mat_<_Tp>::Mat_()
+ : Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; }
-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)
+ : 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; }
+template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value)
+ : Mat(_rows, _cols, DataType<_Tp>::type) { *this = value; }
-template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _size) :
- Mat(_size.height, _size.width, DataType<_Tp>::type) {}
+template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz)
+ : Mat(_sz.height, _sz.width, DataType<_Tp>::type) {}
+
+template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _sz, const _Tp& value)
+ : Mat(_sz.height, _sz.width, DataType<_Tp>::type) { *this = value; }
+
+template<typename _Tp> inline Mat_<_Tp>::Mat_(int _dims, const int* _sz)
+ : Mat(_dims, _sz, DataType<_Tp>::type) {}
-template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _size, const _Tp& value) :
- Mat(_size.height, _size.width, DataType<_Tp>::type) { *this = value; }
+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& m) : Mat()
-{ flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; *this = m; }
+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; }
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m) : Mat(m) {}
+template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m)
+ : Mat(m) {}
-template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t _step)
- : Mat(_rows, _cols, DataType<_Tp>::type, _data, _step) {}
+template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps)
+ : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps) {}
template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& rowRange, const Range& colRange)
: Mat(m, rowRange, colRange) {}
template<typename _Tp> template<int n> inline
Mat_<_Tp>::Mat_(const Vec<_Tp, n>& vec, bool copyData)
- : Mat(vec, copyData)
-{
-}
+ : Mat(vec, copyData) {}
template<typename _Tp> template<int m, int n> inline
Mat_<_Tp>::Mat_(const Matx<_Tp,m,n>& M, bool copyData)
- : Mat(M, copyData)
-{
-}
+ : Mat(M, copyData) {}
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point_<_Tp>& pt)
- : Mat(2, 1, DataType<_Tp>::type)
-{
- ((_Tp*)data)[0] = pt.x;
- ((_Tp*)data)[1] = pt.y;
-}
-
+template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point_<_Tp>& pt, bool copyData)
+ : Mat(pt, copyData) {}
-template<typename _Tp> inline Mat_<_Tp>::Mat_(const Point3_<_Tp>& pt)
- : Mat(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_<_Tp>::Mat_(const Point3_<_Tp>& pt, bool copyData)
+ : Mat(pt, copyData) {}
template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatCommaInitializer_<_Tp>& commaInitializer)
-: Mat(commaInitializer)
-{
-}
-
+ : Mat(commaInitializer) {}
template<typename _Tp> inline Mat_<_Tp>::Mat_(const vector<_Tp>& vec, bool copyData)
- : Mat(vec, copyData)
-{}
+ : Mat(vec, copyData) {}
template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
{
}
if( DataType<_Tp>::depth == m.depth() )
{
- return (*this = m.reshape(DataType<_Tp>::channels));
+ return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0));
}
CV_DbgAssert(DataType<_Tp>::channels == m.channels());
m.convertTo(*this, type());
Mat::create(_rows, _cols, DataType<_Tp>::type);
}
-template<typename _Tp> inline void Mat_<_Tp>::create(Size _size)
+template<typename _Tp> inline void Mat_<_Tp>::create(Size _sz)
{
- Mat::create(_size, DataType<_Tp>::type);
+ Mat::create(_sz, DataType<_Tp>::type);
}
+template<typename _Tp> inline void Mat_<_Tp>::create(int _dims, const int* _sz)
+{
+ Mat::create(_dims, _sz, DataType<_Tp>::type);
+}
+
+
template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
{ return Mat_<_Tp>(Mat::cross(m)); }
CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
return DataType<_Tp>::channels;
}
-template<typename _Tp> inline size_t Mat_<_Tp>::stepT() const { return step/elemSize(); }
-template<typename _Tp> inline size_t Mat_<_Tp>::step1() const { return step/elemSize1(); }
+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(); }
template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::reshape(int _rows) const
{ return Mat_<_Tp>(Mat::reshape(0,_rows)); }
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); }
+
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); }
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int row, int col)
+template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0, int i1)
{
- CV_DbgAssert( (unsigned)row < (unsigned)rows &&
- (unsigned)col < (unsigned)cols &&
- type() == DataType<_Tp>::type );
- return ((_Tp*)(data + step*row))[col];
+ 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 ()(int row, int col) const
+template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(Point pt) const
{
- CV_DbgAssert( (unsigned)row < (unsigned)rows &&
- (unsigned)col < (unsigned)cols &&
+ 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*row))[col];
+ return ((const _Tp*)(data + step.p[0]*pt.y))[pt.x];
}
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i)
+template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(const int* idx)
{
- return at<_Tp>(i);
+ return Mat::at<_Tp>(idx);
}
-
-template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i) const
+
+template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(const int* idx) const
{
- return at<_Tp>(i);
+ return Mat::at<_Tp>(idx);
}
-
-template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(Point pt)
+
+template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int i0)
{
- CV_DbgAssert( (unsigned)pt.y < (unsigned)rows &&
- (unsigned)pt.x < (unsigned)cols &&
- type() == DataType<_Tp>::type );
- return ((_Tp*)(data + step*pt.y))[pt.x];
+ return this->at<_Tp>(i0);
}
-template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(Point pt) const
+template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int i0) const
{
- CV_DbgAssert( (unsigned)pt.y < (unsigned)rows &&
- (unsigned)pt.x < (unsigned)cols &&
- type() == DataType<_Tp>::type );
- return ((const _Tp*)(data + step*pt.y))[pt.x];
+ return this->at<_Tp>(i0);
+}
+
+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);
+}
+
+
template<typename _Tp> inline Mat_<_Tp>::operator vector<_Tp>() const
{
return this->Mat::operator vector<_Tp>();
{
return this->Mat::operator Matx<_Tp, m, n>();
}
-
template<typename T1, typename T2, typename Op> inline void
process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
static inline void merge(const vector<Mat>& mv, Mat& dst)
{ merge(&mv[0], mv.size(), dst); }
-
-template<typename _Tp> void merge(const Mat_<_Tp>* mvbegin, size_t count, Mat& dst)
-{ merge( (const Mat*)mvbegin, count, dst ); }
static inline void split(const Mat& m, vector<Mat>& mv)
{
//////////// Iterators & Comma initializers //////////////////
-template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_()
- : m(0), ptr(0), sliceEnd(0) {}
+inline MatConstIterator::MatConstIterator()
+ : m(0), elemSize(0), ptr(0), sliceStart(0), sliceEnd(0) {}
-template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m) : m(_m)
+inline MatConstIterator::MatConstIterator(const Mat* _m)
+ : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
{
- if( !_m )
- ptr = sliceEnd = 0;
- else
+ if( m && m->isContinuous() )
{
- ptr = (_Tp*)_m->data;
- sliceEnd = ptr + (_m->isContinuous() ? _m->rows*_m->cols : _m->cols);
+ sliceStart = m->data;
+ sliceEnd = sliceStart + m->total()*elemSize;
}
+ seek((const int*)0);
}
-template<typename _Tp> inline MatConstIterator_<_Tp>::
- MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col) : m(_m)
+inline MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col)
+ : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
{
- if( !_m )
- ptr = sliceEnd = 0;
- else
+ CV_Assert(m && m->dims <= 2);
+ if( m->isContinuous() )
{
- CV_DbgAssert( (unsigned)_row < _m->rows && (unsigned)_col < _m->cols );
- ptr = (_Tp*)(_m->data + _m->step*_row);
- sliceEnd = _m->isContinuous() ? (_Tp*)_m->data + _m->rows*_m->cols : ptr + _m->cols;
- ptr += _col;
+ sliceStart = m->data;
+ sliceEnd = sliceStart + m->total()*elemSize;
}
+ int idx[]={_row, _col};
+ seek(idx);
}
-template<typename _Tp> inline MatConstIterator_<_Tp>::
- MatConstIterator_(const Mat_<_Tp>* _m, Point _pt) : m(_m)
+inline MatConstIterator::MatConstIterator(const Mat* _m, Point _pt)
+ : m(_m), elemSize(_m->elemSize()), ptr(0), sliceStart(0), sliceEnd(0)
{
- if( !_m )
- ptr = sliceEnd = 0;
- else
+ CV_Assert(m && m->dims <= 2);
+ if( m->isContinuous() )
{
- CV_DbgAssert( (unsigned)_pt.y < (unsigned)_m->rows && (unsigned)_pt.x < (unsigned)_m->cols );
- ptr = (_Tp*)(_m->data + _m->step*_pt.y);
- sliceEnd = _m->isContinuous() ? (_Tp*)_m->data + _m->rows*_m->cols : ptr + _m->cols;
- ptr += _pt.x;
+ 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)
+{}
-template<typename _Tp> inline MatConstIterator_<_Tp>::
- MatConstIterator_(const MatConstIterator_& it)
- : m(it.m), ptr(it.ptr), sliceEnd(it.sliceEnd) {}
-
-template<typename _Tp> inline MatConstIterator_<_Tp>&
- MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
+inline MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it )
{
- m = it.m; ptr = it.ptr; sliceEnd = it.sliceEnd;
+ m = it.m; elemSize = it.elemSize; ptr = it.ptr;
+ sliceStart = it.sliceStart; sliceEnd = it.sliceEnd;
return *this;
}
-template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator *() const { return *ptr; }
-
-template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (int ofs)
+inline uchar* MatConstIterator::operator *() const { return ptr; }
+
+inline MatConstIterator& MatConstIterator::operator += (ptrdiff_t ofs)
{
if( !m || ofs == 0 )
return *this;
- ptr += ofs;
- if( m->isContinuous() )
+ ptrdiff_t ofsb = ofs*elemSize;
+ ptr += ofsb;
+ if( ptr < sliceStart || sliceEnd <= ptr )
{
- if( ptr > sliceEnd )
- ptr = sliceEnd;
- else if( ptr < (_Tp*)m->data )
- ptr = (_Tp*)m->data;
- }
- else if( ptr >= sliceEnd || ptr < sliceEnd - m->cols )
- {
- ptr -= ofs;
- Point pt = pos();
- int cols = m->cols;
- ofs += pt.y*cols + pt.x;
- if( ofs >= cols*m->rows )
- {
- ptr = sliceEnd = (_Tp*)(m->data + m->step*(m->rows-1)) + cols;
- return *this;
- }
- else if( ofs < 0 )
- ofs = 0;
- pt.y = ofs/cols;
- pt.x = ofs - pt.y*cols;
- ptr = (_Tp*)(m->data + m->step*pt.y);
- sliceEnd = ptr + cols;
- ptr += pt.x;
+ ptr -= ofsb;
+ seek(ofs, true);
}
return *this;
}
-template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (int ofs)
+inline MatConstIterator& MatConstIterator::operator -= (ptrdiff_t ofs)
{ return (*this += -ofs); }
-template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
-{ return (*this += -1); }
+inline MatConstIterator& MatConstIterator::operator --()
+{
+ if( m && (ptr -= elemSize) < sliceStart )
+ {
+ ptr += elemSize;
+ seek(-1, true);
+ }
+ return *this;
+}
-template<typename _Tp> inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int)
+inline MatConstIterator MatConstIterator::operator --(int)
{
- MatConstIterator_ b = *this;
+ MatConstIterator b = *this;
*this += -1;
return b;
}
-template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
+inline MatConstIterator& MatConstIterator::operator ++()
{
- if( m && ++ptr >= sliceEnd )
+ if( m && (ptr += elemSize) >= sliceEnd )
{
- --ptr;
- *this += 1;
+ ptr -= elemSize;
+ seek(1, true);
}
return *this;
}
-template<typename _Tp> inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int)
+inline MatConstIterator MatConstIterator::operator ++(int)
{
- MatConstIterator_ b = *this;
- if( m && ++ptr >= sliceEnd )
- {
- --ptr;
- *this += 1;
- }
+ MatConstIterator b = *this;
+ *this += 1;
return b;
}
-template<typename _Tp> inline Point MatConstIterator_<_Tp>::pos() const
-{
- if( !m )
- return Point();
- if( m->isContinuous() )
- {
- ptrdiff_t ofs = ptr - (_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);
- }
-}
-
-template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_() : MatConstIterator_<_Tp>() {}
+template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_() {}
-template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
- : MatConstIterator_<_Tp>(_m) {}
+template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m)
+ : MatConstIterator(_m) {}
-template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
- : MatConstIterator_<_Tp>(_m, _row, _col) {}
+template<typename _Tp> inline MatConstIterator_<_Tp>::
+ MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col)
+ : MatConstIterator(_m, _row, _col) {}
-template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, Point _pt)
- : MatConstIterator_<_Tp>(_m, _pt) {}
+template<typename _Tp> inline MatConstIterator_<_Tp>::
+ MatConstIterator_(const Mat_<_Tp>* _m, Point _pt)
+ : MatConstIterator(_m, _pt) {}
-template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
- : MatConstIterator_<_Tp>(it) {}
+template<typename _Tp> inline MatConstIterator_<_Tp>::
+ MatConstIterator_(const MatConstIterator_& it)
+ : MatConstIterator(it) {}
-template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
+template<typename _Tp> inline MatConstIterator_<_Tp>&
+ MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
{
- this->m = it.m; this->ptr = it.ptr; this->sliceEnd = it.sliceEnd;
+ MatConstIterator::operator = (it);
return *this;
}
-template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator *() const { return *(this->ptr); }
+template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator *() const { return *ptr; }
-template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (int ofs)
+template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (ptrdiff_t ofs)
{
- MatConstIterator_<_Tp>::operator += (ofs);
+ MatConstIterator::operator += (ofs);
return *this;
}
-template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (int ofs)
-{
- MatConstIterator_<_Tp>::operator += (-ofs);
+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_<_Tp>::operator += (-1);
+ MatConstIterator::operator --();
return *this;
}
template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
{
MatIterator_ b = *this;
- MatConstIterator_<_Tp>::operator += (-1);
+ MatConstIterator::operator --();
return b;
}
template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
{
- if( this->m && ++this->ptr >= this->sliceEnd )
- {
- --this->ptr;
- MatConstIterator_<_Tp>::operator += (1);
- }
+ MatConstIterator::operator ++();
return *this;
}
template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
{
MatIterator_ b = *this;
- if( this->m && ++this->ptr >= this->sliceEnd )
- {
- --this->ptr;
- MatConstIterator_<_Tp>::operator += (1);
- }
+ MatConstIterator::operator ++();
return b;
}
+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 == 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.ptr < b.ptr; }
+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 MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
-{ return a.ptr > b.ptr; }
+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; }
-template<typename _Tp> static inline bool
-operator <= (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
+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; }
-template<typename _Tp> static inline bool
-operator >= (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
+static inline bool
+operator >= (const MatConstIterator& a, const MatConstIterator& b)
{ return a.ptr >= b.ptr; }
-template<typename _Tp> static inline int
-operator - (const MatConstIterator_<_Tp>& b, const MatConstIterator_<_Tp>& a)
-{
- if( a.m != b.m )
- return INT_MAX;
- if( a.sliceEnd == b.sliceEnd )
- return b.ptr - a.ptr;
- {
- Point ap = a.pos(), bp = b.pos();
- if( bp.y > ap.y )
- return (bp.y - ap.y - 1)*a.m->cols + (a.m->cols - ap.x) + bp.x;
- if( bp.y < ap.y )
- return -((ap.y - bp.y - 1)*a.m->cols + (a.m->cols - bp.x) + ap.x);
- return bp.x - ap.x;
- }
-}
+CV_EXPORTS ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a);
-template<typename _Tp> static inline MatConstIterator_<_Tp>
-operator + (const MatConstIterator_<_Tp>& a, int ofs)
-{ MatConstIterator_<_Tp> b = a; return b += ofs; }
+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 + (int ofs, const MatConstIterator_<_Tp>& a)
-{ MatConstIterator_<_Tp> b = a; return b += ofs; }
+operator + (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
+{ return (MatConstIterator_<_Tp>&)((const MatConstIterator&)a + ofs); }
template<typename _Tp> static inline MatConstIterator_<_Tp>
-operator - (const MatConstIterator_<_Tp>& a, int ofs)
-{ MatConstIterator_<_Tp> b = a; return b += -ofs; }
+operator + (ptrdiff_t ofs, const MatConstIterator_<_Tp>& a)
+{ return (MatConstIterator_<_Tp>&)((const MatConstIterator&)a + ofs); }
+
+template<typename _Tp> static inline MatConstIterator_<_Tp>
+operator - (const MatConstIterator_<_Tp>& a, ptrdiff_t ofs)
+{ return (MatConstIterator_<_Tp>&)((const MatConstIterator&)a - ofs); }
-template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator [](int i) const
+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, int ofs)
-{ MatIterator_<_Tp> b = a; return b += ofs; }
+operator + (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
+{ return (MatIterator_<_Tp>&)((const MatConstIterator&)a + ofs); }
template<typename _Tp> static inline MatIterator_<_Tp>
-operator + (int ofs, const MatIterator_<_Tp>& a)
-{ MatIterator_<_Tp> b = a; return b += ofs; }
+operator + (ptrdiff_t ofs, const MatIterator_<_Tp>& a)
+{ return (MatIterator_<_Tp>&)((const MatConstIterator&)a + ofs); }
template<typename _Tp> static inline MatIterator_<_Tp>
-operator - (const MatIterator_<_Tp>& a, int ofs)
-{ MatIterator_<_Tp> b = a; return b += -ofs; }
-
-template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator [](int i) const
+operator - (const MatIterator_<_Tp>& a, ptrdiff_t ofs)
+{ return (MatIterator_<_Tp>&)((const MatConstIterator&)a - ofs); }
+
+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
template<typename _Tp> template<typename T2> inline MatCommaInitializer_<_Tp>&
MatCommaInitializer_<_Tp>::operator , (T2 v)
{
- CV_DbgAssert( this->it < this->it.m->end() );
+ 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 == this->it.m->end() );
- return *this->it.m;
+ 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 == this->it.m->end() );
- return *this->it.m;
+ CV_DbgAssert( this->it == ((const Mat_<_Tp>*)this->it.m)->end() );
+ return Mat_<_Tp>(*this->it.m);
}
template<typename _Tp> inline void
return (commaInitializer, val);
}
-//////////////////////////////// MatND ////////////////////////////////
-
-inline MatND::MatND()
- : flags(MAGIC_VAL), dims(0), refcount(0), data(0), datastart(0), dataend(0)
-{
-}
-
-inline MatND::MatND(int _dims, const int* _sizes, int _type)
- : flags(MAGIC_VAL), dims(0), refcount(0), data(0), datastart(0), dataend(0)
-{
- create(_dims, _sizes, _type);
-}
-
-inline MatND::MatND(int _dims, const int* _sizes, int _type, const Scalar& _s)
- : flags(MAGIC_VAL), dims(0), refcount(0), data(0), datastart(0), dataend(0)
-{
- create(_dims, _sizes, _type);
- *this = _s;
-}
-
-inline MatND::MatND(const MatND& m)
- : flags(m.flags), dims(m.dims), refcount(m.refcount),
- data(m.data), datastart(m.datastart), dataend(m.dataend)
-{
- int i, d = dims;
- for( i = 0; i < d; i++ )
- {
- size[i] = m.size[i];
- step[i] = m.step[i];
- }
- if( refcount )
- CV_XADD(refcount, 1);
-}
-
-inline MatND::MatND(const Mat& m)
- : flags(m.flags), dims(2), refcount(m.refcount),
- data(m.data), datastart(m.datastart), dataend(m.dataend)
-{
- size[0] = m.rows; size[1] = m.cols;
- step[0] = m.step; step[1] = m.elemSize();
- if( refcount )
- CV_XADD(refcount, 1);
-}
-
-static inline MatND cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0)
-{
- if( CV_IS_MAT(arr) || CV_IS_IMAGE(arr))
- return MatND(cvarrToMat(arr, copyData, true, coiMode));
- else if( CV_IS_MATND(arr) )
- return MatND((const CvMatND*)arr, copyData);
- return MatND();
-}
-
-inline MatND::MatND(const CvMatND* m, bool copyData)
- : flags(MAGIC_VAL|(m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG))),
- dims(m->dims), refcount(0), data(m->data.ptr)
-{
- int i, d = dims;
- for( i = 0; i < d; i++ )
- {
- size[i] = m->dim[i].size;
- step[i] = m->dim[i].step;
- }
- datastart = data;
- dataend = datastart + size[0]*step[0];
- if( copyData )
- {
- MatND temp(*this);
- temp.copyTo(*this);
- }
-}
-
-inline MatND::~MatND() { release(); }
-
-inline MatND& MatND::operator = (const MatND& m)
-{
- if( this != &m )
- {
- if( m.refcount )
- CV_XADD(m.refcount, 1);
- release();
- flags = m.flags;
- dims = m.dims;
- data = m.data;
- datastart = m.datastart;
- dataend = m.dataend;
- refcount = m.refcount;
- int i, d = dims;
- for( i = 0; i < d; i++ )
- {
- size[i] = m.size[i];
- step[i] = m.step[i];
- }
- }
- return *this;
-}
-
-inline MatND MatND::clone() const
-{
- MatND temp;
- this->copyTo(temp);
- return temp;
-}
-
-inline MatND MatND::operator()(const Range* ranges) const
-{
- return MatND(*this, ranges);
-}
-
-inline void MatND::assignTo( MatND& m, int type ) const
-{
- if( type < 0 )
- m = *this;
- else
- convertTo(m, type);
-}
-
-inline void MatND::addref()
-{
- if( refcount ) CV_XADD(refcount, 1);
-}
-
-inline void MatND::release()
-{
- if( refcount && CV_XADD(refcount, -1) == 1 )
- fastFree(datastart);
- dims = 0;
- data = datastart = dataend = 0;
- refcount = 0;
-}
-
-inline bool MatND::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
-inline size_t MatND::elemSize() const { return getElemSize(flags); }
-inline size_t MatND::elemSize1() const { return CV_ELEM_SIZE1(flags); }
-inline int MatND::type() const { return CV_MAT_TYPE(flags); }
-inline int MatND::depth() const { return CV_MAT_DEPTH(flags); }
-inline int MatND::channels() const { return CV_MAT_CN(flags); }
-
-inline size_t MatND::step1(int i) const
-{ CV_DbgAssert((unsigned)i < (unsigned)dims); return step[i]/elemSize1(); }
-
-inline uchar* MatND::ptr(int i0)
-{
- CV_DbgAssert( dims == 1 && data &&
- (unsigned)i0 < (unsigned)size[0] );
- return data + i0*step[0];
-}
-
-inline const uchar* MatND::ptr(int i0) const
-{
- CV_DbgAssert( dims == 1 && data &&
- (unsigned)i0 < (unsigned)size[0] );
- return data + i0*step[0];
-}
-
-inline uchar* MatND::ptr(int i0, int i1)
-{
- CV_DbgAssert( dims == 2 && data &&
- (unsigned)i0 < (unsigned)size[0] &&
- (unsigned)i1 < (unsigned)size[1] );
- return data + i0*step[0] + i1*step[1];
-}
-
-inline const uchar* MatND::ptr(int i0, int i1) const
-{
- CV_DbgAssert( dims == 2 && data &&
- (unsigned)i0 < (unsigned)size[0] &&
- (unsigned)i1 < (unsigned)size[1] );
- return data + i0*step[0] + i1*step[1];
-}
-
-inline uchar* MatND::ptr(int i0, int i1, int i2)
-{
- CV_DbgAssert( dims == 3 && data &&
- (unsigned)i0 < (unsigned)size[0] &&
- (unsigned)i1 < (unsigned)size[1] &&
- (unsigned)i2 < (unsigned)size[2] );
- return data + i0*step[0] + i1*step[1] + i2*step[2];
-}
-
-inline const uchar* MatND::ptr(int i0, int i1, int i2) const
-{
- CV_DbgAssert( dims == 3 && data &&
- (unsigned)i0 < (unsigned)size[0] &&
- (unsigned)i1 < (unsigned)size[1] &&
- (unsigned)i2 < (unsigned)size[2] );
- return data + i0*step[0] + i1*step[1] + i2*step[2];
-}
-
-inline uchar* MatND::ptr(const int* idx)
-{
- int i, d = dims;
- uchar* p = data;
- CV_DbgAssert( data );
- for( i = 0; i < d; i++ )
- {
- CV_DbgAssert( (unsigned)idx[i] < (unsigned)size[i] );
- p += idx[i]*step[i];
- }
- return p;
-}
-
-inline const uchar* MatND::ptr(const int* idx) const
-{
- int i, d = dims;
- uchar* p = data;
- CV_DbgAssert( data );
- for( i = 0; i < d; i++ )
- {
- CV_DbgAssert( (unsigned)idx[i] < (unsigned)size[i] );
- p += idx[i]*step[i];
- }
- return p;
-}
-
-template<typename _Tp> inline _Tp& MatND::at(int i0)
-{ return *(_Tp*)ptr(i0); }
-template<typename _Tp> inline const _Tp& MatND::at(int i0) const
-{ return *(const _Tp*)ptr(i0); }
-template<typename _Tp> inline _Tp& MatND::at(int i0, int i1)
-{ return *(_Tp*)ptr(i0, i1); }
-template<typename _Tp> inline const _Tp& MatND::at(int i0, int i1) const
-{ return *(const _Tp*)ptr(i0, i1); }
-template<typename _Tp> inline _Tp& MatND::at(int i0, int i1, int i2)
-{ return *(_Tp*)ptr(i0, i1, i2); }
-template<typename _Tp> inline const _Tp& MatND::at(int i0, int i1, int i2) const
-{ return *(const _Tp*)ptr(i0, i1, i2); }
-template<typename _Tp> inline _Tp& MatND::at(const int* idx)
-{ return *(_Tp*)ptr(idx); }
-template<typename _Tp> inline const _Tp& MatND::at(const int* idx) const
-{ return *(const _Tp*)ptr(idx); }
-
-inline NAryMatNDIterator::NAryMatNDIterator()
-{
-}
-
-inline void subtract(const MatND& a, const Scalar& s, MatND& c, const MatND& mask=MatND())
-{
- add(a, -s, c, mask);
-}
-
-
-template<typename _Tp> inline MatND_<_Tp>::MatND_()
-{
- flags = MAGIC_VAL | DataType<_Tp>::type;
-}
-
-template<typename _Tp> inline MatND_<_Tp>::MatND_(int _dims, const int* _sizes)
-: MatND(_dims, _sizes, DataType<_Tp>::type)
-{
-}
-
-template<typename _Tp> inline MatND_<_Tp>::MatND_(int _dims, const int* _sizes, const _Tp& _s)
-: MatND(_dims, _sizes, DataType<_Tp>::type, Scalar(_s))
-{
-}
-
-template<typename _Tp> inline MatND_<_Tp>::MatND_(const MatND& m)
-{
- if( m.type() == DataType<_Tp>::type )
- *this = (const MatND_<_Tp>&)m;
- else
- m.convertTo(this, DataType<_Tp>::type);
-}
-
-template<typename _Tp> inline MatND_<_Tp>::MatND_(const MatND_<_Tp>& m) : MatND(m)
-{
-}
-
-template<typename _Tp> inline MatND_<_Tp>::MatND_(const MatND_<_Tp>& m, const Range* ranges)
-: MatND(m, ranges)
-{
-}
-
-template<typename _Tp> inline MatND_<_Tp>::MatND_(const CvMatND* m, bool copyData)
-{
- *this = MatND(m, copyData || CV_MAT_TYPE(m->type) != DataType<_Tp>::type);
-}
-
-template<typename _Tp> inline MatND_<_Tp>& MatND_<_Tp>::operator = (const MatND& 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));
- }
- CV_DbgAssert(DataType<_Tp>::channels == m.channels());
- m.convertTo(*this, DataType<_Tp>::type);
- return *this;
-}
-
-template<typename _Tp> inline MatND_<_Tp>& MatND_<_Tp>::operator = (const MatND_<_Tp>& m)
-{
- return ((MatND&)*this = m);
-}
-
-template<typename _Tp> inline MatND_<_Tp>& MatND_<_Tp>::operator = (const _Tp& s)
-{
- return (MatND&)*this = Scalar(s);
-}
-
-template<typename _Tp> inline void MatND_<_Tp>::create(int _dims, const int* _sizes)
-{
- MatND::create(_dims, _sizes, DataType<_Tp>::type);
-}
-
-template<typename _Tp> template<typename _Tp2> inline MatND_<_Tp>::operator MatND_<_Tp2>() const
-{
- return MatND_<_Tp2>((const MatND&)*this);
-}
-
-template<typename _Tp> inline MatND_<_Tp> MatND_<_Tp>::clone() const
-{
- MatND_<_Tp> temp;
- this->copyTo(temp);
- return temp;
-}
-
-template<typename _Tp> inline MatND_<_Tp>
-MatND_<_Tp>::operator()(const Range* ranges) const
-{ return MatND_<_Tp>(*this, ranges); }
-
-template<typename _Tp> inline size_t MatND_<_Tp>::elemSize() const
-{ return CV_ELEM_SIZE(DataType<_Tp>::type); }
-
-template<typename _Tp> inline size_t MatND_<_Tp>::elemSize1() const
-{ return CV_ELEM_SIZE1(DataType<_Tp>::type); }
-
-template<typename _Tp> inline int MatND_<_Tp>::type() const
-{ return DataType<_Tp>::type; }
-
-template<typename _Tp> inline int MatND_<_Tp>::depth() const
-{ return DataType<_Tp>::depth; }
-
-template<typename _Tp> inline int MatND_<_Tp>::channels() const
-{ return DataType<_Tp>::channels; }
-
-template<typename _Tp> inline size_t MatND_<_Tp>::stepT(int i) const
-{
- CV_DbgAssert( (unsigned)i < (unsigned)dims );
- return step[i]/elemSize();
-}
-
-template<typename _Tp> inline size_t MatND_<_Tp>::step1(int i) const
-{
- CV_DbgAssert( (unsigned)i < (unsigned)dims );
- return step[i]/elemSize1();
-}
-
-template<typename _Tp> inline _Tp& MatND_<_Tp>::operator ()(const int* idx)
-{
- uchar* ptr = data;
- int i, d = dims;
- for( i = 0; i < d; i++ )
- {
- int ii = idx[i];
- CV_DbgAssert( (unsigned)ii < (unsigned)size[i] );
- ptr += ii*step[i];
- }
- return *(_Tp*)ptr;
-}
-
-template<typename _Tp> inline const _Tp& MatND_<_Tp>::operator ()(const int* idx) const
-{
- const uchar* ptr = data;
- int i, d = dims;
- for( i = 0; i < d; i++ )
- {
- int ii = idx[i];
- CV_DbgAssert( (unsigned)ii < (unsigned)size[i] );
- ptr += ii*step[i];
- }
- return *(const _Tp*)ptr;
-}
-
-template<typename _Tp> inline _Tp& MatND_<_Tp>::operator ()(int i0)
-{
- CV_DbgAssert( dims == 1 &&
- (unsigned)i0 < (unsigned)size[0] );
-
- return *(_Tp*)(data + i0*step[0]);
-}
-
-template<typename _Tp> inline const _Tp& MatND_<_Tp>::operator ()(int i0) const
-{
- CV_DbgAssert( dims == 1 &&
- (unsigned)i0 < (unsigned)size[0] );
-
- return *(const _Tp*)(data + i0*step[0]);
-}
-
-
-template<typename _Tp> inline _Tp& MatND_<_Tp>::operator ()(int i0, int i1)
-{
- CV_DbgAssert( dims == 2 &&
- (unsigned)i0 < (unsigned)size[0] &&
- (unsigned)i1 < (unsigned)size[1] );
-
- return *(_Tp*)(data + i0*step[0] + i1*step[1]);
-}
-
-template<typename _Tp> inline const _Tp& MatND_<_Tp>::operator ()(int i0, int i1) const
-{
- CV_DbgAssert( dims == 2 &&
- (unsigned)i0 < (unsigned)size[0] &&
- (unsigned)i1 < (unsigned)size[1] );
-
- return *(const _Tp*)(data + i0*step[0] + i1*step[1]);
-}
-
-
-template<typename _Tp> inline _Tp& MatND_<_Tp>::operator ()(int i0, int i1, int i2)
-{
- CV_DbgAssert( dims == 3 &&
- (unsigned)i0 < (unsigned)size[0] &&
- (unsigned)i1 < (unsigned)size[1] &&
- (unsigned)i2 < (unsigned)size[2] );
-
- return *(_Tp*)(data + i0*step[0] + i1*step[1] + i2*step[2]);
-}
-
-template<typename _Tp> inline const _Tp& MatND_<_Tp>::operator ()(int i0, int i1, int i2) const
-{
- CV_DbgAssert( dims == 3 &&
- (unsigned)i0 < (unsigned)size[0] &&
- (unsigned)i1 < (unsigned)size[1] &&
- (unsigned)i2 < (unsigned)size[2] );
-
- return *(const _Tp*)(data + i0*step[0] + i1*step[1] + i2*step[2]);
-}
-
-
-static inline void merge(const vector<MatND>& mv, MatND& dst)
-{
- merge(&mv[0], mv.size(), dst);
-}
-
-static inline void split(const MatND& m, vector<MatND>& mv)
-{
- mv.resize(m.channels());
- if(m.channels() > 0)
- split(m, &mv[0]);
-}
-
-static inline void mixChannels(const vector<MatND>& src, vector<MatND>& dst,
- const int* fromTo, int npairs)
-{
- mixChannels(&src[0], (int)src.size(), &dst[0], (int)dst.size(), fromTo, npairs);
-}
-
//////////////////////////////// SparseMat ////////////////////////////////
inline SparseMat::SparseMat()
inline SparseMat& SparseMat::operator = (const Mat& m)
{ return (*this = SparseMat(m)); }
-inline SparseMat& SparseMat::operator = (const MatND& m)
-{ return (*this = SparseMat(m)); }
-
inline SparseMat SparseMat::clone() const
{
SparseMat temp;
*this = sm;
}
-template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const MatND& m)
-{
- SparseMat sm(m);
- *this = sm;
-}
-
template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const CvSparseMat* m)
{
SparseMat sm(m);
SparseMat_<_Tp>::operator = (const Mat& m)
{ return (*this = SparseMat(m)); }
-template<typename _Tp> inline SparseMat_<_Tp>&
-SparseMat_<_Tp>::operator = (const MatND& m)
-{ return (*this = SparseMat(m)); }
-
template<typename _Tp> inline SparseMat_<_Tp>
SparseMat_<_Tp>::clone() const
{
}
CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat=Mat() );
-CV_EXPORTS void read(const FileNode& node, MatND& mat, const MatND& default_mat=MatND() );
CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat=SparseMat() );
inline FileNode::operator int() const
typedef signed char schar;
+/* special informative macros for wrapper generators */
+#define CV_OUT
+#define CV_CARRAY(counter)
+#define CV_METHOD
+
/* CvArr* is used to pass arbitrary
* array-like data structures
* into functions where the particular
}
}
+
+static void
+binaryOp( const Mat& src1, const Mat& src2, Mat& dst, BinaryFunc func, int dsttype=-1 )
+{
+ if( dsttype == -1 )
+ dsttype = src1.type();
+ CV_Assert( src1.type() == src2.type() && func != 0 );
+
+ if( src1.dims > 2 || src2.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, dsttype);
+ const Mat* arrays[] = { &src1, &src2, &dst, 0 };
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func(it.planes[0], it.planes[1], it.planes[2]);
+ return;
+ }
+
+ CV_Assert( src1.size() == src2.size() );
+ dst.create( src1.size(), dsttype );
+ func( src1, src2, dst );
+}
+
+
static void
binaryMaskOp( const Mat& src1, const Mat& src2, Mat& dst,
const Mat& mask, BinaryFunc func )
{
- CV_Assert( src1.size() == src2.size() && src1.type() == src2.type() && func != 0 );
+ CV_Assert( src1.type() == src2.type() && func != 0 );
+
+ if( src1.dims > 2 || src2.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, src1.type());
+ const Mat* arrays[] = { &src1, &src2, &dst, &mask, 0 };
+ Mat planes[4];
+ NAryMatIterator it(arrays, planes);
+
+ if( !mask.data )
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func(it.planes[0], it.planes[1], it.planes[2]);
+ else
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ binaryMaskOp(it.planes[0], it.planes[1],
+ it.planes[2], it.planes[3],
+ func);
+ return;
+ }
+
+ CV_Assert( src1.size() == src2.size() );
dst.create( src1.size(), src1.type() );
if( !mask.data )
const Mat& mask, BinarySFuncCn func )
{
CV_Assert( func != 0 );
+
+ if( src1.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, src1.type());
+ const Mat* arrays[] = { &src1, &dst, &mask, 0 };
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ if( !mask.data )
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func(it.planes[0], it.planes[1], s);
+ else
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ binarySMaskOp(it.planes[0], s, it.planes[1],
+ it.planes[2], func);
+ return;
+ }
+
dst.create( src1.size(), src1.type() );
if( !mask.data )
void bitwise_not(const Mat& src, Mat& dst)
{
+ if( src.dims > 2 )
+ {
+ dst.create(src.dims, src.size, src.type());
+ const Mat* arrays[] = { &src, &dst, 0 };
+ Mat planes[4];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ bitwise_not(it.planes[0], it.planes[1]);
+ return;
+ }
+
const uchar* sptr = src.data;
dst.create( src.size(), src.type() );
uchar* dptr = dst.data;
binaryOpC1_<OpSub<double>,NoVec>, 0
};
-
void add( const Mat& src1, const Mat& src2, Mat& dst )
{
- Size size = src1.size(); int type = src1.type();
+ int type = src1.type();
BinaryFunc func = addTab[CV_MAT_DEPTH(type)];
- CV_Assert( size == src2.size() && type == src2.type() && func != 0 );
+ CV_Assert( type == src2.type() && func != 0 );
+
+ if( src1.dims > 2 || src2.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, src1.type());
+ const Mat* arrays[] = {&src1, &src2, &dst, 0};
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( it.planes[0], it.planes[1], it.planes[2] );
+ return;
+ }
+
+ Size size = src1.size();
+ CV_Assert( size == src2.size() );
dst.create( size, type );
func(src1, src2, dst);
}
void subtract( const Mat& src1, const Mat& src2, Mat& dst )
{
- Size size = src1.size(); int type = src1.type();
+ int type = src1.type();
BinaryFunc func = subTab[CV_MAT_DEPTH(type)];
- CV_Assert( size == src2.size() && type == src2.type() && func != 0 );
+ CV_Assert( type == src2.type() && func != 0 );
+
+ if( src1.dims > 2 || src2.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, src1.type());
+ const Mat* arrays[] = {&src1, &src2, &dst, 0};
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( it.planes[0], it.planes[1], it.planes[2] );
+ return;
+ }
+
+ Size size = src1.size();
+ CV_Assert( size == src2.size() );
dst.create( size, type );
func(src1, src2, dst);
}
};
MulDivFunc func = tab[src1.depth()];
- CV_Assert( src1.size() == src2.size() && src1.type() == src2.type() && func != 0 );
+ CV_Assert( src1.type() == src2.type() && func != 0 );
+
+ if( src1.dims > 2 || src2.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, src1.type());
+ const Mat* arrays[] = {&src1, &src2, &dst, 0};
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( it.planes[0], it.planes[1], it.planes[2], scale );
+ return;
+ }
+
+ CV_Assert( src1.size() == src2.size() );
dst.create( src1.size(), src1.type() );
func( src1, src2, dst, scale );
}
MulDivFunc func = tab[src1.depth()];
CV_Assert( src1.size() == src2.size() && src1.type() == src2.type() && func != 0 );
+
+ if( src1.dims > 2 || src2.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, src1.type());
+ const Mat* arrays[] = {&src1, &src2, &dst, 0};
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( it.planes[0], it.planes[1], it.planes[2], scale );
+ return;
+ }
+
+ CV_Assert( src1.size() == src2.size() );
dst.create( src1.size(), src1.type() );
func( src1, src2, dst, scale );
}
RecipFunc func = tab[src.depth()];
CV_Assert( func != 0 );
+
+ if( src.dims > 2 )
+ {
+ dst.create(src.dims, src.size, src.type());
+ const Mat* arrays[] = {&src, &dst, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( scale, it.planes[0], it.planes[1] );
+ return;
+ }
+
dst.create( src.size(), src.type() );
func( scale, src, dst );
}
};
AddWeightedFunc func = tab[src1.depth()];
- CV_Assert( src1.size() == src2.size() && src1.type() == src2.type() && func != 0 );
+ CV_Assert( src1.type() == src2.type() && func != 0 );
+
+ if( src1.dims > 2 || src2.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, src1.type());
+ const Mat* arrays[] = {&src1, &src2, &dst, 0};
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( it.planes[0], alpha, it.planes[1], beta, gamma, it.planes[2] );
+ return;
+ }
+
+ CV_Assert( src1.size() == src2.size() );
dst.create( src1.size(), src1.type() );
func( src1, alpha, src2, beta, gamma, dst );
}
binaryOpC1_<OpAbsDiff<double>,NoVec>, 0
};
- dst.create(src1.size(), src1.type());
- BinaryFunc func = tab[src1.depth()];
- CV_Assert(src1.size() == src2.size() && src1.type() == src2.type() && func != 0);
- func( src1, src2, dst );
+ binaryOp(src1, src2, dst, tab[src1.depth()]);
}
binarySOpCn_<OpAbsDiffS<double> >, 0
};
- dst.create(src1.size(), src1.type());
BinarySFuncCn func = tab[src1.depth()];
CV_Assert(src1.channels() <= 4 && func != 0);
+
+ if( src1.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, src1.type());
+ const Mat* arrays[] = {&src1, &dst, 0};
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( it.planes[0], it.planes[1], s );
+ return;
+ }
+
+ dst.create(src1.size(), src1.type());
func( src1, dst, s );
}
inRange_<InRangeC4<double, double> >, 0
};
- CV_Assert( src.size() == lowerb.size() && src.size() == upperb.size() &&
- src.type() == lowerb.type() && src.type() == upperb.type() &&
- src.channels() <= 4 );
+ CV_Assert( src.type() == lowerb.type() && src.type() == upperb.type() && src.channels() <= 4 );
InRangeFunc func = tab[src.type()];
CV_Assert( func != 0 );
+ if( src.dims > 2 || lowerb.dims > 2 || upperb.dims > 2 )
+ {
+ dst.create(src.dims, src.size, CV_8U);
+ const Mat* arrays[] = {&src, &lowerb, &upperb, &dst, 0};
+ Mat planes[4];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( it.planes[0], it.planes[1], it.planes[2], it.planes[3] );
+ return;
+ }
+
+ CV_Assert( src.size() == lowerb.size() && src.size() == upperb.size() );
dst.create(src.size(), CV_8U);
func( src, lowerb, upperb, dst );
}
InRangeSFunc func = tab[src.type()];
CV_Assert( func != 0 );
+
+ if( src.dims > 2 )
+ {
+ dst.create(src.dims, src.size, CV_8U);
+ const Mat* arrays[] = {&src, &dst, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( it.planes[0], lowerb, upperb, it.planes[1] );
+ return;
+ }
dst.create(src.size(), CV_8U);
func( src, lowerb, upperb, dst );
binaryOpC1_<CmpEQ<double>,NoVec>, 0},
};
- dst.create(src1.rows, src1.cols, CV_8U);
- CV_Assert(src1.size() == src2.size() && src1.type() == src2.type() && src1.channels() == 1);
+ CV_Assert(src1.channels() == 1);
int depth = src1.depth();
const Mat *psrc1 = &src1, *psrc2 = &src2;
}
BinaryFunc func = tab[cmpOp == CMP_EQ][depth];
- CV_Assert( func != 0 );
- func( *psrc1, *psrc2, dst );
+ binaryOp(*psrc1, *psrc2, dst, func, CV_8U);
if( invflag )
bitwise_not(dst, dst);
}
BinarySFuncC1 func = tab[cmpOp == CMP_EQ ? 0 : cmpOp == CMP_GT ? 1 : 2][depth];
CV_Assert( func != 0 );
+
+ if( src1.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, CV_8U);
+ const Mat* arrays[] = {&src1, &dst, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ {
+ func( it.planes[0], it.planes[1], value );
+ if( invflag )
+ bitwise_not(it.planes[2], it.planes[2]);
+ }
+ return;
+ }
+
func( src1, dst, value );
if( invflag )
bitwise_not(dst, dst);
binaryOpC1_<MinOp<float>,VMin32f>, binaryOpC1_<MinOp<double>,NoVec>, 0
};
- BinaryFunc func = tab[src1.depth()];
- CV_Assert(src1.size() == src2.size() && src1.type() == src2.type() && func != 0);
- dst.create(src1.size(), src1.type());
-
- return func( src1, src2, dst );
+ binaryOp(src1, src2, dst, tab[src1.depth()]);
}
void max( const Mat& src1, const Mat& src2, Mat& dst )
binaryOpC1_<MaxOp<float>,VMax32f>, binaryOpC1_<MaxOp<double>,NoVec>, 0
};
- BinaryFunc func = tab[src1.depth()];
- CV_Assert(src1.size() == src2.size() && src1.type() == src2.type() && func != 0);
- dst.create(src1.size(), src1.type());
-
- return func( src1, src2, dst );
+ binaryOp(src1, src2, dst, tab[src1.depth()]);
}
void min( const Mat& src1, double value, Mat& dst )
BinarySFuncC1 func = tab[src1.depth()];
CV_Assert(func != 0);
+
+ if( src1.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, src1.type());
+ const Mat* arrays[] = {&src1, &dst, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( it.planes[0], it.planes[1], value );
+ return;
+ }
+
dst.create(src1.size(), src1.type());
return func( src1, dst, value );
}
BinarySFuncC1 func = tab[src1.depth()];
CV_Assert(func != 0);
+
+ if( src1.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, src1.type());
+ const Mat* arrays[] = {&src1, &dst, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( it.planes[0], it.planes[1], value );
+ return;
+ }
+
dst.create(src1.size(), src1.type());
return func( src1, dst, value );
}
};
int i, depth = src.depth(), cn = src.channels();
- Size size = src.size();
if( cn == 1 )
{
}
for( i = 0; i < cn; i++ )
- mv[i].create(src.size(), depth);
+ mv[i].create(src.dims, src.size, depth);
if( cn <= 4 )
{
SplitFunc func = tab[(cn-2)*5 + (src.elemSize1()>>1)];
CV_Assert( func != 0 );
- func( src, mv );
+
+ if( src.dims > 2 )
+ {
+ const Mat* arrays[5];
+ Mat planes[5];
+ arrays[0] = &src;
+ for( i = 0; i < cn; i++ )
+ arrays[i+1] = &mv[i];
+ NAryMatIterator it(arrays, planes, cn+1);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( it.planes[0], &it.planes[1] );
+ }
+ else
+ func( src, mv );
}
else
{
- vector<int> pairs(cn*2);
+ AutoBuffer<int> pairs(cn*2);
for( i = 0; i < cn; i++ )
{
typedef void (*MergeFunc)(const Mat* src, Mat& dst);
-void merge(const Mat* mv, size_t n, Mat& dst)
+void merge(const Mat* mv, size_t _n, Mat& dst)
{
static MergeFunc tab[] =
{
mergeC4_<uchar>, mergeC4_<ushort>, mergeC4_<int>, 0, mergeC4_<int64>
};
- size_t i;
- CV_Assert( mv && n > 0 );
+ CV_Assert( mv && _n > 0 );
int depth = mv[0].depth();
bool allch1 = true;
- int total = 0;
+ int i, total = 0, n = (int)_n;
- Size size = mv[0].size();
-
for( i = 0; i < n; i++ )
{
- CV_Assert(mv[i].size() == size && mv[i].depth() == depth);
+ CV_Assert(mv[i].size == mv[0].size && mv[i].depth() == depth);
allch1 = allch1 && mv[i].channels() == 1;
total += mv[i].channels();
}
return;
}
- dst.create(size, CV_MAKETYPE(depth, total));
+ dst.create(mv[0].dims, mv[0].size, CV_MAKETYPE(depth, total));
if( allch1 && total <= 4 )
{
MergeFunc func = tab[(total-2)*5 + (CV_ELEM_SIZE(depth)>>1)];
CV_Assert( func != 0 );
- func( mv, dst );
+ if( mv[0].dims > 2 )
+ {
+ const Mat* arrays[5];
+ Mat planes[5];
+ arrays[total] = &dst;
+ for( i = 0; i < total; i++ )
+ arrays[i] = &mv[i];
+ NAryMatIterator it(arrays, planes, total+1);
+
+ for( i = 0; i < it.nplanes; i++, ++it )
+ func( &it.planes[0], it.planes[total] );
+ }
+ else
+ func( mv, dst );
}
else
{
- vector<int> pairs(total*2);
+ AutoBuffer<int> pairs(total*2);
int j, k, ni=0;
for( i = 0, j = 0; i < n; i++, j += ni )
void mixChannels( const Mat* src, size_t nsrcs, Mat* dst, size_t ndsts, const int* fromTo, size_t npairs )
{
- size_t i, j;
-
if( npairs == 0 )
return;
CV_Assert( src && nsrcs > 0 && dst && ndsts > 0 && fromTo && npairs > 0 );
-
+
+ if( src[0].dims > 2 )
+ {
+ size_t k, m = nsrcs, n = ndsts;
+ CV_Assert( n > 0 && m > 0 );
+ AutoBuffer<const Mat*> v(m + n);
+ AutoBuffer<Mat> planes(m + n);
+ for( k = 0; k < m; k++ )
+ v[k] = &src[k];
+ for( k = 0; k < n; k++ )
+ v[m + k] = &dst[k];
+ NAryMatIterator it(v, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ mixChannels( &it.planes[0], m, &it.planes[m], n, fromTo, npairs );
+ return;
+ }
+
+ size_t i, j;
int depth = dst[0].depth(), esz1 = (int)dst[0].elemSize1();
Size size = dst[0].size();
Mat temp;
const Mat* psrc = this;
- if( sdepth != ddepth && psrc == &dst )
+ if( sdepth != ddepth && data == dst.data )
psrc = &(temp = *this);
- dst.create( size(), _type );
+ CvtFunc func = 0;
+ CvtScaleFunc scaleFunc = 0;
+
if( noScale )
{
- CvtFunc func = tab[sdepth][ddepth];
+ func = tab[sdepth][ddepth];
CV_Assert( func != 0 );
- func( *psrc, dst );
}
else
{
- CvtScaleFunc func = stab[sdepth][ddepth];
- CV_Assert( func != 0 );
- func( *psrc, dst, alpha, beta );
+ scaleFunc = stab[sdepth][ddepth];
+ CV_Assert( scaleFunc != 0 );
}
+
+ if( dims <= 2 )
+ {
+ dst.create( size(), _type );
+ if( func )
+ func( *psrc, dst );
+ else
+ scaleFunc( *psrc, dst, alpha, beta );
+ }
+ else
+ {
+ dst.create( dims, size, _type );
+ const Mat* arrays[] = {psrc, &dst, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ {
+ if( func )
+ func(it.planes[0], it.planes[1]);
+ else
+ scaleFunc(it.planes[0], it.planes[1], alpha, beta);
+ }
+ }
}
/****************************************************************************************\
{
if( data == dst.data )
return;
-
+
+ if( dims > 2 )
+ {
+ dst.create( dims, size, type() );
+ const Mat* arrays[] = { this, &dst, 0 };
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+ CV_DbgAssert(it.planes[0].isContinuous() &&
+ it.planes[1].isContinuous());
+ size_t planeSize = it.planes[0].elemSize()*it.planes[0].rows*it.planes[0].cols;
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ memcpy(it.planes[1].data, it.planes[0].data, planeSize);
+ return;
+ }
+
dst.create( rows, cols, type() );
Size sz = size();
const uchar* sptr = data;
copyTo(dst);
return;
}
+
+ if( dims > 2 )
+ {
+ dst.create( dims, size, type() );
+ const Mat* arrays[] = { this, &dst, &mask, 0 };
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ it.planes[0].copyTo(it.planes[1], it.planes[2]);
+ return;
+ }
uchar* data0 = dst.data;
dst.create( size(), type() );
Mat& Mat::operator = (const Scalar& s)
{
+ if( dims > 2 )
+ {
+ const Mat* arrays[] = { this, 0 };
+ Mat planes[1];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ it.planes[0] = s;
+ return *this;
+ }
+
Size sz = size();
uchar* dst = data;
CV_Assert( func != 0 );
double buf[4];
scalarToRawData(s, buf, type(), 0);
- func(buf, *this, mask);
+
+ if( dims > 2 )
+ {
+ const Mat* arrays[] = { this, &mask, 0 };
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func(buf, it.planes[0], it.planes[1]);
+ }
+ else
+ func(buf, *this, mask);
}
return *this;
}
flipHoriz_<Vec<int64,4> > // 32
};
+ CV_Assert( src.dims <= 2 );
dst.create( src.size(), src.type() );
if( flip_mode == 0 )
void repeat(const Mat& src, int ny, int nx, Mat& dst)
{
+ CV_Assert( src.dims <= 2 );
+
dst.create(src.rows*ny, src.cols*nx, src.type());
Size ssize = src.size(), dsize = dst.size();
int esz = (int)src.elemSize();
void magnitude( const Mat& X, const Mat& Y, Mat& Mag )
{
- int type = X.type(), depth = X.depth(), cn = X.channels();
+ if( X.dims > 2 )
+ {
+ Mag.create(X.dims, X.size, X.type());
+ const Mat* arrays[] = {&X, &Y, &Mag, 0};
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ magnitude( it.planes[0], it.planes[1], it.planes[2] );
+ return;
+ }
+
+ int type = X.type(), depth = X.depth(), cn = X.channels();
CV_Assert( X.size() == Y.size() && type == Y.type() && (depth == CV_32F || depth == CV_64F));
Mag.create( X.size(), type );
void phase( const Mat& X, const Mat& Y, Mat& Angle, bool angleInDegrees )
{
+ if( X.dims > 2 )
+ {
+ Angle.create(X.dims, X.size, X.type());
+ const Mat* arrays[] = {&X, &Y, &Angle, 0};
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ phase( it.planes[0], it.planes[1], it.planes[2], angleInDegrees );
+ return;
+ }
+
float buf[2][MAX_BLOCK_SIZE];
int i, j, type = X.type(), depth = X.depth(), cn = X.channels();
void cartToPolar( const Mat& X, const Mat& Y, Mat& Mag, Mat& Angle, bool angleInDegrees )
{
+ if( X.dims > 2 )
+ {
+ Mag.create(X.dims, X.size, X.type());
+ Angle.create(X.dims, X.size, X.type());
+ const Mat* arrays[] = {&X, &Y, &Mag, &Angle, 0};
+ Mat planes[4];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ cartToPolar( it.planes[0], it.planes[1], it.planes[2], it.planes[2], angleInDegrees );
+ return;
+ }
+
float buf[2][MAX_BLOCK_SIZE];
int i, j, type = X.type(), depth = X.depth(), cn = X.channels();
void polarToCart( const Mat& Mag, const Mat& Angle, Mat& X, Mat& Y, bool angleInDegrees )
{
+ if( Mag.dims > 2 )
+ {
+ X.create(Mag.dims, Mag.size, Mag.type());
+ Y.create(Mag.dims, Mag.size, Mag.type());
+ const Mat* arrays[] = {&Mag, &Angle, &X, &Y, 0};
+ Mat planes[4];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ polarToCart( it.planes[0], it.planes[1], it.planes[2], it.planes[2], angleInDegrees );
+ return;
+ }
+
int i, j, type = Angle.type(), depth = Angle.depth();
Size size;
void exp( const Mat& src, Mat& dst )
{
+ if( src.dims > 2 )
+ {
+ dst.create(src.dims, src.size, src.type());
+ const Mat* arrays[] = {&src, &dst, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ exp( it.planes[0], it.planes[1] );
+ return;
+ }
+
int depth = src.depth();
dst.create( src.size(), src.type() );
Size size = getContinuousSize( src, dst, src.channels() );
void log( const Mat& src, Mat& dst )
{
+ if( src.dims > 2 )
+ {
+ dst.create(src.dims, src.size, src.type());
+ const Mat* arrays[] = {&src, &dst, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ log( it.planes[0], it.planes[1] );
+ return;
+ }
+
int depth = src.depth();
dst.create( src.size(), src.type() );
Size size = getContinuousSize( src, dst, src.channels() );
void pow( const Mat& _src, double power, Mat& dst )
{
+ if( _src.dims > 2 )
+ {
+ dst.create(_src.dims, _src.size, _src.type());
+ const Mat* arrays[] = {&_src, &dst, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ pow( it.planes[0], power, it.planes[1] );
+ return;
+ }
+
int ipower = cvRound( power ), i, j;
bool is_ipower = 0;
int depth = _src.depth();
bool checkRange(const Mat& src, bool quiet, Point* pt,
double minVal, double maxVal)
{
+ if( src.dims > 2 )
+ {
+ const Mat* arrays[] = {&src, 0};
+ Mat planes[1];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ {
+ if( !checkRange( it.planes[0], quiet, pt, minVal, maxVal ))
+ {
+ // todo: set index properly
+ return false;
+ }
+ }
+ return true;
+ }
+
int depth = src.depth();
Point badPt(-1, -1);
double badValue = 0;
int cv::solveCubic( const Mat& coeffs, Mat& roots )
{
+ CV_Assert( coeffs.dims <= 2 );
const int n = 3;
if( ((roots.rows != 1 || roots.cols != n) &&
(roots.rows != n || roots.cols != 1)) ||
double maxDiff = 0;
int iter, i, j, n;
- CV_Assert( (coeffs0.cols == 1 || coeffs0.rows == 1) &&
+ CV_Assert( coeffs0.dims <= 2 &&
+ (coeffs0.cols == 1 || coeffs0.rows == 1) &&
(coeffs0.depth() == CV_32F || coeffs0.depth() == CV_64F) &&
coeffs0.channels() <= 2 );
n = coeffs0.cols + coeffs0.rows - 2;
GEMMStoreFunc storeFunc;
Mat *matD = &D, tmat;
const uchar* Cdata = C ? C->data : 0;
- size_t Cstep = C ? C->step : 0;
+ size_t Cstep = C ? (size_t)C->step : 0;
AutoBuffer<uchar> buf;
if( type == CV_32FC1 )
void scaleAdd( const Mat& src1, double alpha, const Mat& src2, Mat& dst )
{
+ if( src1.dims > 2 || src2.dims > 2 )
+ {
+ dst.create(src1.dims, src1.size, src1.type());
+ const Mat* arrays[] = {&src1, &src2, &dst, 0};
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ scaleAdd( it.planes[0], alpha, it.planes[1], it.planes[2] );
+ return;
+ }
+
int type = src1.type(), depth = CV_MAT_DEPTH(type);
CV_Assert( src1.size() == src2.size() && type == src2.type() );
dst.create( src1.size(), type );
namespace cv {
+void swap( Mat& a, Mat& b )
+{
+ int *ap = (int*)&a, *bp = (int*)&b;
+ size_t i, n = sizeof(Mat)/sizeof(ap[0]);
+
+ for( i = 0; i < n; i++ )
+ std::swap(ap[i], bp[i]);
+
+ if( a.step.p == b.step.buf )
+ {
+ a.step.p = a.step.buf;
+ a.size.p = &a.rows;
+ }
+
+ if( b.step.p == a.step.buf )
+ {
+ b.step.p = b.step.buf;
+ b.size.p = &b.rows;
+ }
+}
+
+
+static inline void setSize( Mat& m, int _dims, const int* _sz,
+ const size_t* _steps, bool autoSteps=false )
+{
+ CV_Assert( 0 <= _dims && _dims <= CV_MAX_DIM );
+ if( m.dims != _dims )
+ {
+ if( m.step.p != m.step.buf )
+ {
+ fastFree(m.step.p);
+ m.step.p = m.step.buf;
+ m.size.p = &m.rows;
+ }
+ if( _dims > 2 )
+ {
+ m.step.p = (size_t*)fastMalloc(_dims*sizeof(m.step.p[0]) + (_dims+1)*sizeof(m.size.p[0]));
+ m.size.p = (int*)(m.step.p + _dims) + 1;
+ m.size.p[-1] = _dims;
+ }
+ }
+
+ m.dims = _dims;
+ if( !_sz )
+ return;
+
+ size_t esz = m.elemSize(), total = esz;
+ int i;
+ for( i = _dims-1; i >= 0; i-- )
+ {
+ int s = _sz[i];
+ CV_Assert( s > 0 );
+ m.size.p[i] = s;
+
+ if( _steps )
+ m.step.p[i] = i < _dims-1 ? _steps[i] : esz;
+ else if( autoSteps )
+ {
+ m.step.p[i] = total;
+ int64 total1 = (int64)total*s;
+ if( (uint64)total1 != (size_t)total1 )
+ CV_Error( CV_StsOutOfRange, "The total matrix size does not fit to \"size_t\" type" );
+ total = (size_t)total1;
+ }
+ }
+
+ if( _dims == 1 )
+ {
+ m.dims = 2;
+ m.cols = 1;
+ m.step[1] = esz;
+ }
+}
+
+static void finalizeHdr(Mat& m)
+{
+ int i, j;
+
+ for( i = 0; i < m.dims; i++ )
+ {
+ if( m.size[i] > 1 )
+ break;
+ }
+
+ for( j = m.dims-1; j > i; j-- )
+ {
+ if( m.step[j]*m.size[j] < m.step[j-1] )
+ break;
+ }
+ m.flags &= ~Mat::CONTINUOUS_FLAG;
+ int64 t = (int64)(m.step[0]/m.elemSize())*m.size[0];
+ if( j <= i && t == (int)t )
+ m.flags |= Mat::CONTINUOUS_FLAG;
+
+ if( m.dims > 2 )
+ m.rows = m.cols = -1;
+ if( m.data )
+ {
+ m.dataend = m.data;
+ for( i = 0; i < m.dims; i++ )
+ m.dataend += (m.size[i] - 1)*m.step[i];
+ }
+}
+
+
+void Mat::create(int d, const int* _sizes, int _type)
+{
+ int i;
+ CV_Assert(0 <= d && _sizes && d <= CV_MAX_DIM && _sizes);
+ _type = CV_MAT_TYPE(_type);
+
+ if( data && (d == dims || (d == 1 && dims <= 2)) && _type == type() )
+ {
+ if( d == 2 && rows == _sizes[0] && cols == _sizes[1] )
+ return;
+ for( i = 0; i < d; i++ )
+ if( size[i] != _sizes[i] )
+ break;
+ if( i == d && (d > 1 || size[1] == 1))
+ return;
+ }
+
+ release();
+ if( d == 0 )
+ return;
+ flags = (_type & CV_MAT_TYPE_MASK) | MAGIC_VAL;
+ setSize(*this, d, _sizes, 0, allocator == 0);
+
+ if( !allocator )
+ {
+ size_t total = alignSize(step.p[0]*size.p[0], (int)sizeof(*refcount));
+ data = datastart = (uchar*)fastMalloc(total + (int)sizeof(*refcount));
+ refcount = (int*)(data + total);
+ *refcount = 1;
+ }
+ else
+ {
+ allocator->allocate(dims, size, _type, refcount, datastart, data, step.p);
+ CV_Assert( step[dims-1] == elemSize() );
+ }
+
+ finalizeHdr(*this);
+}
+
+void Mat::copySize(const Mat& m)
+{
+ setSize(*this, m.dims, 0, 0);
+ for( int i = 0; i < dims; i++ )
+ {
+ size[i] = m.size[i];
+ step[i] = m.step[i];
+ }
+}
+
+void Mat::deallocate()
+{
+ if( allocator )
+ allocator->deallocate(refcount, datastart, data);
+ else
+ {
+ CV_DbgAssert(refcount != 0);
+ fastFree(datastart);
+ }
+}
+
+
+Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
+ : flags(0), dims(0), rows(0), cols(0), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
+{
+ CV_Assert( m.dims >= 2 );
+ if( m.dims > 2 )
+ {
+ AutoBuffer<Range> rs(m.dims);
+ rs[0] = rowRange;
+ rs[1] = colRange;
+ for( int i = 2; i < m.dims; i++ )
+ rs[i] = Range::all();
+ *this = m(rs);
+ return;
+ }
+
+ *this = m;
+ if( rowRange != Range::all() )
+ {
+ CV_Assert( 0 <= rowRange.start && rowRange.start <= rowRange.end && rowRange.end <= m.rows );
+ rows = rowRange.size();
+ data += step*rowRange.start;
+ }
+
+ if( colRange != Range::all() )
+ {
+ CV_Assert( 0 <= colRange.start && colRange.start <= colRange.end && colRange.end <= m.cols );
+ cols = colRange.size();
+ data += colRange.start*elemSize();
+ flags &= cols < m.cols ? ~CONTINUOUS_FLAG : -1;
+ }
+
+ if( rows == 1 )
+ flags |= CONTINUOUS_FLAG;
+
+ if( refcount )
+ CV_XADD(refcount, 1);
+ if( rows <= 0 || cols <= 0 )
+ {
+ release();
+ rows = cols = 0;
+ }
+}
+
+
+Mat::Mat(const Mat& m, const Rect& roi)
+ : flags(m.flags), dims(2), rows(roi.height), cols(roi.width),
+ data(m.data + roi.y*m.step[0]), refcount(m.refcount),
+ datastart(m.datastart), dataend(m.dataend), allocator(m.allocator), size(&rows)
+{
+ CV_Assert( m.dims <= 2 );
+ flags &= roi.width < m.cols ? ~CONTINUOUS_FLAG : -1;
+ flags |= roi.height == 1 ? CONTINUOUS_FLAG : 0;
+
+ size_t esz = elemSize();
+ data += roi.x*esz;
+ CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
+ 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
+ if( refcount )
+ CV_XADD(refcount, 1);
+
+ step[0] = m.step[0]; step[1] = esz;
+
+ if( rows <= 0 || cols <= 0 )
+ {
+ release();
+ rows = cols = 0;
+ }
+}
+
+
+Mat::Mat(int _dims, const int* _sizes, int _type, void* _data, const size_t* _steps)
+ : flags(MAGIC_VAL|CV_MAT_TYPE(_type)), dims(0), rows(0), cols(0),
+ data((uchar*)_data), refcount(0),
+ datastart((uchar*)_data), dataend((uchar*)_data), allocator(0), size(&rows)
+{
+ setSize(*this, _dims, _sizes, _steps, true);
+ finalizeHdr(*this);
+}
+
+
+Mat::Mat(const Mat& m, const Range* ranges)
+ : flags(m.flags), dims(0), rows(0), cols(0), data(0), refcount(0),
+ datastart(0), dataend(0), allocator(0), size(&rows)
+{
+ int i, d = m.dims;
+
+ CV_Assert(ranges);
+ for( i = 0; i < d; i++ )
+ {
+ Range r = ranges[i];
+ CV_Assert( r == Range::all() || (0 <= r.start && r.start < r.end && r.end <= m.size[i]) );
+ }
+ *this = m;
+ for( i = 0; i < d; i++ )
+ {
+ Range r = ranges[i];
+ if( r != Range::all() )
+ {
+ size[i] = r.end - r.start;
+ data += r.start*step[i];
+ }
+ }
+
+ finalizeHdr(*this);
+}
+
+
+Mat::Mat(const CvMatND* m, bool copyData)
+ : flags(MAGIC_VAL|CV_MAT_TYPE(m->type)), dims(0), rows(0), cols(0),
+ data((uchar*)m->data.ptr), refcount(0),
+ datastart((uchar*)m->data.ptr), dataend((uchar*)m->data.ptr), allocator(0),
+ size(&rows)
+{
+ int _sizes[CV_MAX_DIM];
+ size_t _steps[CV_MAX_DIM];
+
+ int i, d = m->dims;
+ for( i = 0; i < d; i++ )
+ {
+ _sizes[i] = m->dim[i].size;
+ _steps[i] = m->dim[i].step;
+ }
+
+ setSize(*this, d, _sizes, _steps);
+ finalizeHdr(*this);
+
+ if( copyData )
+ {
+ Mat temp(*this);
+ temp.copyTo(*this);
+ }
+}
+
+
+Mat Mat::diag(int d) const
+{
+ CV_Assert( dims <= 2 );
+ Mat m = *this;
+ size_t esz = elemSize();
+ int len;
+
+ if( d >= 0 )
+ {
+ len = std::min(cols - d, rows);
+ m.data += esz*d;
+ }
+ else
+ {
+ len = std::min(rows + d, cols);
+ m.data -= step[0]*d;
+ }
+ CV_DbgAssert( len > 0 );
+
+ m.size[0] = m.rows = len;
+ m.size[1] = m.cols = 1;
+ m.step[0] += (len > 1 ? esz : 0);
+
+ if( m.rows > 1 )
+ m.flags &= ~CONTINUOUS_FLAG;
+ else
+ m.flags |= CONTINUOUS_FLAG;
+ return m;
+}
+
+
Mat::Mat(const IplImage* img, bool copyData)
+ : flags(MAGIC_VAL), dims(2), rows(0), cols(0),
+ data(0), refcount(0), datastart(0), dataend(0), allocator(0), size(&rows)
{
CV_DbgAssert(CV_IS_IMAGE(img) && img->imageData != 0);
int depth = IPL2CV_DEPTH(img->depth);
size_t esz;
- step = img->widthStep;
- refcount = 0;
+ step[0] = img->widthStep;
if(!img->roi)
{
esz = elemSize();
data = datastart = (uchar*)img->imageData +
(selectedPlane ? (img->roi->coi - 1)*step*img->height : 0) +
- img->roi->yOffset*step + img->roi->xOffset*esz;
+ img->roi->yOffset*step[0] + img->roi->xOffset*esz;
}
dataend = datastart + step*(rows-1) + esz*cols;
flags |= (cols*esz == step || rows == 1 ? CONTINUOUS_FLAG : 0);
+ step[1] = esz;
if( copyData )
{
Mat::operator IplImage() const
{
+ CV_Assert( dims <= 2 );
IplImage img;
cvInitImageHeader(&img, size(), cvIplDepth(flags), channels());
- cvSetData(&img, data, (int)step);
+ cvSetData(&img, data, (int)step[0]);
return img;
}
Mat cvarrToMat(const CvArr* arr, bool copyData,
bool allowND, int coiMode)
{
+ if( !arr )
+ return Mat();
if( CV_IS_MAT(arr) )
return Mat((const CvMat*)arr, copyData );
- else if( CV_IS_IMAGE(arr) )
+ if( CV_IS_MATND(arr) )
+ return Mat((const CvMatND*)arr, copyData );
+ if( CV_IS_IMAGE(arr) )
{
const IplImage* iplimg = (const IplImage*)arr;
if( coiMode == 0 && iplimg->roi && iplimg->roi->coi > 0 )
CV_Error(CV_BadCOI, "COI is not supported by the function");
return Mat(iplimg, copyData);
}
- else if( CV_IS_SEQ(arr) )
+ if( CV_IS_SEQ(arr) )
{
CvSeq* seq = (CvSeq*)arr;
CV_Assert(seq->total > 0 && CV_ELEM_SIZE(seq->flags) == seq->elem_size);
cvCvtSeqToArray(seq, buf.data, CV_WHOLE_SEQ);
return buf;
}
+ CV_Error(CV_StsBadArg, "Unknown array type");
+ return Mat();
+}
+
+void Mat::locateROI( Size& wholeSize, Point& ofs ) const
+{
+ CV_Assert( dims <= 2 && step[0] > 0 );
+ size_t esz = elemSize(), minstep;
+ ptrdiff_t delta1 = data - datastart, delta2 = dataend - datastart;
+
+ if( delta1 == 0 )
+ ofs.x = ofs.y = 0;
else
{
- CvMat hdr, *cvmat = cvGetMat( arr, &hdr, 0, allowND ? 1 : 0 );
- if( cvmat )
- return Mat(cvmat, copyData);
+ ofs.y = (int)(delta1/step[0]);
+ ofs.x = (int)((delta1 - step[0]*ofs.y)/esz);
+ CV_DbgAssert( data == datastart + ofs.y*step[0] + ofs.x*esz );
}
- return Mat();
+ minstep = (ofs.x + cols)*esz;
+ wholeSize.height = (int)((delta2 - minstep)/step[0] + 1);
+ wholeSize.height = std::max(wholeSize.height, ofs.y + rows);
+ wholeSize.width = (int)((delta2 - step*(wholeSize.height-1))/esz);
+ wholeSize.width = std::max(wholeSize.width, ofs.x + cols);
}
-
+Mat& Mat::adjustROI( int dtop, int dbottom, int dleft, int dright )
+{
+ CV_Assert( dims <= 2 && step[0] > 0 );
+ Size wholeSize; Point ofs;
+ size_t esz = elemSize();
+ locateROI( wholeSize, ofs );
+ int row1 = std::max(ofs.y - dtop, 0), row2 = std::min(ofs.y + rows + dbottom, wholeSize.height);
+ int col1 = std::max(ofs.x - dleft, 0), col2 = std::min(ofs.x + cols + dright, wholeSize.width);
+ data += (row1 - ofs.y)*step + (col1 - ofs.x)*esz;
+ rows = row2 - row1; cols = col2 - col1;
+ size.p[0] = rows; size.p[1] = cols;
+ if( esz*cols == step[0] || rows == 1 )
+ flags |= CONTINUOUS_FLAG;
+ else
+ flags &= ~CONTINUOUS_FLAG;
+ return *this;
+}
+
void extractImageCOI(const CvArr* arr, Mat& ch, int coi)
{
Mat mat = cvarrToMat(arr, false, true, 1);
- ch.create(mat.size(), mat.depth());
+ ch.create(mat.dims, mat.size, mat.depth());
if(coi < 0)
CV_Assert( CV_IS_IMAGE(arr) && (coi = cvGetImageCOI((const IplImage*)arr)-1) >= 0 );
CV_Assert(0 <= coi && coi < mat.channels());
Mat mat = cvarrToMat(arr, false, true, 1);
if(coi < 0)
CV_Assert( CV_IS_IMAGE(arr) && (coi = cvGetImageCOI((const IplImage*)arr)-1) >= 0 );
- CV_Assert(ch.size() == mat.size() && ch.depth() == mat.depth() && 0 <= coi && coi < mat.channels());
+ CV_Assert(ch.size == mat.size && ch.depth() == mat.depth() && 0 <= coi && coi < mat.channels());
int _pairs[] = { 0, coi };
mixChannels( &ch, 1, &mat, 1, _pairs, 1 );
}
Mat Mat::reshape(int new_cn, int new_rows) const
{
+ CV_Assert( dims <= 2 );
Mat hdr = *this;
int cn = channels();
"is not divisible by the new number of rows" );
hdr.rows = new_rows;
- hdr.step = total_width * elemSize1();
+ hdr.step[0] = total_width * elemSize1();
}
int new_width = total_width / new_cn;
void
setIdentity( Mat& m, const Scalar& s )
{
+ CV_Assert( m.dims <= 2 );
int i, j, rows = m.rows, cols = m.cols, type = m.type();
if( type == CV_32FC1 )
Scalar trace( const Mat& m )
{
+ CV_Assert( m.dims <= 2 );
int i, type = m.type();
int nm = std::min(m.rows, m.cols);
return cv::sum(m.diag());
}
-
/****************************************************************************************\
* transpose *
\****************************************************************************************/
};
size_t esz = src.elemSize();
- CV_Assert( esz <= (size_t)32 );
+ CV_Assert( src.dims <= 2 && esz <= (size_t)32 );
if( dst.data == src.data && dst.cols == dst.rows )
{
}
-void completeSymm( Mat& matrix, bool LtoR )
+void completeSymm( Mat& m, bool LtoR )
{
- int i, j, nrows = matrix.rows, type = matrix.type();
+ CV_Assert( m.dims <= 2 );
+
+ int i, j, nrows = m.rows, type = m.type();
int j0 = 0, j1 = nrows;
- CV_Assert( matrix.rows == matrix.cols );
+ CV_Assert( m.rows == m.cols );
if( type == CV_32FC1 || type == CV_32SC1 )
{
- int* data = (int*)matrix.data;
- size_t step = matrix.step/sizeof(data[0]);
+ int* data = (int*)m.data;
+ size_t step = m.step/sizeof(data[0]);
for( i = 0; i < nrows; i++ )
{
if( !LtoR ) j1 = i; else j0 = i+1;
}
else if( type == CV_64FC1 )
{
- double* data = (double*)matrix.data;
- size_t step = matrix.step/sizeof(data[0]);
+ double* data = (double*)m.data;
+ size_t step = m.step/sizeof(data[0]);
for( i = 0; i < nrows; i++ )
{
if( !LtoR ) j1 = i; else j0 = i+1;
CV_Error( CV_StsUnsupportedFormat, "" );
}
+
Mat Mat::cross(const Mat& m) const
{
int t = type(), d = CV_MAT_DEPTH(t);
- CV_Assert( size() == m.size() && t == m.type() &&
+ CV_Assert( dims <= 2 && m.dims <= 2 && size() == m.size() && t == m.type() &&
((rows == 3 && cols == 1) || (cols*channels() == 3 && rows == 1)));
Mat result(rows, cols, t);
void reduce(const Mat& src, Mat& dst, int dim, int op, int dtype)
{
+ CV_Assert( src.dims <= 2 );
int op0 = op;
int stype = src.type(), sdepth = src.depth();
if( dtype < 0 )
sort_<int>, sort_<float>, sort_<double>, 0
};
SortFunc func = tab[src.depth()];
- CV_Assert( src.channels() == 1 && func != 0 );
+ CV_Assert( src.dims <= 2 && src.channels() == 1 && func != 0 );
dst.create( src.size(), src.type() );
func( src, dst, flags );
}
sortIdx_<int>, sortIdx_<float>, sortIdx_<double>, 0
};
SortFunc func = tab[src.depth()];
- CV_Assert( src.channels() == 1 && func != 0 );
+ CV_Assert( src.dims <= 2 && src.channels() == 1 && func != 0 );
if( dst.data == src.data )
dst.release();
dst.create( src.size(), CV_32S );
bool simd = checkHardwareSupport(CV_CPU_SSE);
attempts = std::max(attempts, 1);
- CV_Assert( type == CV_32F && K > 0 );
+ CV_Assert( data.dims <= 2 && type == CV_32F && K > 0 );
Mat _labels;
if( flags & CV_KMEANS_USE_INITIAL_LABELS )
namespace cv
{
-//////////////////////////////// MatND ///////////////////////////////////
-
-MatND::MatND(const MatND& m, const Range* ranges)
- : flags(MAGIC_VAL), dims(0), refcount(0), data(0), datastart(0), dataend(0)
+Mat Mat::reshape(int, int, const int*) const
{
- int i, j, d = m.dims;
+ CV_Error(CV_StsNotImplemented, "");
+ // TBD
+ return Mat();
+}
- CV_Assert(ranges);
+Mat::operator CvMatND() const
+{
+ CvMatND mat;
+ cvInitMatNDHeader( &mat, dims, size, type(), data );
+ int i, d = dims;
for( i = 0; i < d; i++ )
+ mat.dim[i].step = (int)step[i];
+ mat.type |= flags & CONTINUOUS_FLAG;
+ return mat;
+}
+
+NAryMatIterator::NAryMatIterator()
+ : arrays(0), planes(0), narrays(0), nplanes(0), iterdepth(0), idx(0)
+{
+}
+
+NAryMatIterator::NAryMatIterator(const Mat** _arrays, Mat* _planes, int _narrays)
+ : arrays(0), planes(0), narrays(0), nplanes(0), iterdepth(0), idx(0)
+{
+ init(_arrays, _planes, _narrays);
+}
+
+void NAryMatIterator::init(const Mat** _arrays, Mat* _planes, int _narrays)
+{
+ CV_Assert( _arrays && _planes );
+ int i, j, d1=0, i0 = -1, d = -1, total = 0;
+
+ arrays = _arrays;
+ planes = _planes;
+ narrays = _narrays;
+ nplanes = 0;
+
+ if( narrays < 0 )
{
- Range r = ranges[i];
- CV_Assert( r == Range::all() ||
- (0 <= r.start && r.start < r.end && r.end <= m.size[i]) );
+ for( i = 0; _arrays[i] != 0; i++ )
+ ;
+ narrays = i;
+ CV_Assert(narrays <= 1000);
}
- *this = m;
- for( i = 0; i < d; i++ )
+
+ iterdepth = 0;
+
+ for( i = 0; i < narrays; i++ )
{
- Range r = ranges[i];
- if( r != Range::all() )
+ CV_Assert(arrays[i] != 0);
+ if( !arrays[i]->data )
+ continue;
+ const Mat& A = *arrays[i];
+
+ if( i0 < 0 )
{
- size[i] = r.end - r.start;
- data += r.start*step[i];
+ i0 = i;
+ d = A.dims;
+
+ // find the first dimensionality which is different from 1;
+ // in any of the arrays the first "d1" step do not affect the continuity
+ for( d1 = 0; d1 < d; d1++ )
+ if( A.size[d1] > 1 )
+ break;
+ }
+ else
+ CV_Assert( A.size == arrays[i0]->size );
+
+ if( !A.isContinuous() )
+ {
+ CV_Assert( A.step[d-1] == A.elemSize() );
+ for( j = d-1; j > d1; j-- )
+ if( A.step[j]*A.size[j] < A.step[j-1] )
+ break;
+ iterdepth = std::max(iterdepth, j);
}
}
-
- for( i = 0; i < d; i++ )
+
+ if( i0 >= 0 )
{
- if( size[i] != 1 )
- break;
+ total = arrays[i0]->size[d-1];
+ for( j = d-1; j > iterdepth; j-- )
+ {
+ int64 total1 = (int64)total*arrays[i0]->size[j-1];
+ if( total1 != (int)total1 )
+ break;
+ total = (int)total1;
+ }
+
+ iterdepth = j;
+ if( iterdepth == d1 )
+ iterdepth = 0;
+
+ nplanes = 1;
+ for( j = iterdepth-1; j >= 0; j-- )
+ nplanes *= arrays[i0]->size[j];
}
+ else
+ iterdepth = nplanes = 0;
- CV_Assert( step[d-1] == elemSize() );
- for( j = d-1; j > i; j-- )
+ for( i = 0; i < narrays; i++ )
{
- if( step[j]*size[j] < step[j-1] )
- break;
+ if( !arrays[i]->data )
+ {
+ planes[i] = Mat();
+ continue;
+ }
+ planes[i] = Mat( 1, total, arrays[i]->type(), arrays[i]->data );
+ planes[i].datastart = arrays[i]->datastart;
+ planes[i].dataend = arrays[i]->dataend;
}
- flags = (flags & ~CONTINUOUS_FLAG) | (j <= i ? CONTINUOUS_FLAG : 0);
+
+ idx = 0;
}
-void MatND::create(int d, const int* _sizes, int _type)
-{
- CV_Assert(d > 0 && _sizes);
- int i;
- _type = CV_MAT_TYPE(_type);
- if( data && d == dims && _type == type() )
- {
- for( i = 0; i < d; i++ )
- if( size[i] != _sizes[i] )
- break;
- if( i == d )
- return;
- }
-
- release();
-
- flags = (_type & CV_MAT_TYPE_MASK) | MAGIC_VAL | CONTINUOUS_FLAG;
- size_t total = elemSize();
- int64 total1;
-
- for( i = d-1; i >= 0; i-- )
- {
- int sz = _sizes[i];
- size[i] = sz;
- step[i] = total;
- total1 = (int64)total*sz;
- CV_Assert( sz > 0 );
- if( (uint64)total1 != (size_t)total1 )
- CV_Error( CV_StsOutOfRange, "The total matrix size does not fit to \"size_t\" type" );
- total = (size_t)total1;
- }
- total = alignSize(total, (int)sizeof(*refcount));
- data = datastart = (uchar*)fastMalloc(total + (int)sizeof(*refcount));
- dataend = datastart + step[0]*size[0];
- refcount = (int*)(data + total);
- *refcount = 1;
- dims = d;
-}
-
-void MatND::copyTo( MatND& m ) const
-{
- m.create( dims, size, type() );
- NAryMatNDIterator it(*this, m);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- it.planes[0].copyTo(it.planes[1]);
-}
-
-void MatND::copyTo( MatND& m, const MatND& mask ) const
-{
- m.create( dims, size, type() );
- NAryMatNDIterator it(*this, m, mask);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- it.planes[0].copyTo(it.planes[1], it.planes[2]);
-}
-
-void MatND::convertTo( MatND& m, int rtype, double alpha, double beta ) const
-{
- rtype = rtype < 0 ? type() : CV_MAKETYPE(CV_MAT_DEPTH(rtype), channels());
- m.create( dims, size, rtype );
- NAryMatNDIterator it(*this, m);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- it.planes[0].convertTo(it.planes[1], rtype, alpha, beta);
-}
-
-MatND& MatND::operator = (const Scalar& s)
-{
- NAryMatNDIterator it(*this);
- for( int i = 0; i < it.nplanes; i++, ++it )
- it.planes[0] = s;
-
- return *this;
-}
-
-MatND& MatND::setTo(const Scalar& s, const MatND& mask)
-{
- NAryMatNDIterator it(*this, mask);
- for( int i = 0; i < it.nplanes; i++, ++it )
- it.planes[0].setTo(s, it.planes[1]);
-
- return *this;
-}
-
-MatND MatND::reshape(int, int, const int*) const
-{
- CV_Error(CV_StsNotImplemented, "");
- // TBD
- return MatND();
-}
-
-MatND::operator Mat() const
-{
- int i, d = dims, d1, rows, cols;
- size_t _step = Mat::AUTO_STEP;
-
- if( d <= 2 )
- {
- rows = size[0];
- cols = d == 2 ? size[1] : 1;
- if( d == 2 )
- _step = step[0];
- }
- else
- {
- rows = 1;
- cols = size[d-1];
-
- for( d1 = 0; d1 < d; d1++ )
- if( size[d1] > 1 )
- break;
-
- for( i = d-1; i > d1; i-- )
- {
- int64 cols1 = (int64)cols*size[i-1];
- if( cols1 != (int)cols1 || size[i]*step[i] != step[i-1] )
- break;
- cols = (int)cols1;
- }
-
- if( i > d1 )
- {
- --i;
- _step = step[i];
- rows = size[i];
- for( ; i > d1; i-- )
- {
- int64 rows1 = (int64)rows*size[i-1];
- if( rows1 != (int)rows1 || size[i]*step[i] != step[i-1] )
- break;
- rows = (int)rows1;
- }
-
- if( i > d1 )
- CV_Error( CV_StsBadArg,
- "The nD matrix can not be represented as 2D matrix due "
- "to its layout in memory; you may use (Mat)the_matnd.clone() instead" );
- }
- }
-
- Mat m(rows, cols, type(), data, _step);
- m.datastart = datastart;
- m.dataend = dataend;
- m.refcount = refcount;
- m.addref();
- return m;
-}
-
-MatND::operator CvMatND() const
-{
- CvMatND mat;
- cvInitMatNDHeader( &mat, dims, size, type(), data );
- int i, d = dims;
- for( i = 0; i < d; i++ )
- mat.dim[i].step = (int)step[i];
- mat.type |= flags & CONTINUOUS_FLAG;
- return mat;
-}
-
-NAryMatNDIterator::NAryMatNDIterator(const MatND** _arrays, size_t count)
-{
- init(_arrays, count);
-}
-
-NAryMatNDIterator::NAryMatNDIterator(const MatND* _arrays, size_t count)
-{
- AutoBuffer<const MatND*, 32> buf(count);
- for( size_t i = 0; i < count; i++ )
- buf[i] = _arrays + i;
- init(buf, count);
-}
-
-
-NAryMatNDIterator::NAryMatNDIterator(const MatND& m1)
-{
- const MatND* mm[] = {&m1};
- init(mm, 1);
-}
-
-NAryMatNDIterator::NAryMatNDIterator(const MatND& m1, const MatND& m2)
-{
- const MatND* mm[] = {&m1, &m2};
- init(mm, 2);
-}
-
-NAryMatNDIterator::NAryMatNDIterator(const MatND& m1, const MatND& m2, const MatND& m3)
-{
- const MatND* mm[] = {&m1, &m2, &m3};
- init(mm, 3);
-}
-
-NAryMatNDIterator::NAryMatNDIterator(const MatND& m1, const MatND& m2,
- const MatND& m3, const MatND& m4)
-{
- const MatND* mm[] = {&m1, &m2, &m3, &m4};
- init(mm, 4);
-}
-
-NAryMatNDIterator::NAryMatNDIterator(const MatND& m1, const MatND& m2,
- const MatND& m3, const MatND& m4,
- const MatND& m5)
-{
- const MatND* mm[] = {&m1, &m2, &m3, &m4, &m5};
- init(mm, 5);
-}
-
-NAryMatNDIterator::NAryMatNDIterator(const MatND& m1, const MatND& m2,
- const MatND& m3, const MatND& m4,
- const MatND& m5, const MatND& m6)
-{
- const MatND* mm[] = {&m1, &m2, &m3, &m4, &m5, &m6};
- init(mm, 6);
-}
-
-void NAryMatNDIterator::init(const MatND** _arrays, size_t count)
-{
- CV_Assert( _arrays && count > 0 );
- arrays.resize(count);
- int i, j, d1=0, i0 = -1, d = -1, n = (int)count;
-
- iterdepth = 0;
-
- for( i = 0; i < n; i++ )
- {
- if( !_arrays[i] || !_arrays[i]->data )
- {
- arrays[i] = MatND();
- continue;
- }
- const MatND& A = arrays[i] = *_arrays[i];
-
- if( i0 < 0 )
- {
- i0 = i;
- d = A.dims;
-
- // find the first dimensionality which is different from 1;
- // in any of the arrays the first "d1" steps do not affect the continuity
- for( d1 = 0; d1 < d; d1++ )
- if( A.size[d1] > 1 )
- break;
- }
- else
- {
- CV_Assert( A.dims == d );
- for( j = 0; j < d; j++ )
- CV_Assert( A.size[j] == arrays[i0].size[j] );
- }
-
- if( !A.isContinuous() )
- {
- CV_Assert( A.step[d-1] == A.elemSize() );
- for( j = d-1; j > d1; j-- )
- if( A.step[j]*A.size[j] < A.step[j-1] )
- break;
- iterdepth = std::max(iterdepth, j);
- }
- }
-
- if( i0 < 0 )
- CV_Error( CV_StsBadArg, "All the input arrays are empty" );
-
- int total = arrays[i0].size[d-1];
- for( j = d-1; j > iterdepth; j-- )
- {
- int64 total1 = (int64)total*arrays[i0].size[j-1];
- if( total1 != (int)total1 )
- break;
- total = (int)total1;
- }
-
- iterdepth = j;
- if( iterdepth == d1 )
- iterdepth = 0;
-
- planes.resize(n);
- for( i = 0; i < n; i++ )
- {
- if( !arrays[i].data )
- {
- planes[i] = Mat();
- continue;
- }
- planes[i] = Mat( 1, total, arrays[i].type(), arrays[i].data );
- planes[i].datastart = arrays[i].datastart;
- planes[i].dataend = arrays[i].dataend;
- planes[i].refcount = arrays[i].refcount;
- planes[i].addref();
- }
-
- idx = 0;
- nplanes = 1;
- for( j = iterdepth-1; j >= 0; j-- )
- nplanes *= arrays[i0].size[j];
-}
-
-
-NAryMatNDIterator& NAryMatNDIterator::operator ++()
+
+NAryMatIterator& NAryMatIterator::operator ++()
{
if( idx >= nplanes-1 )
return *this;
++idx;
- for( size_t i = 0; i < arrays.size(); i++ )
+ for( int i = 0; i < narrays; i++ )
{
- const MatND& A = arrays[i];
+ const Mat& A = *arrays[i];
Mat& M = planes[i];
if( !A.data )
continue;
return *this;
}
-NAryMatNDIterator NAryMatNDIterator::operator ++(int)
+NAryMatIterator NAryMatIterator::operator ++(int)
{
- NAryMatNDIterator it = *this;
+ NAryMatIterator it = *this;
++*this;
return it;
}
-void add(const MatND& a, const MatND& b, MatND& c, const MatND& mask)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c, mask);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- add( it.planes[0], it.planes[1], it.planes[2], it.planes[3] );
-}
-
-void subtract(const MatND& a, const MatND& b, MatND& c, const MatND& mask)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c, mask);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- subtract( it.planes[0], it.planes[1], it.planes[2], it.planes[3] );
-}
-
-void add(const MatND& a, const MatND& b, MatND& c)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- add( it.planes[0], it.planes[1], it.planes[2] );
-}
-
-
-void subtract(const MatND& a, const MatND& b, MatND& c)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- subtract( it.planes[0], it.planes[1], it.planes[2] );
-}
-
-void add(const MatND& a, const Scalar& s, MatND& c, const MatND& mask)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, c, mask);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- add( it.planes[0], s, it.planes[1], it.planes[2] );
-}
+///////////////////////////////////////////////////////////////////////////
+// MatConstIterator //
+///////////////////////////////////////////////////////////////////////////
-void subtract(const Scalar& s, const MatND& a, MatND& c, const MatND& mask)
+Point MatConstIterator::pos() const
{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, c, mask);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- subtract( s, it.planes[0], it.planes[1], it.planes[2] );
-}
-
-void multiply(const MatND& a, const MatND& b, MatND& c, double scale)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- multiply( it.planes[0], it.planes[1], it.planes[2], scale );
-}
-
-void divide(const MatND& a, const MatND& b, MatND& c, double scale)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- divide( it.planes[0], it.planes[1], it.planes[2], scale );
-}
-
-void divide(double scale, const MatND& b, MatND& c)
-{
- c.create(b.dims, b.size, b.type());
- NAryMatNDIterator it(b, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- divide( scale, it.planes[0], it.planes[1] );
-}
-
-void scaleAdd(const MatND& a, double alpha, const MatND& b, MatND& c)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- scaleAdd( it.planes[0], alpha, it.planes[1], it.planes[2] );
-}
-
-void addWeighted(const MatND& a, double alpha, const MatND& b,
- double beta, double gamma, MatND& c)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- addWeighted( it.planes[0], alpha, it.planes[1], beta, gamma, it.planes[2] );
-}
-
-Scalar sum(const MatND& m)
-{
- NAryMatNDIterator it(m);
- Scalar s;
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- s += sum(it.planes[0]);
- return s;
-}
-
-int countNonZero( const MatND& m )
-{
- NAryMatNDIterator it(m);
- int nz = 0;
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- nz += countNonZero(it.planes[0]);
- return nz;
-}
-
-Scalar mean(const MatND& m)
-{
- NAryMatNDIterator it(m);
- double total = 1;
- for( int i = 0; i < m.dims; i++ )
- total *= m.size[i];
- return sum(m)*(1./total);
+ if( !m )
+ return Point();
+ CV_DbgAssert(m->dims <= 2);
+
+ ptrdiff_t ofs = ptr - m->data;
+ int y = (int)(ofs/m->step[0]);
+ return Point((int)((ofs - y*m->step[0])/elemSize), y);
}
-Scalar mean(const MatND& m, const MatND& mask)
+void MatConstIterator::pos(int* _idx) const
{
- if( !mask.data )
- return mean(m);
- NAryMatNDIterator it(m, mask);
- double total = 0;
- Scalar s;
- for( int i = 0; i < it.nplanes; i++, ++it )
+ CV_Assert(m != 0 && _idx);
+ ptrdiff_t ofs = ptr - m->data;
+ for( int i = 0; i < m->dims; i++ )
{
- int n = countNonZero(it.planes[1]);
- s += mean(it.planes[0], it.planes[1])*(double)n;
- total += n;
+ size_t s = m->step[i], v = ofs/s;
+ ofs -= v*s;
+ _idx[i] = (int)v;
}
- return s *= 1./std::max(total, 1.);
}
-void meanStdDev(const MatND& m, Scalar& mean, Scalar& stddev, const MatND& mask)
+ptrdiff_t MatConstIterator::lpos() const
{
- NAryMatNDIterator it(m, mask);
- double total = 0;
- Scalar s, sq;
- int k, cn = m.channels();
-
- for( int i = 0; i < it.nplanes; i++, ++it )
+ if(!m)
+ return 0;
+ if( m->isContinuous() )
+ return (ptr - sliceStart)/elemSize;
+ ptrdiff_t ofs = ptr - m->data;
+ int i, d = m->dims;
+ if( d == 2 )
{
- Scalar _mean, _stddev;
- meanStdDev(it.planes[0], _mean, _stddev, it.planes[1]);
- double nz = mask.data ? countNonZero(it.planes[1]) :
- (double)it.planes[0].rows*it.planes[0].cols;
- for( k = 0; k < cn; k++ )
- {
- s[k] += _mean[k]*nz;
- sq[k] += (_stddev[k]*_stddev[k] + _mean[k]*_mean[k])*nz;
- }
- total += nz;
+ ptrdiff_t y = ofs/m->step[0];
+ return y*m->cols + (ofs - y*m->step[0])/elemSize;
}
-
- mean = stddev = Scalar();
- total = 1./std::max(total, 1.);
- for( k = 0; k < cn; k++ )
+ ptrdiff_t result = 0;
+ for( i = 0; i < d; i++ )
{
- mean[k] = s[k]*total;
- stddev[k] = std::sqrt(std::max(sq[k]*total - mean[k]*mean[k], 0.));
+ size_t s = m->step[i], v = ofs/s;
+ ofs -= v*s;
+ result = result*m->size[i] + v;
}
+ return result;
}
-
-double norm(const MatND& a, int normType, const MatND& mask)
+
+void MatConstIterator::seek(ptrdiff_t ofs, bool relative)
{
- NAryMatNDIterator it(a, mask);
- double total = 0;
-
- for( int i = 0; i < it.nplanes; i++, ++it )
+ if( m->isContinuous() )
{
- double n = norm(it.planes[0], normType, it.planes[1]);
- if( normType == NORM_INF )
- total = std::max(total, n);
- else if( normType == NORM_L1 )
- total += n;
- else
- total += n*n;
+ ptr = (relative ? ptr : sliceStart) + ofs*elemSize;
+ if( ptr < sliceStart )
+ ptr = sliceStart;
+ else if( ptr > sliceEnd )
+ ptr = sliceEnd;
+ return;
}
-
- return normType != NORM_L2 ? total : std::sqrt(total);
-}
-
-double norm(const MatND& a, const MatND& b,
- int normType, const MatND& mask)
-{
- bool isRelative = (normType & NORM_RELATIVE) != 0;
- normType &= 7;
-
- NAryMatNDIterator it(a, b, mask);
- double num = 0, denom = 0;
-
- for( int i = 0; i < it.nplanes; i++, ++it )
+
+ int d = m->dims;
+ if( d == 2 )
{
- double n = norm(it.planes[0], it.planes[1], normType, it.planes[2]);
- double d = !isRelative ? 0 : norm(it.planes[1], normType, it.planes[2]);
- if( normType == NORM_INF )
+ ptrdiff_t ofs0, y;
+ if( relative )
{
- num = std::max(num, n);
- denom = std::max(denom, d);
+ ofs0 = ptr - m->data;
+ y = ofs0/m->step[0];
+ ofs += y*m->cols + (ofs0 - y*m->step[0])/elemSize;
}
- else if( normType == NORM_L1 )
- {
- num += n;
- denom += d;
- }
- else
- {
- num += n*n;
- denom += d*d;
- }
- }
-
- if( normType == NORM_L2 )
- {
- num = std::sqrt(num);
- denom = std::sqrt(denom);
- }
-
- return !isRelative ? num : num/std::max(denom,DBL_EPSILON);
-}
-
-void normalize( const MatND& src, MatND& dst, double a, double b,
- int norm_type, int rtype, const MatND& mask )
-{
- double scale = 1, shift = 0;
- if( norm_type == CV_MINMAX )
- {
- double smin = 0, smax = 0;
- double dmin = std::min( a, b ), dmax = std::max( a, b );
- minMaxLoc( src, &smin, &smax, 0, 0, mask );
- scale = (dmax - dmin)*(smax - smin > DBL_EPSILON ? 1./(smax - smin) : 0);
- shift = dmin - smin*scale;
- }
- else if( norm_type == CV_L2 || norm_type == CV_L1 || norm_type == CV_C )
- {
- scale = norm( src, norm_type, mask );
- scale = scale > DBL_EPSILON ? a/scale : 0.;
- shift = 0;
+ y = ofs/m->cols;
+ int y1 = std::min(std::max((int)y, 0), m->rows-1);
+ sliceStart = m->data + y1*m->step[0];
+ sliceEnd = sliceStart + (m->cols-1)*elemSize;
+ ptr = y < 0 ? sliceStart : y >= m->rows ? sliceEnd :
+ sliceStart + (ofs - y*m->cols)*elemSize;
+ return;
}
- else
- CV_Error( CV_StsBadArg, "Unknown/unsupported norm type" );
- if( !mask.data )
- src.convertTo( dst, rtype, scale, shift );
- else
- {
- MatND temp;
- src.convertTo( temp, rtype, scale, shift );
- temp.copyTo( dst, mask );
- }
-}
-
-static void ofs2idx(const MatND& a, size_t ofs, int* idx)
-{
- int i, d = a.dims;
- for( i = 0; i < d; i++ )
- {
- idx[i] = (int)(ofs / a.step[i]);
- ofs %= a.step[i];
- }
-}
+ if( relative )
+ ofs += lpos();
+ if( ofs < 0 )
+ ofs = 0;
-void minMaxLoc(const MatND& a, double* minVal,
- double* maxVal, int* minLoc, int* maxLoc,
- const MatND& mask)
-{
- NAryMatNDIterator it(a, mask);
- double minval = DBL_MAX, maxval = -DBL_MAX;
- size_t minofs = 0, maxofs = 0, esz = a.elemSize();
+ int szi = m->size[d-1];
+ ptrdiff_t t = ofs/szi;
+ int v = (int)(ofs - t*szi);
+ ofs = t;
+ ptr = m->data + v*elemSize;
+ sliceStart = m->data;
- for( int i = 0; i < it.nplanes; i++, ++it )
+ for( int i = d-2; i >= 0; i-- )
{
- double val0 = 0, val1 = 0;
- Point pt0, pt1;
- minMaxLoc( it.planes[0], &val0, &val1, &pt0, &pt1, it.planes[1] );
- if( val0 < minval )
- {
- minval = val0;
- minofs = (it.planes[0].data - a.data) + pt0.x*esz;
- }
- if( val1 > maxval )
- {
- maxval = val1;
- maxofs = (it.planes[0].data - a.data) + pt1.x*esz;
- }
+ szi = m->size[i];
+ t = ofs/szi;
+ v = (int)(ofs - t*szi);
+ ofs = t;
+ sliceStart += v*m->step[i];
}
-
- if( minVal )
- *minVal = minval;
- if( maxVal )
- *maxVal = maxval;
- if( minLoc )
- ofs2idx(a, minofs, minLoc);
- if( maxLoc )
- ofs2idx(a, maxofs, maxLoc);
-}
-
-void merge(const MatND* mv, size_t n, MatND& dst)
-{
- size_t k;
- CV_Assert( n > 0 );
- vector<MatND> v(n + 1);
- int total_cn = 0;
- for( k = 0; k < n; k++ )
- {
- total_cn += mv[k].channels();
- v[k] = mv[k];
- }
- dst.create( mv[0].dims, mv[0].size, CV_MAKETYPE(mv[0].depth(), total_cn) );
- v[n] = dst;
- NAryMatNDIterator it(&v[0], v.size());
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- merge( &it.planes[0], n, it.planes[n] );
-}
-
-void split(const MatND& m, MatND* mv)
-{
- size_t k, n = m.channels();
- CV_Assert( n > 0 );
- vector<MatND> v(n + 1);
- for( k = 0; k < n; k++ )
- {
- mv[k].create( m.dims, m.size, CV_MAKETYPE(m.depth(), 1) );
- v[k] = mv[k];
- }
- v[n] = m;
- NAryMatNDIterator it(&v[0], v.size());
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- split( it.planes[n], &it.planes[0] );
+
+ sliceEnd = sliceStart + m->size[d-1]*elemSize;
+ if( ofs > 0 )
+ ptr = sliceEnd;
+ else
+ ptr = sliceStart + (ptr - m->data);
}
-
-void mixChannels(const MatND* src, int nsrcs, MatND* dst, int ndsts,
- const int* fromTo, size_t npairs)
-{
- size_t k, m = nsrcs, n = ndsts;
- CV_Assert( n > 0 && m > 0 );
- vector<MatND> v(m + n);
- for( k = 0; k < m; k++ )
- v[k] = src[k];
- for( k = 0; k < n; k++ )
- v[m + k] = dst[k];
- NAryMatNDIterator it(&v[0], v.size());
-
- for( int i = 0; i < it.nplanes; i++, ++it )
+
+void MatConstIterator::seek(const int* _idx, bool relative)
+{
+ int i, d = m->dims;
+ ptrdiff_t ofs = 0;
+ if( !_idx )
+ ;
+ else if( d == 2 )
+ ofs = _idx[0]*m->size[1] + _idx[1];
+ else
{
- Mat* pptr = &it.planes[0];
- mixChannels( pptr, m, pptr + m, n, fromTo, npairs );
+ for( i = 0; i < d; i++ )
+ ofs = ofs*m->size[i] + _idx[i];
}
+ seek(ofs, relative);
}
-void bitwise_and(const MatND& a, const MatND& b, MatND& c, const MatND& mask)
+ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a)
{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c, mask);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- bitwise_and( it.planes[0], it.planes[1], it.planes[2], it.planes[3] );
-}
-
-void bitwise_or(const MatND& a, const MatND& b, MatND& c, const MatND& mask)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c, mask);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- bitwise_or( it.planes[0], it.planes[1], it.planes[2], it.planes[3] );
-}
-
-void bitwise_xor(const MatND& a, const MatND& b, MatND& c, const MatND& mask)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c, mask);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- bitwise_xor( it.planes[0], it.planes[1], it.planes[2], it.planes[3] );
-}
-
-void bitwise_and(const MatND& a, const Scalar& s, MatND& c, const MatND& mask)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, c, mask);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- bitwise_and( it.planes[0], s, it.planes[1], it.planes[2] );
-}
-
-void bitwise_or(const MatND& a, const Scalar& s, MatND& c, const MatND& mask)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, c, mask);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- bitwise_or( it.planes[0], s, it.planes[1], it.planes[2] );
-}
-
-void bitwise_xor(const MatND& a, const Scalar& s, MatND& c, const MatND& mask)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, c, mask);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- bitwise_xor( it.planes[0], s, it.planes[1], it.planes[2] );
-}
-
-void bitwise_not(const MatND& a, MatND& c)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- bitwise_not( it.planes[0], it.planes[1] );
-}
-
-void absdiff(const MatND& a, const MatND& b, MatND& c)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- absdiff( it.planes[0], it.planes[1], it.planes[2] );
-}
-
-void absdiff(const MatND& a, const Scalar& s, MatND& c)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- absdiff( it.planes[0], s, it.planes[1] );
-}
-
-void inRange(const MatND& src, const MatND& lowerb,
- const MatND& upperb, MatND& dst)
-{
- dst.create(src.dims, src.size, CV_8UC1);
- NAryMatNDIterator it(src, lowerb, upperb, dst);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- inRange( it.planes[0], it.planes[1], it.planes[2], it.planes[3] );
-}
-
-void inRange(const MatND& src, const Scalar& lowerb,
- const Scalar& upperb, MatND& dst)
-{
- dst.create(src.dims, src.size, CV_8UC1);
- NAryMatNDIterator it(src, dst);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- inRange( it.planes[0], lowerb, upperb, it.planes[1] );
-}
-
-void compare(const MatND& a, const MatND& b, MatND& c, int cmpop)
-{
- c.create(a.dims, a.size, CV_8UC1);
- NAryMatNDIterator it(a, b, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- compare( it.planes[0], it.planes[1], it.planes[2], cmpop );
-}
-
-void compare(const MatND& a, double s, MatND& c, int cmpop)
-{
- c.create(a.dims, a.size, CV_8UC1);
- NAryMatNDIterator it(a, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- compare( it.planes[0], s, it.planes[1], cmpop );
-}
-
-void min(const MatND& a, const MatND& b, MatND& c)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- min( it.planes[0], it.planes[1], it.planes[2] );
-}
-
-void min(const MatND& a, double alpha, MatND& c)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- min( it.planes[0], alpha, it.planes[1] );
-}
-
-void max(const MatND& a, const MatND& b, MatND& c)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- max( it.planes[0], it.planes[1], it.planes[2] );
-}
-
-void max(const MatND& a, double alpha, MatND& c)
-{
- c.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, c);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- max( it.planes[0], alpha, it.planes[1] );
-}
-
-void sqrt(const MatND& a, MatND& b)
-{
- b.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- sqrt( it.planes[0], it.planes[1] );
-}
-
-void pow(const MatND& a, double power, MatND& b)
-{
- b.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- pow( it.planes[0], power, it.planes[1] );
-}
-
-void exp(const MatND& a, MatND& b)
-{
- b.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- exp( it.planes[0], it.planes[1] );
-}
-
-void log(const MatND& a, MatND& b)
-{
- b.create(a.dims, a.size, a.type());
- NAryMatNDIterator it(a, b);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- log( it.planes[0], it.planes[1] );
-}
-
-bool checkRange(const MatND& a, bool quiet, int*,
- double minVal, double maxVal)
-{
- NAryMatNDIterator it(a);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- {
- Point pt;
- if( !checkRange( it.planes[0], quiet, &pt, minVal, maxVal ))
- {
- // todo: set index properly
- return false;
- }
- }
- return true;
-}
-
+ if( a.m != b.m )
+ return INT_MAX;
+ if( a.sliceEnd == b.sliceEnd )
+ return (b.ptr - a.ptr)/b.elemSize;
+ return b.lpos() - a.lpos();
+}
+
//////////////////////////////// SparseMat ////////////////////////////////
template<typename T1, typename T2> void
}
-SparseMat::SparseMat(const Mat& m, bool try1d)
-: flags(MAGIC_VAL), hdr(0)
-{
- bool is1d = try1d && m.cols == 1;
-
- if( is1d )
- {
- int i, M = m.rows;
- const uchar* data = m.data;
- size_t step = m.step, esz = m.elemSize();
- create( 1, &M, m.type() );
- for( i = 0; i < M; i++ )
- {
- const uchar* from = data + step*i;
- if( isZeroElem(from, esz) )
- continue;
- uchar* to = newNode(&i, hash(i));
- copyElem(from, to, esz);
- }
- }
- else
- {
- int i, j, size[] = {m.rows, m.cols};
- const uchar* data = m.data;
- size_t step = m.step, esz = m.elemSize();
- create( 2, size, m.type() );
- for( i = 0; i < m.rows; i++ )
- {
- for( j = 0; j < m.cols; j++ )
- {
- const uchar* from = data + step*i + esz*j;
- if( isZeroElem(from, esz) )
- continue;
- int idx[] = {i, j};
- uchar* to = newNode(idx, hash(i, j));
- copyElem(from, to, esz);
- }
- }
- }
-}
-
-SparseMat::SparseMat(const MatND& m)
+SparseMat::SparseMat(const Mat& m)
: flags(MAGIC_VAL), hdr(0)
{
create( m.dims, m.size, m.type() );
}
void SparseMat::copyTo( Mat& m ) const
-{
- CV_Assert( hdr && hdr->dims <= 2 );
- m.create( hdr->size[0], hdr->dims == 2 ? hdr->size[1] : 1, type() );
- m = Scalar(0);
-
- SparseMatConstIterator from = begin();
- size_t i, N = nzcount(), esz = elemSize();
-
- if( hdr->dims == 2 )
- {
- for( i = 0; i < N; i++, ++from )
- {
- const Node* n = from.node();
- uchar* to = m.data + m.step*n->idx[0] + esz*n->idx[1];
- copyElem( from.ptr, to, esz );
- }
- }
- else
- {
- for( i = 0; i < N; i++, ++from )
- {
- const Node* n = from.node();
- uchar* to = m.data + esz*n->idx[0];
- copyElem( from.ptr, to, esz );
- }
- }
-}
-
-void SparseMat::copyTo( MatND& m ) const
{
CV_Assert( hdr );
m.create( dims(), hdr->size, type() );
rtype = type();
rtype = CV_MAKETYPE(rtype, cn);
- CV_Assert( hdr && hdr->dims <= 2 );
- m.create( hdr->size[0], hdr->dims == 2 ? hdr->size[1] : 1, type() );
- m = Scalar(beta);
-
- SparseMatConstIterator from = begin();
- size_t i, N = nzcount(), esz = CV_ELEM_SIZE(rtype);
-
- if( alpha == 1 && beta == 0 )
- {
- ConvertData cvtfunc = getConvertData(type(), rtype);
-
- if( hdr->dims == 2 )
- {
- for( i = 0; i < N; i++, ++from )
- {
- const Node* n = from.node();
- uchar* to = m.data + m.step*n->idx[0] + esz*n->idx[1];
- cvtfunc( from.ptr, to, cn );
- }
- }
- else
- {
- for( i = 0; i < N; i++, ++from )
- {
- const Node* n = from.node();
- uchar* to = m.data + esz*n->idx[0];
- cvtfunc( from.ptr, to, cn );
- }
- }
- }
- else
- {
- ConvertScaleData cvtfunc = getConvertScaleData(type(), rtype);
-
- if( hdr->dims == 2 )
- {
- for( i = 0; i < N; i++, ++from )
- {
- const Node* n = from.node();
- uchar* to = m.data + m.step*n->idx[0] + esz*n->idx[1];
- cvtfunc( from.ptr, to, cn, alpha, beta );
- }
- }
- else
- {
- for( i = 0; i < N; i++, ++from )
- {
- const Node* n = from.node();
- uchar* to = m.data + esz*n->idx[0];
- cvtfunc( from.ptr, to, cn, alpha, beta );
- }
- }
- }
-}
-
-void SparseMat::convertTo( MatND& m, int rtype, double alpha, double beta ) const
-{
- int cn = channels();
- if( rtype < 0 )
- rtype = type();
- rtype = CV_MAKETYPE(rtype, cn);
-
CV_Assert( hdr );
m.create( dims(), hdr->size, rtype );
m = Scalar(beta);
void write( FileStorage& fs, const string& name, const Mat& value )
{
- CvMat mat = value;
- cvWrite( *fs, name.size() ? name.c_str() : 0, &mat );
+ if( value.dims <= 2 )
+ {
+ CvMat mat = value;
+ cvWrite( *fs, name.size() ? name.c_str() : 0, &mat );
+ }
+ else
+ {
+ CvMatND mat = value;
+ cvWrite( *fs, name.size() ? name.c_str() : 0, &mat );
+ }
}
-void write( FileStorage& fs, const string& name, const MatND& value )
-{
- CvMatND mat = value;
- cvWrite( *fs, name.size() ? name.c_str() : 0, &mat );
-}
-
// TODO: the 4 functions below need to be implemented more efficiently
void write( FileStorage& fs, const string& name, const SparseMat& value )
{
default_mat.copyTo(mat);
return;
}
- Ptr<CvMat> m = (CvMat*)cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node);
- CV_Assert(CV_IS_MAT(m));
- Mat(m).copyTo(mat);
-}
-
-void read( const FileNode& node, MatND& mat, const MatND& default_mat )
-{
- if( node.empty() )
+ void* obj = cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node);
+ if(CV_IS_MAT(obj))
{
- default_mat.copyTo(mat);
- return;
+ Mat((const CvMat*)obj).copyTo(mat);
+ cvReleaseMat((CvMat**)&obj);
+ }
+ else if(CV_IS_MATND(obj))
+ {
+ Mat((const CvMatND*)obj).copyTo(mat);
+ cvReleaseMatND((CvMatND**)&obj);
+ }
+ else
+ {
+ cvRelease(&obj);
+ CV_Error(CV_StsBadArg, "Unknown array type");
}
- Ptr<CvMatND> m = (CvMatND*)cvRead((CvFileStorage*)node.fs, (CvFileNode*)*node);
- CV_Assert(CV_IS_MATND(m));
- MatND(m).copyTo(mat);
}
-
+
void read( const FileNode& node, SparseMat& mat, const SparseMat& default_mat )
{
if( node.empty() )
Randn_<float,float>,
Randn_<double,double>, 0}
};
-
+
int depth = mat.depth(), channels = mat.channels();
double dparam[2][12];
float fparam[2][12];
}
CV_Assert( func != 0);
- func( mat, &state, param );
-}
-
-void RNG::fill( MatND& mat, int disttype, const Scalar& param1, const Scalar& param2 )
-{
- NAryMatNDIterator it(mat);
-
- for( int i = 0; i < it.nplanes; i++, ++it )
- fill( it.planes[0], disttype, param1, param2 );
+
+ if( mat.dims > 2 )
+ {
+ const Mat* arrays[] = {&mat, 0};
+ Mat planes[1];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ func( it.planes[0], &state, param );
+ }
+ else
+ func( mat, &state, param );
}
#ifdef WIN32
sum_<Vec<double, 4>, Vec<double, 4> >, 0
};
- Size size = m.size();
- SumFunc func;
-
CV_Assert( m.channels() <= 4 );
- func = tab[m.type()];
+ SumFunc func = tab[m.type()];
CV_Assert( func != 0 );
+ if( m.dims > 2 )
+ {
+ const Mat* arrays[] = {&m, 0};
+ Mat planes[1];
+ NAryMatIterator it(arrays, planes);
+ Scalar s;
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ s += func(it.planes[0]);
+ return s;
+ }
+
return func(m);
}
CountNonZeroFunc func = tab[m.depth()];
CV_Assert( m.channels() == 1 && func != 0 );
+
+ if( m.dims > 2 )
+ {
+ const Mat* arrays[] = {&m, 0};
+ Mat planes[1];
+ NAryMatIterator it(arrays, planes);
+ int nz = 0;
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ nz += func(it.planes[0]);
+ return nz;
+ }
+
return func(m);
}
Scalar mean(const Mat& m)
{
- return sum(m)*(1./std::max(m.rows*m.cols, 1));
+ return sum(m)*(1./m.total());
}
Scalar mean( const Mat& m, const Mat& mask )
if( !mask.data )
return mean(m);
- CV_Assert( m.channels() <= 4 && m.size() == mask.size() && mask.type() == CV_8U );
+ CV_Assert( m.channels() <= 4 && mask.type() == CV_8U );
MeanMaskFunc func = tab[m.type()];
CV_Assert( func != 0 );
-
+
+ if( m.dims > 2 )
+ {
+ const Mat* arrays[] = {&m, &mask, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+ double total = 0;
+ Scalar s;
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ {
+ int n = countNonZero(it.planes[1]);
+ s += mean(it.planes[0], it.planes[1])*(double)n;
+ total += n;
+ }
+ return (s * 1./std::max(total, 1.));
+ }
+
+ CV_Assert( m.size() == mask.size() );
return func( m, mask );
}
meanStdDevMask_<SqrC4<double, double> >, 0
};
- CV_Assert( m.channels() <= 4 );
+ CV_Assert( m.channels() <= 4 && (mask.empty() || mask.type() == CV_8U) );
- if( !mask.data )
+ MeanStdDevFunc func = tab[m.type()];
+ MeanStdDevMaskFunc mfunc = mtab[m.type()];
+ CV_Assert( func != 0 || mfunc != 0 );
+
+ if( m.dims > 2 )
{
- MeanStdDevFunc func = tab[m.type()];
- CV_Assert( func != 0 );
- func( m, mean, stddev );
+ Scalar s, sq;
+ double total = 0;
+
+ const Mat* arrays[] = {&m, &mask, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+ int k, cn = m.channels();
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ {
+ Scalar _mean, _stddev;
+ double nz = (double)(mask.data ? countNonZero(it.planes[1]) : it.planes[0].rows*it.planes[0].cols);
+
+ if( func )
+ func(it.planes[0], _mean, _stddev);
+ else
+ mfunc(it.planes[0], it.planes[1], _mean, _stddev);
+
+ total += nz;
+ for( k = 0; k < cn; k++ )
+ {
+ s[k] += _mean[k]*nz;
+ sq[k] += (_stddev[k]*_stddev[k] + _mean[k]*_mean[k])*nz;
+ }
+ }
+
+ mean = stddev = Scalar();
+ total = 1./std::max(total, 1.);
+ for( k = 0; k < cn; k++ )
+ {
+ mean[k] = s[k]*total;
+ stddev[k] = std::sqrt(std::max(sq[k]*total - mean[k]*mean[k], 0.));
+ }
+ return;
}
- else
+
+ if( mask.data )
{
- MeanStdDevMaskFunc func = mtab[m.type()];
- CV_Assert( mask.size() == m.size() && mask.type() == CV_8U && func != 0 );
- func( m, mask, mean, stddev );
+ CV_Assert( mask.size() == m.size() );
+ mfunc( m, mask, mean, stddev );
}
+ else
+ func( m, mean, stddev );
}
void minMaxLoc( const Mat& img, double* minVal, double* maxVal,
Point* minLoc, Point* maxLoc, const Mat& mask )
{
+ CV_Assert(img.dims <= 2);
+
static MinMaxIndxFunc tab[] =
{minMaxIndx_<uchar>, 0, minMaxIndx_<ushort>, minMaxIndx_<short>,
minMaxIndx_<int>, minMaxIndx_<float>, minMaxIndx_<double>, 0};
}
}
+static void ofs2idx(const Mat& a, size_t ofs, int* idx)
+{
+ int i, d = a.dims;
+ for( i = 0; i < d; i++ )
+ {
+ idx[i] = (int)(ofs / a.step[i]);
+ ofs %= a.step[i];
+ }
+}
+
+void minMaxIndx(const Mat& a, double* minVal,
+ double* maxVal, int* minIdx, int* maxIdx,
+ const Mat& mask)
+{
+ if( a.dims <= 2 )
+ {
+ Point minLoc, maxLoc;
+ minMaxLoc(a, minVal, maxVal, &minLoc, &maxLoc, mask);
+ if( minIdx )
+ minIdx[0] = minLoc.x, minIdx[1] = minLoc.y;
+ if( maxIdx )
+ maxIdx[0] = maxLoc.x, maxIdx[1] = maxLoc.y;
+ return;
+ }
+
+ const Mat* arrays[] = {&a, &mask, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+ double minval = DBL_MAX, maxval = -DBL_MAX;
+ size_t minofs = 0, maxofs = 0, esz = a.elemSize();
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ {
+ double val0 = 0, val1 = 0;
+ Point pt0, pt1;
+ minMaxLoc( it.planes[0], &val0, &val1, &pt0, &pt1, it.planes[1] );
+ if( val0 < minval )
+ {
+ minval = val0;
+ minofs = (it.planes[0].data - a.data) + pt0.x*esz;
+ }
+ if( val1 > maxval )
+ {
+ maxval = val1;
+ maxofs = (it.planes[0].data - a.data) + pt1.x*esz;
+ }
+ }
+
+ if( minVal )
+ *minVal = minval;
+ if( maxVal )
+ *maxVal = maxval;
+ if( minIdx )
+ ofs2idx(a, minofs, minIdx);
+ if( maxIdx )
+ ofs2idx(a, maxofs, maxIdx);
+}
+
/****************************************************************************************\
* norm *
\****************************************************************************************/
CV_Assert(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2);
NormFunc func = tab[normType >> 1][a.depth()];
CV_Assert(func != 0);
- double r = func(a);
+
+ double r = 0;
+ if( a.dims > 2 )
+ {
+ const Mat* arrays[] = {&a, 0};
+ Mat planes[1];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ {
+ double n = func(it.planes[0]);
+ if( normType == NORM_INF )
+ r = std::max(r, n);
+ else
+ r += n;
+ }
+ }
+ else
+ r = func(a);
+
return normType == NORM_L2 ? std::sqrt(r) : r;
}
normType &= 7;
CV_Assert((normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2) &&
- a.size() == mask.size() && mask.type() == CV_8U && a.channels() == 1);
+ mask.type() == CV_8U && a.channels() == 1);
NormMaskFunc func = tab[normType >> 1][a.depth()];
CV_Assert(func != 0);
- double r = func(a, mask);
+
+ double r = 0;
+ if( a.dims > 2 )
+ {
+ const Mat* arrays[] = {&a, &mask, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ {
+ double n = func(it.planes[0], it.planes[1]);
+ if( normType == NORM_INF )
+ r = std::max(r, n);
+ else
+ r += n;
+ }
+ }
+ else
+ {
+ CV_Assert( a.size() == mask.size() );
+ r = func(a, mask);
+ }
+
return normType == NORM_L2 ? std::sqrt(r) : r;
}
}
};
- CV_Assert( a.type() == b.type() && a.size() == b.size() );
-
+ CV_Assert( a.type() == b.type() );
bool isRelative = (normType & NORM_RELATIVE) != 0;
normType &= 7;
CV_Assert(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2);
-
NormDiffFunc func = tab[normType >> 1][a.depth()];
CV_Assert(func != 0);
- double r = func( a, b );
+
+ double r = 0.;
+ if( a.dims > 2 )
+ {
+ const Mat* arrays[] = {&a, &b, 0};
+ Mat planes[2];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ {
+ double n = func(it.planes[0], it.planes[1]);
+
+ if( normType == NORM_INF )
+ r = std::max(r, n);
+ else
+ r += n;
+ }
+ }
+ else
+ {
+ CV_Assert( a.size() == b.size() );
+ r = func( a, b );
+ }
if( normType == NORM_L2 )
r = std::sqrt(r);
if( isRelative )
if( !mask.data )
return norm(a, b, normType);
- CV_Assert( a.type() == b.type() && a.size() == b.size() &&
- a.size() == mask.size() && mask.type() == CV_8U && a.channels() == 1);
-
+ CV_Assert( a.type() == b.type() && mask.type() == CV_8U && a.channels() == 1);
bool isRelative = (normType & NORM_RELATIVE) != 0;
normType &= 7;
CV_Assert(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2);
NormDiffMaskFunc func = tab[normType >> 1][a.depth()];
CV_Assert(func != 0);
- double r = func( a, b, mask );
+
+ double r = 0.;
+ if( a.dims > 2 )
+ {
+ const Mat* arrays[] = {&a, &b, &mask, 0};
+ Mat planes[3];
+ NAryMatIterator it(arrays, planes);
+
+ for( int i = 0; i < it.nplanes; i++, ++it )
+ {
+ double n = func(it.planes[0], it.planes[1], it.planes[2]);
+
+ if( normType == NORM_INF )
+ r = std::max(r, n);
+ else
+ r += n;
+ }
+ }
+ else
+ {
+ CV_Assert( a.size() == b.size() && a.size() == mask.size() );
+ r = func( a, b, mask );
+ }
+
if( normType == NORM_L2 )
r = std::sqrt(r);
if( isRelative )