1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 00:03:03 +04:00

Merge pull request #27757 from vpisarev:matshape_inside_mat

Use MatShape instead of MatSize inside cv::Mat/cv::UMat #27757

**Merge together with https://github.com/opencv/opencv_contrib/pull/3996**
---

This PR continues cv::Mat/cv::UMat refactoring. See #26056, where `MatShape` was introduced. Now it's put inside cv::Mat/cv::UMat instead of a weird `MatSize`. MatSize is now an alias for MatShape:

**before:**

```
struct MatShape { ... };
struct MatSize { ... };

struct Mat {
    ...
    int dims;
    int rows;
    int cols;

    ...

    MatShape shape() const { ... /* constructs MatShape out of MatSize and returns it;
                                    layout is always 'unknown', because we don't store it */ }

    MatSize size; // size is not valid without the parent cv::Mat,
                  // because size.p may point to Mat::rows or to Mat::cols,
                  // depending on the dimensionality, and dims() returns Mat::dims.
    MatStep step; // may allocate memory, depending on the dimensionality.
    ...
};
```

**after:**

```
struct MatShape { ... };
typedef MatShape MatSize; // they are now synonyms

struct Mat {
    ...
    int dims;
    int rows;
    int cols;

    ...

    MatShape shape() const { return size; } // just return the embedded shape (including the proper layout information)

    MatSize size; // size is self-contained data structure that can be used without the parent cv::Mat.
                  // size.dims is now a copy of dims; size.p[*] contains copies of Mat::rows and Mat::cols when dims <= 2.
    MatStep step; // does not allocate extra memory buffers.
    ...
};
```

There are several reasons to do that:

1. the main reason is to be able to store data layout (MatShape::layout) inside each cv::Mat/cv::UMat. This is necessary for the proper shape inference in DNN module. In particular, it's necessary for the next step of DNN inference optimization where we introduce block-layout-optimized convolution and other operations. Later on, we can use layout information to support non-interleaved images (e.g. RRR...GGG...BBB...) or even batches of such images in core/imgproc modules.
2. the other reason is to represent 3D/4D/5D etc. tensors as cv::Mat/cv::UMat instances more conveniently, without extra dynamic memory allocation. Before this patch we allocated some memory buffers dynamically to store shape & steps for more than 2D arrays. Now the whole cv::Mat/cv::UMat header can be stored completely on stack/in a container. Creating another copy of Mat/UMat header is now done more efficiently.
3. the third reason is to introduce the new coding pattern: `dst.create(src.size, <dst_type>);`. The pattern is suitable for most of element-wise (including cloning) and filtering operations. This pattern does not only look crisp and self-documenting, it will also automatically copy shape (including layout) from the source tensor into the destination matrix/tensor.
4. in the future we might add `colorspace` member to MatShape that will allow to distinguish RGB from BGR or NV12. `dst.create(src.size, <dst_type>);` will then copy the colorspace information as well.

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Vadim Pisarevsky
2025-09-15 15:03:34 +03:00
committed by GitHub
parent abcfb3c1e7
commit bdab54f79e
52 changed files with 521 additions and 624 deletions
@@ -751,7 +751,7 @@ namespace cv {
inline
Mat::Mat(const cuda::GpuMat& m)
: flags(0), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows)
: flags(0), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0)
{
m.download(*this);
}
@@ -169,16 +169,22 @@ std::ostream& operator << (std::ostream& out, const Rect_<_Tp>& rect)
return out << "[" << rect.width << " x " << rect.height << " from (" << rect.x << ", " << rect.y << ")]";
}
static inline std::ostream& operator << (std::ostream& out, const MatSize& msize)
static inline std::ostream& operator << (std::ostream& strm, const MatShape& shape)
{
int i, dims = msize.dims();
for( i = 0; i < dims; i++ )
{
out << msize[i];
if( i < dims-1 )
out << " x ";
strm << '[';
if (shape.empty()) {
strm << "<empty>";
} else {
size_t n = shape.size();
if (n == 0) {
strm << "<scalar>";
} else {
for(size_t i = 0; i < n; ++i)
strm << (i > 0 ? " x " : "") << shape[i];
}
}
return out;
strm << "]";
return strm;
}
static inline std::ostream &operator<< (std::ostream &s, cv::Range &r)
+22 -20
View File
@@ -148,8 +148,9 @@ struct CV_EXPORTS_W_SIMPLE MatShape
const int& back() const;
void push_back(int value);
void emplace_back(int value);
int& operator [](size_t idx);
const int& operator [](size_t idx) const;
int& operator [](size_t idx);
Size operator()() const; // for compatibility with MatSize
CV_WRAP bool hasSymbols() const; // negative elements in the shape may denote 'symbols' instead of actual values.
@@ -162,7 +163,7 @@ struct CV_EXPORTS_W_SIMPLE MatShape
size_t total() const; // returns the total number of elements in the tensor (including padding elements, i.e. the method ignores 'C' in the case of block layout). Returns 1 for scalar tensors. Returns 0 for empty shapes.
operator std::vector<int>() const;
std::vector<int> vec() const;
std::string str() const;
int dims;
@@ -723,20 +724,7 @@ struct CV_EXPORTS UMatData
};
CV_ENUM_FLAGS(UMatData::MemoryFlag)
struct CV_EXPORTS MatSize
{
explicit MatSize(int* _p) CV_NOEXCEPT;
int dims() const CV_NOEXCEPT;
Size operator()() const;
const int& operator[](int i) const;
int& operator[](int i);
operator const int*() const CV_NOEXCEPT; // TODO OpenCV 4.0: drop this
bool operator == (const MatSize& sz) const CV_NOEXCEPT;
bool operator != (const MatSize& sz) const CV_NOEXCEPT;
int* p;
};
typedef MatShape MatSize;
struct CV_EXPORTS MatStep
{
@@ -746,11 +734,9 @@ struct CV_EXPORTS MatStep
size_t& operator[](int i) CV_NOEXCEPT;
operator size_t() const;
MatStep& operator = (size_t s);
void clear();
size_t* p;
size_t buf[3];
protected:
MatStep& operator = (const MatStep&);
size_t p[MatShape::MAX_DIMS];
};
/** @example samples/cpp/cout_mat.cpp
@@ -1633,6 +1619,12 @@ public:
*/
CV_NODISCARD_STD static MatExpr zeros(int ndims, const int* sz, int type);
/** @overload
@param shape Array shape.
@param type Created matrix type.
*/
CV_NODISCARD_STD static MatExpr zeros(const MatShape& shape, int type);
/** @brief Returns an array of all 1's of the specified size and type.
The method returns a Matlab-style 1's array initializer, similarly to Mat::zeros. Note that using
@@ -1664,6 +1656,12 @@ public:
*/
CV_NODISCARD_STD static MatExpr ones(int ndims, const int* sz, int type);
/** @overload
@param shape Array shape.
@param type Created matrix type.
*/
CV_NODISCARD_STD static MatExpr ones(const MatShape& shape, int type);
/** @brief Returns an identity matrix of the specified size and type.
The method returns a Matlab-style identity matrix initializer, similarly to Mat::zeros. Similarly to
@@ -2745,6 +2743,8 @@ public:
//! constructs n-dimensional matrix
UMat(int ndims, const int* sizes, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
UMat(int ndims, const int* sizes, int type, const Scalar& s, UMatUsageFlags usageFlags = USAGE_DEFAULT);
UMat(const MatShape& shape, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
UMat(const MatShape& shape, int type, const Scalar& s, UMatUsageFlags usageFlags = USAGE_DEFAULT);
//! copy constructor
UMat(const UMat& m);
@@ -2816,9 +2816,11 @@ public:
CV_NODISCARD_STD static UMat zeros(int rows, int cols, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
CV_NODISCARD_STD static UMat zeros(Size size, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
CV_NODISCARD_STD static UMat zeros(int ndims, const int* sz, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
CV_NODISCARD_STD static UMat zeros(const MatShape& shape, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
CV_NODISCARD_STD static UMat ones(int rows, int cols, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
CV_NODISCARD_STD static UMat ones(Size size, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
CV_NODISCARD_STD static UMat ones(int ndims, const int* sz, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
CV_NODISCARD_STD static UMat ones(const MatShape& shape, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
CV_NODISCARD_STD static UMat eye(int rows, int cols, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
CV_NODISCARD_STD static UMat eye(Size size, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT);
+58 -40
View File
@@ -94,16 +94,24 @@ inline const int* MatShape::data() const { return p; }
inline int& MatShape::operator [](size_t idx)
{
CV_Assert(idx < (size_t)(dims >= 0 ? dims : 1));
CV_Assert(idx < (size_t)(dims > 0 ? dims : 1));
return p[idx];
}
inline const int& MatShape::operator [](size_t idx) const
{
CV_Assert(idx < (size_t)(dims >= 0 ? dims : 1));
CV_Assert(idx < (size_t)(dims > 0 ? dims : 1));
return p[idx];
}
inline Size MatShape::operator()() const
{
CV_Assert(dims <= 2);
int cols = dims > 0 ? p[dims > 1] : int(dims >= 0);
int rows = dims > 1 ? p[0] : int(dims >= 0);
return Size(cols, rows);
}
template<typename _It> inline MatShape::MatShape(_It begin, _It end)
{
int buf[MAX_DIMS];
@@ -540,11 +548,10 @@ template<typename _Tp> inline
Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(1), rows(1),
cols((int)vec.size()), data(0), datastart(0), dataend(0), datalimit(0),
allocator(0), u(0), size(&cols)
allocator(0), u(0), size(1)
{
step.buf[1] = sizeof(_Tp);
step.buf[0] = cols*step.buf[1];
step.p = &step.buf[1];
size[0] = cols;
step[0] = sizeof(_Tp);
if(vec.empty())
return;
@@ -585,11 +592,10 @@ template<typename _Tp, std::size_t _Nm> inline
Mat::Mat(const std::array<_Tp, _Nm>& arr, bool copyData)
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(1), rows(1),
cols((int)arr.size()), data(0), datastart(0), dataend(0), datalimit(0),
allocator(0), u(0), size(&cols), step(0)
allocator(0), u(0), size(1), step(0)
{
step.buf[1] = sizeof(_Tp);
step.buf[0] = cols*step.buf[1];
step.p = &step.buf[1];
size[0] = cols;
step[0] = sizeof(_Tp);
if(arr.empty())
return;
@@ -605,13 +611,12 @@ Mat::Mat(const std::array<_Tp, _Nm>& arr, bool copyData)
template<typename _Tp, int n> inline
Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(1), rows(1), cols(n), data(0),
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&cols), step(0)
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(1), step(0)
{
if( !copyData )
{
step.p = &step.buf[1];
step.buf[1] = sizeof(_Tp);
step.buf[0] = cols*step.buf[1];
size[0] = cols;
step[0] = sizeof(_Tp);
datastart = data = (uchar*)vec.val;
datalimit = dataend = datastart + cols * step[0];
}
@@ -623,13 +628,14 @@ Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
template<typename _Tp, int m, int n> inline
Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0),
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(2), step(0)
{
if( !copyData )
{
step.p = &step.buf[0];
step.buf[1] = sizeof(_Tp);
step.buf[0] = n*sizeof(_Tp);
size[1] = cols;
size[0] = rows;
step[1] = sizeof(_Tp);
step[0] = n*sizeof(_Tp);
datastart = data = (uchar*)M.val;
datalimit = dataend = datastart + rows * step[0];
}
@@ -640,13 +646,12 @@ Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
template<typename _Tp> inline
Mat::Mat(const Point_<_Tp>& pt, bool copyData)
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(1), rows(1), cols(2), data(0),
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&cols), step(0)
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(1), step(0)
{
if( !copyData )
{
step.p = &step.buf[1];
step.buf[1] = sizeof(_Tp);
step.buf[0] = cols*step.buf[1];
size[0] = cols;
step[0] = sizeof(_Tp);
datastart = data = (uchar*)&pt.x;
datalimit = dataend = datastart + cols * step[0];
}
@@ -661,20 +666,20 @@ Mat::Mat(const Point_<_Tp>& pt, bool copyData)
template<typename _Tp> inline
Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0),
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(1), rows(1), cols(3), data(0),
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(1), step(0)
{
if( !copyData )
{
step.p = &step.buf[1];
step.buf[1] = sizeof(_Tp);
step.buf[0] = cols*step.buf[1];
size[0] = cols;
step[0] = sizeof(_Tp);
datastart = data = (uchar*)&pt.x;
datalimit = dataend = datastart + cols * step[0];
}
else
{
create(3, 1, traits::Type<_Tp>::value);
int sz = 3;
create(1, &sz, traits::Type<_Tp>::value);
((_Tp*)data)[0] = pt.x;
((_Tp*)data)[1] = pt.y;
((_Tp*)data)[2] = pt.z;
@@ -684,7 +689,7 @@ Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
template<typename _Tp> inline
Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0),
datastart(0), dataend(0), allocator(0), u(0), size(&rows)
datastart(0), dataend(0), allocator(0), u(0)
{
*this = commaInitializer.operator Mat_<_Tp>();
}
@@ -791,6 +796,12 @@ int Mat::channels() const
return CV_MAT_CN(flags);
}
inline
MatShape Mat::shape() const
{
return size;
}
inline
uchar* Mat::ptr(int y)
{
@@ -1093,9 +1104,9 @@ const _Tp& Mat::at(int i0) const
if( isContinuous() || rows == 1 )
return ((const _Tp*)data)[i0];
if( cols == 1 )
return *(const _Tp*)(data + step.buf[0] * i0);
return *(const _Tp*)(data + step[0] * i0);
int i = i0 / cols, j = i0 - i * cols;
return ((const _Tp*)(data + step.buf[0] * i))[j];
return ((const _Tp*)(data + step[0] * i))[j];
}
template<typename _Tp> inline
@@ -1287,6 +1298,10 @@ void Mat::push_back(const _Tp& elem)
if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
{
*(_Tp*)(data + (size.p[0]++) * step.p[0]) = elem;
if (dims == 2)
rows = size.p[0];
else if (dims == 1)
cols = size.p[0];
dataend = tmp;
}
else
@@ -1315,6 +1330,7 @@ void Mat::push_back(const std::vector<_Tp>& v)
///////////////////////////// MatSize ////////////////////////////
/*
inline
MatSize::MatSize(int* _p) CV_NOEXCEPT
: p(_p) {}
@@ -1364,21 +1380,21 @@ bool MatSize::operator != (const MatSize& sz) const CV_NOEXCEPT
{
return !(*this == sz);
}
*/
///////////////////////////// MatStep ////////////////////////////
inline
MatStep::MatStep() CV_NOEXCEPT
{
p = buf; p[0] = p[1] = 0; p[2] = 153;
clear();
}
inline
MatStep::MatStep(size_t s) CV_NOEXCEPT
{
p = buf; p[0] = s; p[1] = 0; p[2] = 153;
clear();
p[0] = s;
}
inline
@@ -1395,18 +1411,20 @@ size_t& MatStep::operator[](int i) CV_NOEXCEPT
inline MatStep::operator size_t() const
{
CV_DbgAssert( p == buf || p == buf+1 );
return *p;
return p[0];
}
inline MatStep& MatStep::operator = (size_t s)
{
CV_DbgAssert( p == buf || p == buf+1 );
*p = s;
p[0] = s;
return *this;
}
inline void MatStep::clear()
{
for (int i = 0; i < MatShape::MAX_DIMS; i++)
p[i] = 0;
}
////////////////////////////// Mat_<_Tp> ////////////////////////////
+1 -1
View File
@@ -1623,7 +1623,7 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op)
int cn = src1.channels();
_dst.create(src1.dims, src1.size, CV_8UC(cn));
_dst.create(src1.size, CV_8UC(cn));
src1 = src1.reshape(1); src2 = src2.reshape(1);
Mat dst = _dst.getMat().reshape(1);
+1 -1
View File
@@ -164,7 +164,7 @@ void Mat::convertTo(OutputArray dst, int type_, double alpha, double beta) const
bool allowTransposed = dims == 1 ||
dst.kind() == _InputArray::STD_VECTOR ||
(dst.fixedSize() && dst.dims() == 1);
dst.create( dims, size, dtype, -1, allowTransposed );
dst.create( size, dtype, -1, allowTransposed );
Mat dstMat = dst.getMat();
if( dims <= 2 )
+1 -1
View File
@@ -94,7 +94,7 @@ void convertScaleAbs(InputArray _src, OutputArray _dst, double alpha, double bet
Mat src = _src.getMat();
int cn = src.channels();
double scale[] = {alpha, beta};
_dst.create( src.dims, src.size, CV_8UC(cn) );
_dst.create( src.size, CV_8UC(cn) );
Mat dst = _dst.getMat();
BinaryFunc func = getCvtScaleAbsFunc(src.depth());
CV_Assert( func != 0 );
+2 -2
View File
@@ -520,7 +520,7 @@ void Mat::copyTo( OutputArray _dst ) const
return;
}
_dst.create( dims, size, stype );
_dst.create( size, stype );
Mat dst = _dst.getMat();
if( data == dst.data )
return;
@@ -595,7 +595,7 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
Mat dst;
{
Mat dst0 = _dst.getMat();
_dst.create(dims, size, type()); // TODO Prohibit 'dst' re-creation, user should pass it explicitly with correct size/type or empty
_dst.create(size, type()); // TODO Prohibit 'dst' re-creation, user should pass it explicitly with correct size/type or empty
dst = _dst.getMat();
if (dst.data != dst0.data) // re-allocation happened
+1 -1
View File
@@ -2389,7 +2389,7 @@ static bool ocl_dft(InputArray _src, OutputArray _dst, int flags, int nonzero_ro
else
{
_dst.createSameSize(src, CV_MAKETYPE(depth, 1));
output.create(src.dims, src.size, CV_MAKETYPE(depth, 2));
output.create(src.size, CV_MAKETYPE(depth, 2));
}
}
+9 -9
View File
@@ -155,7 +155,7 @@ void magnitude( InputArray src1, InputArray src2, OutputArray dst )
ocl_math_op(src1, src2, dst, OCL_OP_MAG))
Mat X = src1.getMat(), Y = src2.getMat();
dst.create(X.dims, X.size, X.type());
dst.create(X.size, X.type());
Mat Mag = dst.getMat();
const Mat* arrays[] = {&X, &Y, &Mag, 0};
@@ -191,7 +191,7 @@ void phase( InputArray src1, InputArray src2, OutputArray dst, bool angleInDegre
ocl_math_op(src1, src2, dst, angleInDegrees ? OCL_OP_PHASE_DEGREES : OCL_OP_PHASE_RADIANS))
Mat X = src1.getMat(), Y = src2.getMat();
dst.create( X.dims, X.size, type );
dst.create( X.size, type );
Mat Angle = dst.getMat();
const Mat* arrays[] = {&X, &Y, &Angle, 0};
@@ -288,8 +288,8 @@ void cartToPolar( InputArray src1, InputArray src2,
Mat X = src1.getMat(), Y = src2.getMat();
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));
dst1.create( X.dims, X.size, type );
dst2.create( X.dims, X.size, type );
dst1.create( X.size, type );
dst2.create( X.size, type );
Mat Mag = dst1.getMat(), Angle = dst2.getMat();
const Mat* arrays[] = {&X, &Y, &Mag, &Angle, 0};
@@ -393,8 +393,8 @@ void polarToCart( InputArray src1, InputArray src2,
Mat Mag = src1.getMat(), Angle = src2.getMat();
CV_Assert( Mag.empty() || Angle.size == Mag.size);
dst1.create( Angle.dims, Angle.size, type );
dst2.create( Angle.dims, Angle.size, type );
dst1.create( Angle.size, type );
dst2.create( Angle.size, type );
Mat X = dst1.getMat(), Y = dst2.getMat();
const Mat* arrays[] = {&Mag, &Angle, &X, &Y, 0};
@@ -445,7 +445,7 @@ void exp( InputArray _src, OutputArray _dst )
ocl_math_op(_src, noArray(), _dst, OCL_OP_EXP))
Mat src = _src.getMat();
_dst.create( src.dims, src.size, type );
_dst.create( src.size, type );
Mat dst = _dst.getMat();
const Mat* arrays[] = {&src, &dst, 0};
@@ -478,7 +478,7 @@ void log( InputArray _src, OutputArray _dst )
ocl_math_op(_src, noArray(), _dst, OCL_OP_LOG))
Mat src = _src.getMat();
_dst.create( src.dims, src.size, type );
_dst.create( src.size, type );
Mat dst = _dst.getMat();
const Mat* arrays[] = {&src, &dst, 0};
@@ -1032,7 +1032,7 @@ void pow( InputArray _src, double power, OutputArray _dst )
CV_OCL_RUN(useOpenCL, ocl_pow(_src, power, _dst, is_ipower, ipower))
Mat src = _src.getMat();
_dst.create( src.dims, src.size, type );
_dst.create( src.size, type );
Mat dst = _dst.getMat();
const Mat* arrays[] = {&src, &dst, 0};
+1 -1
View File
@@ -656,7 +656,7 @@ void scaleAdd(InputArray _src1, double alpha, InputArray _src2, OutputArray _dst
Mat src1 = _src1.getMat(), src2 = _src2.getMat();
CV_Assert(src1.size == src2.size);
_dst.create(src1.dims, src1.size, type);
_dst.create(src1.size, type);
Mat dst = _dst.getMat();
float falpha = (float)alpha;
+159 -230
View File
@@ -191,6 +191,13 @@ size_t MatShape::total() const
return result;
}
std::vector<int> MatShape::vec() const
{
if (dims < 0)
return std::vector<int>(1, 0);
return std::vector<int>(p, p + dims);
}
std::string MatShape::str() const
{
std::stringstream sstrm;
@@ -401,13 +408,6 @@ MatShape MatShape::expand(const MatShape& another) const
return result;
}
MatShape::operator std::vector<int>() const
{
if (dims < 0)
return std::vector<int>(1, 0);
return std::vector<int>(p, p + dims);
}
/////////////////////////// MatAllocator ////////////////////////////
void MatAllocator::map(UMatData*, AccessFlag) const
@@ -603,85 +603,31 @@ MatAllocator* Mat::getStdAllocator()
//==================================================================================================
bool MatSize::operator==(const MatSize& sz) const CV_NOEXCEPT
{
int d = dims();
int dsz = sz.dims();
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;
}
void setSize( Mat& m, int _dims, const int* _sz, const size_t* _steps, bool autoSteps)
{
CV_Assert( 0 <= _dims && _dims <= CV_MAX_DIM );
if( m.dims != _dims )
{
if( m.step.p != m.step.buf && m.step.p != m.step.buf+1)
{
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.rows = m.cols = -1;
}
}
CV_Assert( 0 <= _dims && _dims <= CV_MAX_DIM && _dims <= MatShape::MAX_DIMS);
m.dims = _dims;
size_t esz = CV_ELEM_SIZE(m.flags), esz1 = CV_ELEM_SIZE1(m.flags), total = esz;
if (_sz != 0) {
for( int i = _dims-1; i >= 0; i-- )
{
int s = _sz[i];
CV_Assert( s >= 0 );
m.size.p[i] = s;
if( _steps )
{
if (i < _dims-1)
{
if (_steps[i] % esz1 != 0)
{
CV_Error_(Error::BadStep, ("Step %zu for dimension %d must be a multiple of esz1 %zu", _steps[i], i, esz1));
}
m.step.p[i] = _steps[i];
}
else
{
m.step.p[i] = esz;
}
}
else if( autoSteps )
{
m.step.p[i] = total;
uint64 total1 = (uint64)total*s;
if( (uint64)total1 != (size_t)total1 )
CV_Error( cv::Error::StsOutOfRange, "The total matrix size does not fit to \"size_t\" type" );
total = (size_t)total1;
}
m.size = MatShape(_dims, _sz);
m.step[std::max(_dims-1, 0)] = CV_ELEM_SIZE(m.flags);
for (int i = _dims-2; i >= 0; i--) {
size_t autostep = m.size[i+1]*m.step[i+1];
if (_steps) {
m.step[i] = _steps[i];
//CV_Assert(m.step[i] >= autostep);
} else if (autoSteps) {
m.step[i] = autostep;
} else {
m.step[i] = 0;
}
}
if( _dims < 2 )
if( _dims <= 2 )
{
m.cols = _dims >= 1 && _sz ? _sz[0] : 1;
m.rows = 1;
m.size.p = &m.cols;
m.step.buf[0] = m.cols*esz;
m.step.buf[1] = esz;
m.step.p = &m.step.buf[1];
m.cols = _dims == 0 ? 1 : _sz ? _sz[_dims > 1] : 0;
m.rows = _dims < 2 ? 1 : _sz ? _sz[0] : 0;
} else {
m.cols = m.rows = -1;
}
}
@@ -743,19 +689,19 @@ void finalizeHdr(Mat& m)
Mat::Mat() CV_NOEXCEPT
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{}
Mat::Mat(int _rows, int _cols, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{
create(_rows, _cols, _type);
}
Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{
create(_rows, _cols, _type);
*this = _s;
@@ -763,14 +709,14 @@ Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
Mat::Mat(Size _sz, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{
create( _sz.height, _sz.width, _type );
}
Mat::Mat(Size _sz, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{
create(_sz.height, _sz.width, _type);
*this = _s;
@@ -778,14 +724,14 @@ Mat::Mat(Size _sz, int _type, const Scalar& _s)
Mat::Mat(int _dims, const int* _sz, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{
create(_dims, _sz, _type);
}
Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{
create(_dims, _sz, _type);
*this = _s;
@@ -793,14 +739,14 @@ Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s)
Mat::Mat(const std::vector<int>& _sz, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{
create(_sz, _type);
}
Mat::Mat(const std::vector<int>& _sz, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{
create(_sz, _type);
*this = _s;
@@ -808,21 +754,21 @@ Mat::Mat(const std::vector<int>& _sz, int _type, const Scalar& _s)
Mat::Mat(const MatShape& _shape, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{
create(_shape, _type);
}
Mat::Mat(std::initializer_list<int> _shape, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{
create(_shape, _type);
}
Mat::Mat(const MatShape& _shape, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{
create(_shape, _type);
*this = _s;
@@ -830,7 +776,7 @@ Mat::Mat(const MatShape& _shape, int _type, const Scalar& _s)
Mat::Mat(std::initializer_list<int> _shape, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
datalimit(0), allocator(0), u(0)
{
create(_shape, _type);
*this = _s;
@@ -839,29 +785,16 @@ Mat::Mat(std::initializer_list<int> _shape, int _type, const Scalar& _s)
Mat::Mat(const Mat& m)
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
u(m.u), size(&rows), step(0)
u(m.u), size(m.size), step(m.step)
{
if( u )
CV_XADD(&u->refcount, 1);
if( m.dims <= 2 )
{
int _1d = m.dims <= 1;
size.p = &rows + _1d;
step.p = &step.buf[_1d];
step.buf[0] = m.step.buf[0];
step.buf[1] = m.step.buf[1];
}
else
{
dims = 0;
copySize(m);
}
}
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), datastart((uchar*)_data), dataend(0), datalimit(0),
allocator(0), u(0), size(&rows)
allocator(0), u(0), size(2)
{
CV_Assert(total() == 0 || data != NULL);
@@ -879,8 +812,10 @@ Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
CV_Error(Error::BadStep, "Step must be a multiple of esz1");
}
}
step.buf[0] = _step;
step.buf[1] = esz;
size[0] = rows;
size[1] = cols;
step[0] = _step;
step[1] = esz;
datalimit = datastart + _step * rows;
dataend = datalimit - _step + minstep;
updateContinuityFlag();
@@ -889,7 +824,7 @@ Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
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), datastart((uchar*)_data), dataend(0), datalimit(0),
allocator(0), u(0), size(&rows)
allocator(0), u(0), size(2)
{
CV_Assert(total() == 0 || data != NULL);
@@ -908,6 +843,8 @@ Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
CV_Error(Error::BadStep, "Step must be a multiple of esz1");
}
}
size[0] = rows;
size[1] = cols;
step[0] = _step;
step[1] = esz;
datalimit = datastart + _step*rows;
@@ -918,13 +855,10 @@ Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
Mat::~Mat()
{
CV_Assert(dummy == 153 && step.buf[2] == 153);
release();
if( step.p != step.buf && step.p != step.buf+1 )
fastFree(step.p);
}
Mat& Mat::operator=(const Mat& m)
Mat& Mat::operator = (const Mat& m)
{
if( this != &m )
{
@@ -932,20 +866,11 @@ Mat& Mat::operator=(const Mat& m)
CV_XADD(&m.u->refcount, 1);
release();
flags = m.flags;
if( dims <= 2 && m.dims <= 2 )
{
int _1d = m.dims < 2;
dims = m.dims;
rows = m.rows;
cols = m.cols;
step.p = &step.buf[_1d];
step.buf[0] = m.step.buf[0];
step.buf[1] = m.step.buf[1];
size.p = &rows + _1d;
}
else
copySize(m);
dims = m.dims;
rows = m.rows;
cols = m.cols;
size = m.size;
step = m.step;
data = m.data;
datastart = m.datastart;
dataend = m.dataend;
@@ -987,7 +912,8 @@ void Mat::create(Size _sz, int _type)
void Mat::createSameSize(InputArray m, int type)
{
_OutputArray(*this).createSameSize(m, type);
MatShape msize = m.shape();
create(msize, type);
}
void Mat::fit(int _dims, const int* _sizes, int _type)
@@ -1063,16 +989,9 @@ void Mat::release()
datastart = dataend = datalimit = data = 0;
for(int i = 0; i < dims; i++)
size.p[i] = 0;
#ifdef _DEBUG
flags = MAGIC_VAL;
if(step.p != step.buf && step.p != step.buf+1)
{
fastFree(step.p);
step.p = step.buf;
size.p = &rows;
}
dims = rows = cols = 0;
#endif
size.clear();
}
size_t Mat::step1(int i) const
@@ -1105,71 +1024,31 @@ size_t Mat::total(int startDim, int endDim) const
return p;
}
MatShape Mat::shape() const
{
return dims == 0 && data == 0 ? MatShape() : MatShape(dims, size.p);
}
Mat::Mat(Mat&& m) CV_NOEXCEPT
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
u(m.u), size(&rows)
u(m.u), size(m.size), step(m.step)
{
if (m.dims <= 2) // move new step/size info
{
int _1d = dims <= 1;
step.p = &step.buf[_1d];
size.p = &rows + _1d;
step.buf[0] = m.step.buf[0];
step.buf[1] = m.step.buf[1];
}
else
{
CV_Assert(m.step.p != m.step.buf && m.step.p != m.step.buf+1);
step.p = m.step.p;
size.p = m.size.p;
m.step.p = m.step.buf;
m.size.p = &m.rows;
}
m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
m.size.clear(); m.step.clear();
m.data = NULL; m.datastart = NULL; m.dataend = NULL; m.datalimit = NULL;
m.allocator = NULL;
m.u = NULL;
}
Mat& Mat::operator=(Mat&& m)
Mat& Mat::operator = (Mat&& m)
{
if (this == &m)
return *this;
release();
flags = m.flags; dims = m.dims; rows = m.rows; cols = m.cols; data = m.data;
size = m.size; step = m.step;
datastart = m.datastart; dataend = m.dataend; datalimit = m.datalimit; allocator = m.allocator;
u = m.u;
if (step.p != step.buf && step.p != step.buf+1) // release self step/size
{
fastFree(step.p);
}
step.p = step.buf;
size.p = &rows;
if (m.dims <= 2) // move new step/size info
{
int _1d = dims <= 1;
step.buf[0] = m.step.buf[0];
step.buf[1] = m.step.buf[1];
step.p = &step.buf[_1d];
size.p = &rows + _1d;
}
else
{
CV_Assert(m.step.p != m.step.buf && m.step.p != m.step.buf+1);
step.p = m.step.p;
size.p = m.size.p;
}
m.step.p = m.step.buf;
m.size.p = &m.rows;
m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
m.size.clear(); m.step.clear();
m.data = NULL; m.datastart = NULL; m.dataend = NULL; m.datalimit = NULL;
m.allocator = NULL;
m.u = NULL;
@@ -1218,7 +1097,7 @@ void Mat::create(int d0, const int* _sizes, int _type)
a = a0;
try
{
u = a->allocate(dims, size, _type, 0, step.p, ACCESS_RW /* ignored */, USAGE_DEFAULT);
u = a->allocate(dims, size.p, _type, 0, step.p, ACCESS_RW /* ignored */, USAGE_DEFAULT);
CV_Assert(u != 0);
allocator = a;
}
@@ -1226,7 +1105,7 @@ void Mat::create(int d0, const int* _sizes, int _type)
{
if (a == a0)
throw;
u = a0->allocate(dims, size, _type, 0, step.p, ACCESS_RW /* ignored */, USAGE_DEFAULT);
u = a0->allocate(dims, size.p, _type, 0, step.p, ACCESS_RW /* ignored */, USAGE_DEFAULT);
CV_Assert(u != 0);
allocator = a0;
}
@@ -1235,7 +1114,7 @@ void Mat::create(int d0, const int* _sizes, int _type)
addref();
finalizeHdr(*this);
dims = d0;
size.dims = dims = d0;
}
void Mat::create(const std::vector<int>& _sizes, int _type)
@@ -1266,14 +1145,11 @@ void Mat::create(std::initializer_list<int> _shape, int _type)
void Mat::copySize(const Mat& m)
{
setSize(*this, m.dims, 0, 0);
step.buf[0] = m.step.buf[0];
step.buf[1] = m.step.buf[1];
for( int i = 0; i < dims; i++ )
{
size[i] = m.size[i];
step[i] = m.step[i];
}
dims = m.dims;
cols = m.cols;
rows = m.rows;
size = m.size;
step = m.step;
}
void Mat::deallocate()
@@ -1288,17 +1164,20 @@ void Mat::deallocate()
Mat::Mat(const Mat& m, const Range& _rowRange, const Range& _colRange)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows)
datalimit(0), allocator(0), u(0)
{
CV_Assert( m.dims >= 2 || (m.dims == 1 && (_rowRange == Range::all() || _rowRange == Range(0, m.rows))));
CV_Assert(m.dims <= MatShape::MAX_DIMS);
CV_Assert(m.dims >= 2 ||
(m.dims == 1 && (_rowRange == Range::all() ||
_rowRange == Range(0, m.rows))));
if( m.dims > 2 )
{
AutoBuffer<Range> rs(m.dims);
Range rs[MatShape::MAX_DIMS];
rs[0] = _rowRange;
rs[1] = _colRange;
for( int i = 2; i < m.dims; i++ )
rs[i] = Range::all();
*this = m(rs.data());
*this = m(rs);
return;
}
@@ -1309,7 +1188,7 @@ Mat::Mat(const Mat& m, const Range& _rowRange, const Range& _colRange)
{
CV_Assert( 0 <= _rowRange.start && _rowRange.start <= _rowRange.end
&& _rowRange.end <= m.rows );
rows = _rowRange.size();
size[0] = rows = _rowRange.size();
data += step*_rowRange.start;
flags |= SUBMATRIX_FLAG;
}
@@ -1318,7 +1197,7 @@ Mat::Mat(const Mat& m, const Range& _rowRange, const Range& _colRange)
{
CV_Assert( 0 <= _colRange.start && _colRange.start <= _colRange.end
&& _colRange.end <= m.cols );
cols = _colRange.size();
size[dims > 1] = cols = _colRange.size();
data += _colRange.start*elemSize();
flags |= SUBMATRIX_FLAG;
}
@@ -1343,7 +1222,7 @@ 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]),
datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit),
allocator(m.allocator), u(m.u), size(&rows)
allocator(m.allocator), u(m.u), size(2)
{
CV_Assert( m.dims <= 2 );
@@ -1354,7 +1233,10 @@ Mat::Mat(const Mat& m, const Rect& roi)
if( roi.width < m.cols || roi.height < m.rows )
flags |= SUBMATRIX_FLAG;
step[0] = m.step[0]; step[1] = esz;
size[0] = rows;
size[1] = cols;
step[0] = m.step[0];
step[1] = esz;
updateContinuityFlag();
addref();
@@ -1368,7 +1250,7 @@ Mat::Mat(const Mat& m, const Rect& roi)
Mat::Mat(int _dims, const int* _sizes, int _type, void* _data, const size_t* _steps)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows)
datalimit(0), allocator(0), u(0)
{
flags |= CV_MAT_TYPE(_type);
datastart = data = (uchar*)_data;
@@ -1380,7 +1262,7 @@ Mat::Mat(int _dims, const int* _sizes, int _type, void* _data, const size_t* _st
Mat::Mat(const std::vector<int>& _sizes, int _type, void* _data, const size_t* _steps)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows)
datalimit(0), allocator(0), u(0)
{
flags |= CV_MAT_TYPE(_type);
datastart = data = (uchar*)_data;
@@ -1392,7 +1274,7 @@ Mat::Mat(const std::vector<int>& _sizes, int _type, void* _data, const size_t* _
Mat::Mat(const MatShape& _shape, int _type, void* _data, const size_t* _steps)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows)
datalimit(0), allocator(0), u(0)
{
flags |= CV_MAT_TYPE(_type);
datastart = data = (uchar*)_data;
@@ -1407,7 +1289,7 @@ Mat::Mat(const MatShape& _shape, int _type, void* _data, const size_t* _steps)
Mat::Mat(std::initializer_list<int> _shape, int _type, void* _data, const size_t* _steps)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows)
datalimit(0), allocator(0), u(0)
{
int new_shape[MatShape::MAX_DIMS];
int _dims = (int)_shape.size();
@@ -1425,7 +1307,7 @@ Mat::Mat(std::initializer_list<int> _shape, int _type, void* _data, const size_t
Mat::Mat(const Mat& m, const Range* ranges)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows)
datalimit(0), allocator(0), u(0)
{
int d = m.dims;
@@ -1446,12 +1328,17 @@ Mat::Mat(const Mat& m, const Range* ranges)
flags |= SUBMATRIX_FLAG;
}
}
if (d <= 2) {
rows = d == 2 ? size[0] : 1;
cols = d <= 0 ? (d >= 0) : size[d > 1];
}
updateContinuityFlag();
}
Mat::Mat(const Mat& m, const std::vector<Range>& ranges)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows)
datalimit(0), allocator(0), u(0)
{
int d = m.dims;
@@ -1472,6 +1359,11 @@ Mat::Mat(const Mat& m, const std::vector<Range>& ranges)
flags |= SUBMATRIX_FLAG;
}
}
if (d <= 2) {
rows = d == 2 ? size[0] : 1;
cols = d <= 0 ? (d >= 0) : size[d > 1];
}
updateContinuityFlag();
}
@@ -1511,12 +1403,17 @@ Mat Mat::diag(int d) const
void Mat::pop_back(size_t nelems)
{
CV_Assert( nelems <= (size_t)size.p[0] );
CV_Assert( dims >= 1 );
if( isSubmatrix() )
*this = rowRange(0, size.p[0] - (int)nelems);
else
{
size.p[0] -= (int)nelems;
if (dims == 2)
rows = size.p[0];
else if (dims == 1)
cols = size.p[0];
dataend -= nelems*step.p[0];
}
}
@@ -1531,6 +1428,10 @@ void Mat::push_back_(const void* elem)
size_t esz = elemSize();
memcpy(data + r*step.p[0], elem, esz);
size.p[0] = int(r + 1);
if (dims == 2)
rows = size.p[0];
else if (dims == 1)
cols = size.p[0];
dataend += step.p[0];
uint64 tsz = size.p[0];
for( int i = 1; i < dims; i++ )
@@ -1545,23 +1446,28 @@ void Mat::reserve(size_t nelems)
const size_t MIN_SIZE = 64;
CV_Assert( (int)nelems >= 0 );
if( !isSubmatrix() && data + step.p[0]*nelems <= datalimit )
if( !isSubmatrix() && step.p[0] != 0 && data + step.p[0]*nelems <= datalimit )
return;
int r = size.p[0];
if( (size_t)r >= nelems )
if( (size_t)r >= nelems)
return;
size.p[0] = std::max((int)nelems, 1);
size_t newsize = total()*elemSize();
MatShape newsize = size;
size_t esz = elemSize();
newsize.dims = std::max(newsize.dims, 1);
if (dims > 1 && r == 0 && step.p[0] == 0) {
step.p[0] = size.p[1] * (dims == 2 ? esz : step.p[1]);
}
newsize.p[0] = (int)nelems;
size_t newbytes = newsize.total() * esz;
if (newbytes < MIN_SIZE) {
newsize.p[0] = 1;
newsize.p[0] = int(MIN_SIZE / newsize.total() / esz);
}
if( newsize < MIN_SIZE )
size.p[0] = (int)((MIN_SIZE + newsize - 1)*nelems/newsize);
Mat m(dims, size.p, type());
size.p[0] = r;
if( r > 0 )
Mat m(newsize, type());
if( r > 0)
{
Mat mpart = m.rowRange(0, r);
copyTo(mpart);
@@ -1569,6 +1475,11 @@ void Mat::reserve(size_t nelems)
*this = m;
size.p[0] = r;
if (dims == 2)
rows = size.p[0];
else if (dims == 1)
cols = size.p[0];
dataend = data + step.p[0]*r;
}
@@ -1602,8 +1513,8 @@ void Mat::reserveBuffer(size_t nbytes)
void Mat::resize(size_t nelems)
{
int saveRows = size.p[0];
if( saveRows == (int)nelems )
int r = size.p[0];
if( r == (int)nelems )
return;
CV_Assert( (int)nelems >= 0 );
@@ -1611,7 +1522,11 @@ void Mat::resize(size_t nelems)
reserve(nelems);
size.p[0] = (int)nelems;
dataend += (size.p[0] - saveRows)*step.p[0];
if (dims == 2)
rows = size.p[0];
else if (dims == 1)
cols = size.p[0];
dataend += (size.p[0] - r)*(int64_t)step.p[0];
//updateContinuityFlag(*this);
}
@@ -1646,6 +1561,7 @@ void Mat::push_back(const Mat& elems)
*this = elems.clone();
return;
}
CV_Assert(dims > 0);
size.p[0] = elems.size.p[0];
bool eq = size == elems.size;
@@ -1654,17 +1570,28 @@ void Mat::push_back(const Mat& elems)
CV_Error(cv::Error::StsUnmatchedSizes, "Pushed vector length is not equal to matrix row length");
if( type() != elems.type() )
CV_Error(cv::Error::StsUnmatchedFormats, "Pushed vector type is not the same as matrix type");
size_t esz = elemSize();
size_t minstep = dims <= 1 ? esz : size.p[1] * (dims == 2 ? esz : step.p[1]);
size_t step0 = step.p[0];
if (step0 < minstep) {
if (size.p[0] <= 1)
step.p[0] = step0 = minstep;
}
if( isSubmatrix() || dataend + step.p[0]*delta > datalimit )
if( isSubmatrix() || dataend + step0*delta > datalimit )
reserve( std::max(r + delta, (r*3+1)/2) );
size.p[0] += int(delta);
dataend += step.p[0]*delta;
if (dims == 2)
rows = size.p[0];
else if (dims == 1)
cols = size.p[0];
dataend += step0*delta;
//updateContinuityFlag(*this);
if( isContinuous() && elems.isContinuous() )
memcpy(data + r*step.p[0], elems.data, elems.total()*elems.elemSize());
memcpy(data + r*step0, elems.data, elems.total()*elems.elemSize());
else
{
Mat part = rowRange(int(r), int(r + delta));
@@ -1763,8 +1690,12 @@ Mat Mat::reshape(int new_cn, int new_rows) const
CV_Error( cv::Error::StsBadArg, "The total number of matrix elements "
"is not divisible by the new number of rows" );
hdr.rows = new_rows;
hdr.step.buf[0] = total_width * elemSize1();
hdr.size[0] = hdr.rows = new_rows;
hdr.step[0] = total_width * elemSize1();
} else {
hdr.size[0] = hdr.rows = rows;
if (dims <= 1)
hdr.step[0] = cols * CV_ELEM_SIZE(flags);
}
int new_width = total_width / new_cn;
@@ -1773,12 +1704,10 @@ Mat Mat::reshape(int new_cn, int new_rows) const
CV_Error( cv::Error::BadNumChannels,
"The total width is not divisible by the new number of channels" );
hdr.dims = 2;
hdr.cols = new_width;
hdr.size.dims = hdr.dims = 2;
hdr.size[1] = hdr.cols = new_width;
hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn-1) << CV_CN_SHIFT);
hdr.step.buf[1] = CV_ELEM_SIZE(hdr.flags);
hdr.step.p = &hdr.step.buf[0];
hdr.size.p = &hdr.rows;
hdr.step[1] = CV_ELEM_SIZE(hdr.flags);
return hdr;
}
+19 -1
View File
@@ -1679,7 +1679,7 @@ void MatOp_Initializer::assign(const MatExpr& e, Mat& m, int _type) const
if( _type == -1 )
_type = e.a.type();
m.create(e.a.dims, e.a.size, _type);
m.create(e.a.size, _type);
if( e.flags == 'I' && e.a.dims <= 2 )
setIdentity(m, Scalar(e.alpha));
@@ -1767,6 +1767,15 @@ MatExpr Mat::zeros(int ndims, const int* sizes, int type)
return e;
}
MatExpr Mat::zeros(const MatShape& shape, int type)
{
CV_INSTRUMENT_REGION();
MatExpr e;
MatOp_Initializer::makeExpr(e, '0', shape.dims, shape.p, type);
return e;
}
MatExpr Mat::ones(int rows, int cols, int type)
{
CV_INSTRUMENT_REGION();
@@ -1794,6 +1803,15 @@ MatExpr Mat::ones(int ndims, const int* sizes, int type)
return e;
}
MatExpr Mat::ones(const MatShape& shape, int type)
{
CV_INSTRUMENT_REGION();
MatExpr e;
MatOp_Initializer::makeExpr(e, '1', shape.dims, shape.p, type);
return e;
}
MatExpr Mat::eye(int rows, int cols, int type)
{
CV_INSTRUMENT_REGION();
+1 -1
View File
@@ -82,7 +82,7 @@ void NAryMatIterator::init(const Mat** _arrays, Mat* _planes, uchar** _ptrs, int
if( i0 >= 0 )
{
size = arrays[i0]->size[d > 0 ? d-1 : 0];
size = arrays[i0]->size[std::max(d-1, 0)];
for( j = d-1; j > iterdepth; j-- )
{
int64 total1 = (int64)size*arrays[i0]->size[j-1];
+2 -18
View File
@@ -29,24 +29,8 @@ void cv::swap( Mat& a, Mat& b )
std::swap(a.allocator, b.allocator);
std::swap(a.u, b.u);
std::swap(a.size.p, b.size.p);
std::swap(a.step.p, b.step.p);
std::swap(a.step.buf[0], b.step.buf[0]);
std::swap(a.step.buf[1], b.step.buf[1]);
if(a.dims <= 2)
{
int a_1d = a.dims <= 1;
a.step.p = &a.step.buf[a_1d];
a.size.p = &a.rows + a_1d;
}
if(b.dims <= 2)
{
int b_1d = b.dims <= 1;
b.step.p = &b.step.buf[b_1d];
b.size.p = &b.rows + b_1d;
}
std::swap(a.size, b.size);
std::swap(a.step, b.step);
}
+1 -1
View File
@@ -273,7 +273,7 @@ size_t SparseMat::hash(const int* idx) const
SparseMat::SparseMat(const Mat& m)
: flags(MAGIC_VAL), hdr(0)
{
create( m.dims, m.size, m.type() );
create( m.dims, m.size.p, m.type() );
int i, idx[CV_MAX_DIM] = {0}, d = m.dims, lastSize = m.size[d - 1];
size_t esz = m.elemSize();
+1 -1
View File
@@ -136,7 +136,7 @@ void merge(const Mat* mv, size_t n, OutputArray _dst)
}
CV_Assert( 0 < cn && cn <= CV_CN_MAX );
_dst.create(mv[0].dims, mv[0].size, CV_MAKETYPE(depth, cn));
_dst.create(mv[0].size, CV_MAKETYPE(depth, cn));
Mat dst = _dst.getMat();
if( n == 1 )
+1 -1
View File
@@ -132,7 +132,7 @@ void split(const Mat& src, Mat* mv)
for( k = 0; k < cn; k++ )
{
mv[k].create(src.dims, src.size, depth);
mv[k].create(src.size, depth);
}
CV_IPP_RUN_FAST(ipp_split(src, mv, cn));
+119 -172
View File
@@ -260,65 +260,66 @@ UMatDataAutoLock::~UMatDataAutoLock()
//////////////////////////////// UMat ////////////////////////////////
UMat::UMat(UMatUsageFlags _usageFlags) CV_NOEXCEPT
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0)
{}
UMat::UMat(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0)
{
create(_rows, _cols, _type);
}
UMat::UMat(int _rows, int _cols, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0)
{
create(_rows, _cols, _type);
*this = _s;
}
UMat::UMat(Size _sz, int _type, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0)
{
create( _sz.height, _sz.width, _type );
}
UMat::UMat(Size _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0)
{
create(_sz.height, _sz.width, _type);
*this = _s;
}
UMat::UMat(int _dims, const int* _sz, int _type, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0)
{
create(_dims, _sz, _type);
}
UMat::UMat(int _dims, const int* _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0)
{
create(_dims, _sz, _type);
*this = _s;
}
UMat::UMat(const MatShape& _shape, int _type, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0)
{
create(_shape.dims, _shape.p, _type);
}
UMat::UMat(const MatShape& _shape, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0)
{
create(_shape.dims, _shape.p, _type);
*this = _s;
}
UMat::UMat(const UMat& m)
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),
usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows)
usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(m.size), step(m.step)
{
addref();
if( m.dims <= 2 )
{
int _1d = dims <= 1;
step.buf[0] = m.step.buf[0]; step.buf[1] = m.step.buf[1];
step.p = &step.buf[_1d];
size.p = &rows + _1d;
}
else
{
dims = 0;
copySize(m);
}
}
UMat& UMat::operator=(const UMat& m)
@@ -328,19 +329,11 @@ UMat& UMat::operator=(const UMat& m)
const_cast<UMat&>(m).addref();
release();
flags = m.flags;
if( dims <= 2 && m.dims <= 2 )
{
dims = m.dims;
rows = m.rows;
cols = m.cols;
int _1d = dims <= 1;
step.buf[0] = m.step.buf[0];
step.buf[1] = m.step.buf[1];
step.p = &step.buf[_1d];
size.p = &rows + _1d;
}
else
copySize(m);
dims = m.dims;
rows = m.rows;
cols = m.cols;
size = m.size;
step = m.step;
allocator = m.allocator;
usageFlags = m.usageFlags;
u = m.u;
@@ -392,9 +385,9 @@ void UMat::release()
{
if( u && CV_XADD(&(u->urefcount), -1) == 1 )
deallocate();
for(int i = 0; i < dims; i++)
size.p[i] = 0;
u = 0;
size.clear();
dims = cols = rows = 0;
}
bool UMat::empty() const
@@ -414,30 +407,19 @@ size_t UMat::total() const
MatShape UMat::shape() const
{
return dims == 0 && u == 0 ? MatShape() : MatShape(dims, size.p);
return size;
}
UMat::UMat(UMat&& m)
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),
usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows)
usageFlags(m.usageFlags), u(m.u), offset(m.offset)
{
if (m.dims <= 2) // move new step/size info
{
int _1d = m.dims <= 1;
step.buf[0] = m.step.buf[0];
step.buf[1] = m.step.buf[1];
step.p = &step.buf[_1d];
size.p = &rows + _1d;
}
else
{
CV_DbgAssert(m.step.p != m.step.buf && m.step.p != m.step.buf+1);
step.p = m.step.p;
size.p = m.size.p;
m.step.p = m.step.buf;
m.size.p = &m.rows;
}
m.flags = MAGIC_VAL; m.dims = m.rows = m.cols = 0;
size = m.size;
step = m.step;
m.flags = MAGIC_VAL;
m.usageFlags = USAGE_DEFAULT;
m.dims = m.rows = m.cols = 0;
m.size.clear();
m.allocator = NULL;
m.u = NULL;
m.offset = 0;
@@ -452,28 +434,8 @@ UMat& UMat::operator=(UMat&& m)
allocator = m.allocator; usageFlags = m.usageFlags;
u = m.u;
offset = m.offset;
if (step.p != step.buf && step.p != step.buf+1) // release self step/size
{
fastFree(step.p);
}
step.p = step.buf;
size.p = &rows;
if (m.dims <= 2) // move new step/size info
{
int _1d = dims <= 1;
step.buf[0] = m.step.buf[0];
step.buf[1] = m.step.buf[1];
step.p = &step.buf[_1d];
size.p = &rows + _1d;
}
else
{
CV_DbgAssert(m.step.p != m.step.buf && m.step.p != m.step.buf+1);
step.p = m.step.p;
size.p = m.size.p;
}
m.step.p = m.step.buf;
m.size.p = &m.rows;
size = m.size;
step = m.step;
m.flags = MAGIC_VAL;
m.usageFlags = USAGE_DEFAULT;
m.dims = m.rows = m.cols = 0;
@@ -503,80 +465,37 @@ void swap( UMat& a, UMat& b )
std::swap(a.u, b.u);
std::swap(a.offset, b.offset);
std::swap(a.size.p, b.size.p);
std::swap(a.step.p, b.step.p);
std::swap(a.step.buf[0], b.step.buf[0]);
std::swap(a.step.buf[1], b.step.buf[1]);
if(a.dims <= 2)
{
int a_1d = a.dims <= 1;
a.step.p = &a.step.buf[a_1d];
a.size.p = &a.rows + a_1d;
}
if( b.dims <= 2)
{
int b_1d = b.dims <= 1;
b.step.p = &b.step.buf[b_1d];
b.size.p = &b.rows + b_1d;
}
std::swap(a.size, b.size);
std::swap(a.step, b.step);
}
void setSize( UMat& m, int _dims, const int* _sz,
const size_t* _steps, bool autoSteps )
{
CV_Assert( 0 <= _dims && _dims <= CV_MAX_DIM );
if( m.dims != _dims )
{
if( m.step.p != m.step.buf && m.step.p != m.step.buf+1 )
{
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.rows = m.cols = -1;
}
}
CV_Assert( 0 <= _dims && _dims <= CV_MAX_DIM && _dims <= MatShape::MAX_DIMS);
m.dims = _dims;
size_t esz = CV_ELEM_SIZE(m.flags), total = esz;
if (_sz != 0) {
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::Error::StsOutOfRange, "The total matrix size does not fit to \"size_t\" type" );
total = (size_t)total1;
}
m.size = MatShape(_dims, _sz);
m.step[std::max(_dims-1, 0)] = CV_ELEM_SIZE(m.flags);
for (int i = _dims-2; i >= 0; i--) {
size_t autostep = m.size[i+1]*m.step[i+1];
if (_steps) {
m.step[i] = _steps[i];
//CV_Assert(m.step[i] >= autostep);
} else if (autoSteps) {
m.step[i] = autostep;
} else {
m.step[i] = 0;
}
}
if( _dims < 2 )
if( _dims <= 2 )
{
m.cols = _dims >= 1 && _sz ? _sz[0] : 1;
m.rows = 1;
m.size.p = &m.cols;
m.step.buf[0] = m.cols*esz;
m.step.buf[1] = esz;
m.step.p = &m.step.buf[1];
m.cols = _dims == 0 ? 1 : _sz ? _sz[_dims > 1] : 0;
m.rows = _dims < 2 ? 1 : _sz ? _sz[0] : 0;
} else {
m.cols = m.rows = -1;
}
}
@@ -622,11 +541,12 @@ UMat Mat::getUMat(AccessFlag accessFlags, UMatUsageFlags usageFlags) const
accessFlags |= ACCESS_RW;
UMatData* new_u = NULL;
MatStep new_step = step;
{
MatAllocator *a = allocator, *a0 = getDefaultAllocator();
if(!a)
a = a0;
new_u = a->allocate(dims, size.p, type(), data, step.p, accessFlags, usageFlags);
new_u = a->allocate(dims, size.p, type(), data, new_step.p, accessFlags, usageFlags);
new_u->originalUMatData = u;
}
bool allocated = false;
@@ -658,7 +578,7 @@ UMat Mat::getUMat(AccessFlag accessFlags, UMatUsageFlags usageFlags) const
{
hdr.flags = flags;
hdr.usageFlags = usageFlags;
setSize(hdr, dims, size.p, step.p);
setSize(hdr, dims, size.p, new_step.p);
finalizeHdr(hdr);
hdr.u = new_u;
hdr.offset = 0; //data - datastart;
@@ -733,13 +653,13 @@ void UMat::create(int d0, const int* _sizes, int _type, UMatUsageFlags _usageFla
}
try
{
u = a->allocate(dims, size, _type, 0, step.p, ACCESS_RW /* ignored */, usageFlags);
u = a->allocate(dims, size.p, _type, 0, step.p, ACCESS_RW /* ignored */, usageFlags);
CV_Assert(u != 0);
}
catch(...)
{
if(a != a0)
u = a0->allocate(dims, size, _type, 0, step.p, ACCESS_RW /* ignored */, usageFlags);
u = a0->allocate(dims, size.p, _type, 0, step.p, ACCESS_RW /* ignored */, usageFlags);
CV_Assert(u != 0);
}
CV_Assert( step[dims-1] == (size_t)CV_ELEM_SIZE(flags) );
@@ -747,7 +667,7 @@ void UMat::create(int d0, const int* _sizes, int _type, UMatUsageFlags _usageFla
finalizeHdr(*this);
addref();
dims = d0;
size.dims = dims = d0;
}
void UMat::create(const std::vector<int>& _sizes, int _type, UMatUsageFlags _usageFlags)
@@ -818,20 +738,16 @@ void UMat::fitSameSize(InputArray m, int _type, UMatUsageFlags _usageFlags)
void UMat::copySize(const UMat& m)
{
setSize(*this, m.dims, 0, 0);
for( int i = 0; i < dims; i++ )
{
size[i] = m.size[i];
step[i] = m.step[i];
}
dims = m.dims;
cols = m.cols;
rows = m.rows;
size = m.size;
step = m.step;
}
UMat::~UMat()
{
release();
if( step.p != step.buf && step.p != step.buf+1 )
fastFree(step.p);
}
void UMat::deallocate()
@@ -843,33 +759,37 @@ void UMat::deallocate()
UMat::UMat(const UMat& m, const Range& _rowRange, const Range& _colRange)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0)
{
CV_Assert( m.dims >= 2 );
CV_Assert( m.dims >= 2 && m.dims <= MatShape::MAX_DIMS );
if( m.dims > 2 )
{
AutoBuffer<Range> rs(m.dims);
Range rs[MatShape::MAX_DIMS];
rs[0] = _rowRange;
rs[1] = _colRange;
for( int i = 2; i < m.dims; i++ )
rs[i] = Range::all();
*this = m(rs.data());
*this = m(rs);
return;
}
*this = m;
if( _rowRange != Range::all() && _rowRange != Range(0,rows) )
{
CV_Assert( 0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows );
rows = _rowRange.size();
CV_Assert( 0 <= _rowRange.start &&
_rowRange.start <= _rowRange.end &&
_rowRange.end <= m.rows );
size[0] = rows = _rowRange.size();
offset += step*_rowRange.start;
flags |= SUBMATRIX_FLAG;
}
if( _colRange != Range::all() && _colRange != Range(0,cols) )
{
CV_Assert( 0 <= _colRange.start && _colRange.start <= _colRange.end && _colRange.end <= m.cols );
cols = _colRange.size();
CV_Assert( 0 <= _colRange.start &&
_colRange.start <= _colRange.end &&
_colRange.end <= m.cols );
size[1] = cols = _colRange.size();
offset += _colRange.start*elemSize();
flags |= SUBMATRIX_FLAG;
}
@@ -886,7 +806,8 @@ UMat::UMat(const UMat& m, const Range& _rowRange, const Range& _colRange)
UMat::UMat(const UMat& m, const Rect& roi)
: flags(m.flags), dims(2), rows(roi.height), cols(roi.width),
allocator(m.allocator), usageFlags(m.usageFlags), u(m.u), offset(m.offset + roi.y*m.step[0]), size(&rows)
allocator(m.allocator), usageFlags(m.usageFlags), u(m.u),
offset(m.offset + roi.y*m.step[0]), size(2)
{
CV_Assert( m.dims <= 2 );
@@ -897,7 +818,11 @@ UMat::UMat(const UMat& m, const Rect& roi)
if( roi.width < m.cols || roi.height < m.rows )
flags |= SUBMATRIX_FLAG;
step[0] = m.step[0]; step[1] = esz;
size[0] = rows;
size[1] = cols;
step[0] = m.dims == 2 ? m.step[0] : cols*esz;
step[1] = esz;
updateContinuityFlag();
addref();
@@ -910,7 +835,7 @@ UMat::UMat(const UMat& m, const Rect& roi)
UMat::UMat(const UMat& m, const Range* ranges)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0)
{
int i, d = m.dims;
@@ -931,11 +856,16 @@ UMat::UMat(const UMat& m, const Range* ranges)
flags |= SUBMATRIX_FLAG;
}
}
if (d <= 2) {
rows = d == 2 ? size[0] : 1;
cols = d <= 0 ? (d >= 0) : size[d > 1];
}
updateContinuityFlag();
}
UMat::UMat(const UMat& m, const std::vector<Range>& ranges)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0)
{
int i, d = m.dims;
@@ -956,6 +886,11 @@ UMat::UMat(const UMat& m, const std::vector<Range>& ranges)
flags |= SUBMATRIX_FLAG;
}
}
if (d <= 2) {
rows = d == 2 ? size[0] : 1;
cols = d <= 0 ? (d >= 0) : size[d > 1];
}
updateContinuityFlag();
}
@@ -1069,8 +1004,12 @@ UMat UMat::reshape(int new_cn, int new_rows) const
CV_Error( cv::Error::StsBadArg, "The total number of matrix elements "
"is not divisible by the new number of rows" );
hdr.rows = new_rows;
hdr.step.buf[0] = total_width * elemSize1();
hdr.size[0] = hdr.rows = new_rows;
hdr.step[0] = total_width * elemSize1();
} else {
hdr.size[0] = hdr.rows = rows;
if (dims <= 1)
hdr.step[0] = cols * CV_ELEM_SIZE(flags);
}
int new_width = total_width / new_cn;
@@ -1079,12 +1018,10 @@ UMat UMat::reshape(int new_cn, int new_rows) const
CV_Error( cv::Error::BadNumChannels,
"The total width is not divisible by the new number of channels" );
hdr.dims = 2;
hdr.cols = new_width;
hdr.size.dims = hdr.dims = 2;
hdr.size[1] = hdr.cols = new_width;
hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn-1) << CV_CN_SHIFT);
hdr.step.buf[1] = CV_ELEM_SIZE(hdr.flags);
hdr.step.p = &hdr.step.buf[0];
hdr.size.p = &hdr.rows;
hdr.step[1] = CV_ELEM_SIZE(hdr.flags);
return hdr;
}
@@ -1328,7 +1265,7 @@ void UMat::copyTo(OutputArray _dst, InputArray _mask) const
if (ocl::useOpenCL() && _dst.isUMat() && dims <= 2)
{
UMatData * prevu = _dst.getUMat().u;
_dst.create( dims, size, type() );
_dst.create( size, type() );
UMat dst = _dst.getUMat();
@@ -1453,6 +1390,11 @@ UMat UMat::zeros(int ndims, const int* sz, int type, UMatUsageFlags usageFlags)
return UMat(ndims, sz, type, Scalar::all(0), usageFlags);
}
UMat UMat::zeros(const MatShape& shape, int type, UMatUsageFlags usageFlags)
{
return UMat(shape.dims, shape.p, type, Scalar::all(0), usageFlags);
}
UMat UMat::ones(int rows, int cols, int type, UMatUsageFlags usageFlags)
{
return UMat(rows, cols, type, Scalar(1), usageFlags);
@@ -1468,6 +1410,11 @@ UMat UMat::ones(int ndims, const int* sz, int type, UMatUsageFlags usageFlags)
return UMat(ndims, sz, type, Scalar(1), usageFlags);
}
UMat UMat::ones(const MatShape& shape, int type, UMatUsageFlags usageFlags)
{
return UMat(shape.dims, shape.p, type, Scalar(1), usageFlags);
}
}
/* End of file. */
+10 -10
View File
@@ -614,7 +614,7 @@ static void inRange(const Mat& src, const Mat& lb, const Mat& rb, Mat& dst)
{
CV_Assert( src.type() == lb.type() && src.type() == rb.type() &&
src.size == lb.size && src.size == rb.size );
dst.create( src.dims, &src.size[0], CV_8U );
dst.create( src.size, CV_8U );
const Mat *arrays[]={&src, &lb, &rb, &dst, 0};
Mat planes[4];
@@ -678,7 +678,7 @@ static void inRange(const Mat& src, const Mat& lb, const Mat& rb, Mat& dst)
static void inRangeS(const Mat& src, const Scalar& lb, const Scalar& rb, Mat& dst)
{
dst.create( src.dims, &src.size[0], CV_8U );
dst.create( src.size, CV_8U );
const Mat *arrays[]={&src, &dst, 0};
Mat planes[2];
@@ -836,7 +836,7 @@ static void finiteMask_(const _Tp *src, uchar *dst, size_t total, int cn)
static void finiteMask(const Mat& src, Mat& dst)
{
dst.create(src.dims, &src.size[0], CV_8UC1);
dst.create(src.size, CV_8UC1);
const Mat *arrays[]={&src, &dst, 0};
Mat planes[2];
@@ -1019,7 +1019,7 @@ namespace reference {
static void flip(const Mat& src, Mat& dst, int flipcode)
{
CV_Assert(src.dims <= 2);
dst.createSameSize(src, src.type());
dst.create(src.size, src.type());
int i, j, k, esz = (int)src.elemSize(), width = src.cols*esz;
for( i = 0; i < dst.rows; i++ )
@@ -1191,7 +1191,7 @@ struct SetZeroOp : public BaseElemWiseOp
namespace reference {
static void exp(const Mat& src, Mat& dst)
{
dst.create( src.dims, &src.size[0], src.type() );
dst.create( src.size, src.type() );
const Mat *arrays[]={&src, &dst, 0};
Mat planes[2];
@@ -1220,7 +1220,7 @@ static void exp(const Mat& src, Mat& dst)
static void log(const Mat& src, Mat& dst)
{
dst.create( src.dims, &src.size[0], src.type() );
dst.create( src.size, src.type() );
const Mat *arrays[]={&src, &dst, 0};
Mat planes[2];
@@ -1312,8 +1312,8 @@ static void cartToPolar(const Mat& mx, const Mat& my, Mat& mmag, Mat& mangle, bo
{
CV_Assert( (mx.type() == CV_32F || mx.type() == CV_64F) &&
mx.type() == my.type() && mx.size == my.size );
mmag.create( mx.dims, &mx.size[0], mx.type() );
mangle.create( mx.dims, &mx.size[0], mx.type() );
mmag.create( mx.size, mx.type() );
mangle.create( mx.size, mx.type() );
const Mat *arrays[]={&mx, &my, &mmag, &mangle, 0};
Mat planes[4];
@@ -1380,7 +1380,7 @@ struct CartToPolarToCartOp : public BaseArithmOp
Mat msrc[] = {mag, angle, x, y};
int pairs[] = {0, 0, 1, 1, 2, 2, 3, 3};
dst.create(src[0].dims, src[0].size, CV_MAKETYPE(src[0].depth(), 4));
dst.create(src[0].size, CV_MAKETYPE(src[0].depth(), 4));
cv::mixChannels(msrc, 4, &dst, 1, pairs, 4);
}
void refop(const vector<Mat>& src, Mat& dst, const Mat&)
@@ -1389,7 +1389,7 @@ struct CartToPolarToCartOp : public BaseArithmOp
reference::cartToPolar(src[0], src[1], mag, angle, angleInDegrees);
Mat msrc[] = {mag, angle, src[0], src[1]};
int pairs[] = {0, 0, 1, 1, 2, 2, 3, 3};
dst.create(src[0].dims, src[0].size, CV_MAKETYPE(src[0].depth(), 4));
dst.create(src[0].size, CV_MAKETYPE(src[0].depth(), 4));
cv::mixChannels(msrc, 4, &dst, 1, pairs, 4);
}
void generateScalars(int, RNG& rng)
+13 -6
View File
@@ -160,23 +160,26 @@ TEST_P(HasNonZeroNd, hasNonZeroNd)
std::vector<size_t> steps(ndims);
std::vector<int> sizes(ndims);
size_t totalBytes = 1;
for(int dim = 0 ; dim<ndims ; ++dim)
for(int dim = ndims-1; dim >= 0; --dim)
{
const bool isFirstDim = (dim == 0);
const bool isLastDim = (dim+1 == ndims);
const int length = rng.uniform(1, 64);
steps[dim] = (isLastDim ? 1 : static_cast<size_t>(length))*CV_ELEM_SIZE(type);
steps[dim] = isLastDim ? CV_ELEM_SIZE(type) : sizes[dim+1]*steps[dim+1];
sizes[dim] = (isFirstDim || continuous) ? length : rng.uniform(1, length);
totalBytes *= steps[dim]*static_cast<size_t>(sizes[dim]);
totalBytes *= steps[dim];
}
totalBytes *= sizes[0];
std::vector<unsigned char> buffer(totalBytes);
void* data = buffer.data();
unsigned char magicval = 153;
size_t border = 128;
std::vector<unsigned char> buffer(totalBytes+border*2, magicval);
void* data = buffer.data() + border;
Mat m = Mat(ndims, sizes.data(), type, data, steps.data());
std::vector<Range> nzRange(ndims);
for(int dim = 0 ; dim<ndims ; ++dim)
for(int dim = 0; dim < ndims ; ++dim)
{
const int pos = rng.uniform(0, sizes[dim]);
nzRange[dim] = Range(pos, pos+1);
@@ -187,6 +190,10 @@ TEST_P(HasNonZeroNd, hasNonZeroNd)
const int nzCount = countNonZero(m);
EXPECT_EQ((nzCount>0), hasNonZero(m));
for (size_t j = 0; j < border; j++) {
ASSERT_EQ(buffer[j], magicval);
ASSERT_EQ(buffer[border + totalBytes + j], magicval);
}
}
}
+5 -4
View File
@@ -131,13 +131,13 @@ protected:
static_cast<int>(cvtest::randInt(rng)%10+1),
static_cast<int>(cvtest::randInt(rng)%10+1),
};
MatND test_mat_nd(3, sz, CV_MAKETYPE(depth, cn));
Mat test_mat_nd(3, sz, CV_MAKETYPE(depth, cn));
rng0.fill(test_mat_nd, RNG::UNIFORM, Scalar::all(ranges[depth][0]), Scalar::all(ranges[depth][1]));
if( depth >= CV_32F )
{
exp(test_mat_nd, test_mat_nd);
MatND test_mat_scale(test_mat_nd.dims, test_mat_nd.size, test_mat_nd.type());
Mat test_mat_scale(test_mat_nd.size, test_mat_nd.type());
rng0.fill(test_mat_scale, RNG::UNIFORM, Scalar::all(-1), Scalar::all(1));
cv::multiply(test_mat_nd, test_mat_scale, test_mat_nd);
}
@@ -148,8 +148,9 @@ protected:
static_cast<int>(cvtest::randInt(rng)%10+1),
static_cast<int>(cvtest::randInt(rng)%10+1),
};
SparseMat test_sparse_mat = cvTsGetRandomSparseMat(4, ssz, cvtest::randInt(rng)%(CV_64F+1),
cvtest::randInt(rng) % 10000, 0, 100, rng);
SparseMat test_sparse_mat =
cvTsGetRandomSparseMat(4, ssz, cvtest::randInt(rng)%(CV_64F+1),
cvtest::randInt(rng) % 10000, 0, 100, rng);
fs << "test_int" << test_int << "test_real" << test_real << "test_string" << test_string;
fs << "test_mat" << test_mat;
+2 -2
View File
@@ -2411,7 +2411,7 @@ TEST(Mat1D, basic)
m1.at<uchar>(50) = 10;
EXPECT_FALSE(m1.empty());
ASSERT_EQ(1, m1.dims);
ASSERT_EQ(1, m1.size.dims()); // hack map on .rows
ASSERT_EQ(1, m1.size.dims); // hack map on .rows
EXPECT_EQ(Size(100, 1), m1.size());
{
@@ -2598,7 +2598,7 @@ TEST(Mat, Recreate1DMatWithSameMeta)
cv::Mat m(dims, depth);
// By default m has dims: [1, 100]
m.dims = 1;
m.size.dims = m.dims = 1;
EXPECT_NO_THROW(m.create(dims, depth));
}