Merge pull request #8535 from arnaudbrejeon:std_array

Add support for std::array<T, N> (#8535)

* Add support for std::array<T, N>

* Add std::array<Mat, N> support

* Remove UMat constructor with std::array parameter
pull/8273/merge
Arnaud Brejeon 8 years ago committed by Alexander Alekhin
parent 2922738b6d
commit 636ab095b0
  1. 15
      modules/core/include/opencv2/core/cvdef.h
  2. 45
      modules/core/include/opencv2/core/mat.hpp
  3. 101
      modules/core/include/opencv2/core/mat.inl.hpp
  4. 4
      modules/core/src/convert.cpp
  5. 4
      modules/core/src/lda.cpp
  6. 2
      modules/core/src/matmul.cpp
  7. 223
      modules/core/src/matrix.cpp
  8. 92
      modules/core/test/test_mat.cpp

@ -364,6 +364,21 @@ Cv64suf;
# endif
#endif
/****************************************************************************************\
* C++11 std::array *
\****************************************************************************************/
#ifndef CV_CXX_STD_ARRAY
# if __cplusplus >= 201103L
# define CV_CXX_STD_ARRAY 1
# include <array>
# endif
#else
# if CV_CXX_STD_ARRAY == 0
# undef CV_CXX_STD_ARRAY
# endif
#endif
//! @}
#endif // OPENCV_CORE_CVDEF_H

@ -165,7 +165,9 @@ public:
UMAT =10 << KIND_SHIFT,
STD_VECTOR_UMAT =11 << KIND_SHIFT,
STD_BOOL_VECTOR =12 << KIND_SHIFT,
STD_VECTOR_CUDA_GPU_MAT = 13 << KIND_SHIFT
STD_VECTOR_CUDA_GPU_MAT = 13 << KIND_SHIFT,
STD_ARRAY =14 << KIND_SHIFT,
STD_ARRAY_MAT =15 << KIND_SHIFT
};
_InputArray();
@ -189,6 +191,11 @@ public:
_InputArray(const UMat& um);
_InputArray(const std::vector<UMat>& umv);
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _N> _InputArray(const std::array<_Tp, _N>& arr);
template<std::size_t _N> _InputArray(const std::array<Mat, _N>& arr);
#endif
Mat getMat(int idx=-1) const;
Mat getMat_(int idx=-1) const;
UMat getUMat(int idx=-1) const;
@ -316,6 +323,13 @@ public:
_OutputArray(const UMat& m);
_OutputArray(const std::vector<UMat>& vec);
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _N> _OutputArray(std::array<_Tp, _N>& arr);
template<typename _Tp, std::size_t _N> _OutputArray(const std::array<_Tp, _N>& arr);
template<std::size_t _N> _OutputArray(std::array<Mat, _N>& arr);
template<std::size_t _N> _OutputArray(const std::array<Mat, _N>& arr);
#endif
bool fixedSize() const;
bool fixedType() const;
bool needed() const;
@ -374,6 +388,14 @@ public:
template<typename _Tp, int m, int n> _InputOutputArray(const Matx<_Tp, m, n>& matx);
_InputOutputArray(const UMat& m);
_InputOutputArray(const std::vector<UMat>& vec);
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _N> _InputOutputArray(std::array<_Tp, _N>& arr);
template<typename _Tp, std::size_t _N> _InputOutputArray(const std::array<_Tp, _N>& arr);
template<std::size_t _N> _InputOutputArray(std::array<Mat, _N>& arr);
template<std::size_t _N> _InputOutputArray(const std::array<Mat, _N>& arr);
#endif
};
typedef const _InputArray& InputArray;
@ -955,6 +977,12 @@ public:
*/
template<typename _Tp> explicit Mat(const std::vector<_Tp>& vec, bool copyData=false);
#ifdef CV_CXX_STD_ARRAY
/** @overload
*/
template<typename _Tp, size_t _N> explicit Mat(const std::array<_Tp, _N>& arr, bool copyData=false);
#endif
/** @overload
*/
template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true);
@ -1575,6 +1603,10 @@ public:
template<typename _Tp, int n> operator Vec<_Tp, n>() const;
template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const;
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _N> operator std::array<_Tp, _N>() const;
#endif
/** @brief Reports whether the matrix is continuous or not.
The method returns true if the matrix elements are stored continuously without gaps at the end of
@ -2114,6 +2146,10 @@ public:
explicit Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
#ifdef CV_CXX_STD_ARRAY
template <std::size_t _N> explicit Mat_(const std::array<_Tp, _N>& arr, bool copyData=false);
#endif
Mat_& operator = (const Mat& m);
Mat_& operator = (const Mat_& m);
//! set all the elements to s.
@ -2207,6 +2243,12 @@ public:
//! conversion to vector.
operator std::vector<_Tp>() const;
#ifdef CV_CXX_STD_ARRAY
//! conversion to array.
template<std::size_t _N> operator std::array<_Tp, _N>() const;
#endif
//! conversion to Vec
template<int n> operator Vec<typename DataType<_Tp>::channel_type, n>() const;
//! conversion to Matx
@ -2281,6 +2323,7 @@ public:
UMat(const UMat& m, const std::vector<Range>& ranges);
//! builds matrix from std::vector with or without copying the data
template<typename _Tp> explicit UMat(const std::vector<_Tp>& vec, bool copyData=false);
//! builds matrix from cv::Vec; the data is copied by default
template<typename _Tp, int n> explicit UMat(const Vec<_Tp, n>& vec, bool copyData=true);
//! builds matrix from cv::Matx; the data is copied by default

@ -77,6 +77,16 @@ template<typename _Tp> inline
_InputArray::_InputArray(const std::vector<_Tp>& vec)
{ init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_READ, &vec); }
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _N> inline
_InputArray::_InputArray(const std::array<_Tp, _N>& arr)
{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + DataType<_Tp>::type + ACCESS_READ, arr.data(), Size(1, _N)); }
template<std::size_t _N> inline
_InputArray::_InputArray(const std::array<Mat, _N>& arr)
{ init(STD_ARRAY_MAT + ACCESS_READ, arr.data(), Size(1, _N)); }
#endif
inline
_InputArray::_InputArray(const std::vector<bool>& vec)
{ init(FIXED_TYPE + STD_BOOL_VECTOR + DataType<bool>::type + ACCESS_READ, &vec); }
@ -133,7 +143,9 @@ inline bool _InputArray::isUMat() const { return kind() == _InputArray::UMAT; }
inline bool _InputArray::isMatVector() const { return kind() == _InputArray::STD_VECTOR_MAT; }
inline bool _InputArray::isUMatVector() const { return kind() == _InputArray::STD_VECTOR_UMAT; }
inline bool _InputArray::isMatx() const { return kind() == _InputArray::MATX; }
inline bool _InputArray::isVector() const { return kind() == _InputArray::STD_VECTOR || kind() == _InputArray::STD_BOOL_VECTOR; }
inline bool _InputArray::isVector() const { return kind() == _InputArray::STD_VECTOR ||
kind() == _InputArray::STD_BOOL_VECTOR ||
kind() == _InputArray::STD_ARRAY; }
inline bool _InputArray::isGpuMatVector() const { return kind() == _InputArray::STD_VECTOR_CUDA_GPU_MAT; }
////////////////////////////////////////////////////////////////////////////////////////
@ -149,6 +161,16 @@ template<typename _Tp> inline
_OutputArray::_OutputArray(std::vector<_Tp>& vec)
{ init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _N> inline
_OutputArray::_OutputArray(std::array<_Tp, _N>& arr)
{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + DataType<_Tp>::type + ACCESS_WRITE, arr.data(), Size(1, _N)); }
template<std::size_t _N> inline
_OutputArray::_OutputArray(std::array<Mat, _N>& arr)
{ init(STD_ARRAY_MAT + ACCESS_WRITE, arr.data(), Size(1, _N)); }
#endif
inline
_OutputArray::_OutputArray(std::vector<bool>&)
{ CV_Error(Error::StsUnsupportedFormat, "std::vector<bool> cannot be an output array\n"); }
@ -177,6 +199,16 @@ template<typename _Tp> inline
_OutputArray::_OutputArray(const std::vector<_Tp>& vec)
{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _N> inline
_OutputArray::_OutputArray(const std::array<_Tp, _N>& arr)
{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + DataType<_Tp>::type + ACCESS_WRITE, arr.data(), Size(1, _N)); }
template<std::size_t _N> inline
_OutputArray::_OutputArray(const std::array<Mat, _N>& arr)
{ init(FIXED_SIZE + STD_ARRAY_MAT + ACCESS_WRITE, arr.data(), Size(1, _N)); }
#endif
template<typename _Tp> inline
_OutputArray::_OutputArray(const std::vector<std::vector<_Tp> >& vec)
{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); }
@ -244,6 +276,16 @@ template<typename _Tp> inline
_InputOutputArray::_InputOutputArray(std::vector<_Tp>& vec)
{ init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _N> inline
_InputOutputArray::_InputOutputArray(std::array<_Tp, _N>& arr)
{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + DataType<_Tp>::type + ACCESS_RW, arr.data(), Size(1, _N)); }
template<std::size_t _N> inline
_InputOutputArray::_InputOutputArray(std::array<Mat, _N>& arr)
{ init(STD_ARRAY_MAT + ACCESS_RW, arr.data(), Size(1, _N)); }
#endif
inline _InputOutputArray::_InputOutputArray(std::vector<bool>&)
{ CV_Error(Error::StsUnsupportedFormat, "std::vector<bool> cannot be an input/output array\n"); }
@ -271,6 +313,16 @@ template<typename _Tp> inline
_InputOutputArray::_InputOutputArray(const std::vector<_Tp>& vec)
{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _N> inline
_InputOutputArray::_InputOutputArray(const std::array<_Tp, _N>& arr)
{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + DataType<_Tp>::type + ACCESS_RW, arr.data(), Size(1, _N)); }
template<std::size_t _N> inline
_InputOutputArray::_InputOutputArray(const std::array<Mat, _N>& arr)
{ init(FIXED_SIZE + STD_ARRAY_MAT + ACCESS_RW, arr.data(), Size(1, _N)); }
#endif
template<typename _Tp> inline
_InputOutputArray::_InputOutputArray(const std::vector<std::vector<_Tp> >& vec)
{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); }
@ -505,6 +557,25 @@ Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
}
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _N> inline
Mat::Mat(const std::array<_Tp, _N>& arr, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)arr.size()),
cols(1), data(0), datastart(0), dataend(0), allocator(0), u(0), size(&rows)
{
if(arr.empty())
return;
if( !copyData )
{
step[0] = step[1] = sizeof(_Tp);
datastart = data = (uchar*)arr.data();
datalimit = dataend = datastart + rows * step[0];
}
else
Mat((int)arr.size(), 1, DataType<_Tp>::type, (uchar*)arr.data()).copyTo(*this);
}
#endif
template<typename _Tp, int n> inline
Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0),
@ -1114,6 +1185,16 @@ Mat::operator std::vector<_Tp>() const
return v;
}
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp, std::size_t _N> inline
Mat::operator std::array<_Tp, _N>() const
{
std::array<_Tp, _N> v;
copyTo(v);
return v;
}
#endif
template<typename _Tp, int n> inline
Mat::operator Vec<_Tp, n>() const
{
@ -1468,6 +1549,13 @@ Mat_<_Tp>::Mat_(const std::vector<_Tp>& vec, bool copyData)
: Mat(vec, copyData)
{}
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp> template<std::size_t _N> inline
Mat_<_Tp>::Mat_(const std::array<_Tp, _N>& arr, bool copyData)
: Mat(arr, copyData)
{}
#endif
template<typename _Tp> inline
Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
{
@ -1745,6 +1833,16 @@ Mat_<_Tp>::operator std::vector<_Tp>() const
return v;
}
#ifdef CV_CXX_STD_ARRAY
template<typename _Tp> template<std::size_t _N> inline
Mat_<_Tp>::operator std::array<_Tp, _N>() const
{
std::array<_Tp, _N> a;
copyTo(a);
return a;
}
#endif
template<typename _Tp> template<int n> inline
Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const
{
@ -3426,7 +3524,6 @@ cols(1), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
}
inline
UMat& UMat::operator = (const UMat& m)
{

@ -637,9 +637,11 @@ void cv::mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst,
ocl_mixChannels(src, dst, fromTo, npairs))
bool src_is_mat = src.kind() != _InputArray::STD_VECTOR_MAT &&
src.kind() != _InputArray::STD_ARRAY_MAT &&
src.kind() != _InputArray::STD_VECTOR_VECTOR &&
src.kind() != _InputArray::STD_VECTOR_UMAT;
bool dst_is_mat = dst.kind() != _InputArray::STD_VECTOR_MAT &&
dst.kind() != _InputArray::STD_ARRAY_MAT &&
dst.kind() != _InputArray::STD_VECTOR_VECTOR &&
dst.kind() != _InputArray::STD_VECTOR_UMAT;
int i;
@ -668,9 +670,11 @@ void cv::mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst,
ocl_mixChannels(src, dst, &fromTo[0], fromTo.size()>>1))
bool src_is_mat = src.kind() != _InputArray::STD_VECTOR_MAT &&
src.kind() != _InputArray::STD_ARRAY_MAT &&
src.kind() != _InputArray::STD_VECTOR_VECTOR &&
src.kind() != _InputArray::STD_VECTOR_UMAT;
bool dst_is_mat = dst.kind() != _InputArray::STD_VECTOR_MAT &&
dst.kind() != _InputArray::STD_ARRAY_MAT &&
dst.kind() != _InputArray::STD_VECTOR_VECTOR &&
dst.kind() != _InputArray::STD_VECTOR_UMAT;
int i;

@ -53,7 +53,8 @@ static Mat argsort(InputArray _src, bool ascending=true)
static Mat asRowMatrix(InputArrayOfArrays src, int rtype, double alpha=1, double beta=0) {
// make sure the input data is a vector of matrices or vector of vector
if(src.kind() != _InputArray::STD_VECTOR_MAT && src.kind() != _InputArray::STD_VECTOR_VECTOR) {
if(src.kind() != _InputArray::STD_VECTOR_MAT && src.kind() != _InputArray::STD_ARRAY_MAT &&
src.kind() != _InputArray::STD_VECTOR_VECTOR) {
String error_message = "The data is expected as InputArray::STD_VECTOR_MAT (a std::vector<Mat>) or _InputArray::STD_VECTOR_VECTOR (a std::vector< std::vector<...> >).";
CV_Error(Error::StsBadArg, error_message);
}
@ -1096,6 +1097,7 @@ void LDA::lda(InputArrayOfArrays _src, InputArray _lbls) {
void LDA::compute(InputArrayOfArrays _src, InputArray _lbls) {
switch(_src.kind()) {
case _InputArray::STD_VECTOR_MAT:
case _InputArray::STD_ARRAY_MAT:
lda(asRowMatrix(_src, CV_64FC1), _lbls);
break;
case _InputArray::MAT:

@ -2579,7 +2579,7 @@ void cv::calcCovarMatrix( InputArray _src, OutputArray _covar, InputOutputArray
{
CV_INSTRUMENT_REGION()
if(_src.kind() == _InputArray::STD_VECTOR_MAT)
if(_src.kind() == _InputArray::STD_VECTOR_MAT || _src.kind() == _InputArray::STD_ARRAY_MAT)
{
std::vector<cv::Mat> src;
_src.getMatVector(src);

@ -1235,7 +1235,7 @@ Mat _InputArray::getMat_(int i) const
return (Mat)*((const MatExpr*)obj);
}
if( k == MATX )
if( k == MATX || k == STD_ARRAY )
{
CV_Assert( i < 0 );
return Mat(sz, flags, obj);
@ -1286,6 +1286,14 @@ Mat _InputArray::getMat_(int i) const
return v[i];
}
if( k == STD_ARRAY_MAT )
{
const Mat* v = (const Mat*)obj;
CV_Assert( 0 <= i && i < sz.height );
return v[i];
}
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
@ -1381,7 +1389,7 @@ void _InputArray::getMatVector(std::vector<Mat>& mv) const
return;
}
if( k == MATX )
if( k == MATX || k == STD_ARRAY )
{
size_t n = sz.height, esz = CV_ELEM_SIZE(flags);
mv.resize(n);
@ -1436,6 +1444,17 @@ void _InputArray::getMatVector(std::vector<Mat>& mv) const
return;
}
if( k == STD_ARRAY_MAT )
{
const Mat* v = (const Mat*)obj;
size_t n = sz.height;
mv.resize(n);
for( size_t i = 0; i < n; i++ )
mv[i] = v[i];
return;
}
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
@ -1472,6 +1491,17 @@ void _InputArray::getUMatVector(std::vector<UMat>& umv) const
return;
}
if( k == STD_ARRAY_MAT )
{
const Mat* v = (const Mat*)obj;
size_t n = sz.height;
umv.resize(n);
for( size_t i = 0; i < n; i++ )
umv[i] = v[i].getUMat(accessFlags);
return;
}
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
@ -1584,7 +1614,7 @@ Size _InputArray::size(int i) const
return ((const UMat*)obj)->size();
}
if( k == MATX )
if( k == MATX || k == STD_ARRAY )
{
CV_Assert( i < 0 );
return sz;
@ -1631,6 +1661,16 @@ Size _InputArray::size(int i) const
return vv[i].size();
}
if( k == STD_ARRAY_MAT )
{
const Mat* vv = (const Mat*)obj;
if( i < 0 )
return sz.height==0 ? Size() : Size(sz.height, 1);
CV_Assert( i < sz.height );
return vv[i].size();
}
if (k == STD_VECTOR_CUDA_GPU_MAT)
{
const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
@ -1709,6 +1749,16 @@ int _InputArray::sizend(int* arrsz, int i) const
for(j = 0; j < d; j++)
arrsz[j] = m.size.p[j];
}
else if( k == STD_ARRAY_MAT && i >= 0 )
{
const Mat* vv = (const Mat*)obj;
CV_Assert( i < sz.height );
const Mat& m = vv[i];
d = m.dims;
if(arrsz)
for(j = 0; j < d; j++)
arrsz[j] = m.size.p[j];
}
else if( k == STD_VECTOR_UMAT && i >= 0 )
{
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
@ -1789,7 +1839,7 @@ int _InputArray::dims(int i) const
return ((const UMat*)obj)->dims;
}
if( k == MATX )
if( k == MATX || k == STD_ARRAY )
{
CV_Assert( i < 0 );
return 2;
@ -1823,6 +1873,16 @@ int _InputArray::dims(int i) const
return vv[i].dims;
}
if( k == STD_ARRAY_MAT )
{
const Mat* vv = (const Mat*)obj;
if( i < 0 )
return 1;
CV_Assert( i < sz.height );
return vv[i].dims;
}
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
@ -1881,6 +1941,15 @@ size_t _InputArray::total(int i) const
return vv[i].total();
}
if( k == STD_ARRAY_MAT )
{
const Mat* vv = (const Mat*)obj;
if( i < 0 )
return sz.height;
CV_Assert( i < sz.height );
return vv[i].total();
}
if( k == STD_VECTOR_UMAT )
{
@ -1908,7 +1977,7 @@ int _InputArray::type(int i) const
if( k == EXPR )
return ((const MatExpr*)obj)->type();
if( k == MATX || k == STD_VECTOR || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
if( k == MATX || k == STD_VECTOR || k == STD_ARRAY || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
return CV_MAT_TYPE(flags);
if( k == NONE )
@ -1938,6 +2007,18 @@ int _InputArray::type(int i) const
return vv[i >= 0 ? i : 0].type();
}
if( k == STD_ARRAY_MAT )
{
const Mat* vv = (const Mat*)obj;
if( sz.height == 0 )
{
CV_Assert((flags & FIXED_TYPE) != 0);
return CV_MAT_TYPE(flags);
}
CV_Assert( i < sz.height );
return vv[i >= 0 ? i : 0].type();
}
if (k == STD_VECTOR_CUDA_GPU_MAT)
{
const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
@ -1986,7 +2067,7 @@ bool _InputArray::empty() const
if( k == EXPR )
return false;
if( k == MATX )
if( k == MATX || k == STD_ARRAY )
return false;
if( k == STD_VECTOR )
@ -2016,6 +2097,11 @@ bool _InputArray::empty() const
return vv.empty();
}
if( k == STD_ARRAY_MAT )
{
return sz.height == 0;
}
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
@ -2051,7 +2137,7 @@ bool _InputArray::isContinuous(int i) const
if( k == UMAT )
return i < 0 ? ((const UMat*)obj)->isContinuous() : true;
if( k == EXPR || k == MATX || k == STD_VECTOR ||
if( k == EXPR || k == MATX || k == STD_VECTOR || k == STD_ARRAY ||
k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
return true;
@ -2062,6 +2148,13 @@ bool _InputArray::isContinuous(int i) const
return vv[i].isContinuous();
}
if( k == STD_ARRAY_MAT )
{
const Mat* vv = (const Mat*)obj;
CV_Assert(i < sz.height);
return vv[i].isContinuous();
}
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
@ -2086,7 +2179,7 @@ bool _InputArray::isSubmatrix(int i) const
if( k == UMAT )
return i < 0 ? ((const UMat*)obj)->isSubmatrix() : false;
if( k == EXPR || k == MATX || k == STD_VECTOR ||
if( k == EXPR || k == MATX || k == STD_VECTOR || k == STD_ARRAY ||
k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
return false;
@ -2097,6 +2190,13 @@ bool _InputArray::isSubmatrix(int i) const
return vv[i].isSubmatrix();
}
if( k == STD_ARRAY_MAT )
{
const Mat* vv = (const Mat*)obj;
CV_Assert(i < sz.height);
return vv[i].isSubmatrix();
}
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
@ -2125,7 +2225,7 @@ size_t _InputArray::offset(int i) const
return ((const UMat*)obj)->offset;
}
if( k == EXPR || k == MATX || k == STD_VECTOR ||
if( k == EXPR || k == MATX || k == STD_VECTOR || k == STD_ARRAY ||
k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
return 0;
@ -2139,6 +2239,15 @@ size_t _InputArray::offset(int i) const
return (size_t)(vv[i].ptr() - vv[i].datastart);
}
if( k == STD_ARRAY_MAT )
{
const Mat* vv = (const Mat*)obj;
if( i < 0 )
return 1;
CV_Assert( i < sz.height );
return (size_t)(vv[i].ptr() - vv[i].datastart);
}
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
@ -2180,7 +2289,7 @@ size_t _InputArray::step(int i) const
return ((const UMat*)obj)->step;
}
if( k == EXPR || k == MATX || k == STD_VECTOR ||
if( k == EXPR || k == MATX || k == STD_VECTOR || k == STD_ARRAY ||
k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
return 0;
@ -2193,6 +2302,15 @@ size_t _InputArray::step(int i) const
return vv[i].step;
}
if( k == STD_ARRAY_MAT )
{
const Mat* vv = (const Mat*)obj;
if( i < 0 )
return 1;
CV_Assert( i < sz.height );
return vv[i].step;
}
if( k == STD_VECTOR_UMAT )
{
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
@ -2222,7 +2340,7 @@ void _InputArray::copyTo(const _OutputArray& arr) const
if( k == NONE )
arr.release();
else if( k == MAT || k == MATX || k == STD_VECTOR || k == STD_BOOL_VECTOR )
else if( k == MAT || k == MATX || k == STD_VECTOR || k == STD_ARRAY || k == STD_BOOL_VECTOR )
{
Mat m = getMat();
m.copyTo(arr);
@ -2247,7 +2365,7 @@ void _InputArray::copyTo(const _OutputArray& arr, const _InputArray & mask) cons
if( k == NONE )
arr.release();
else if( k == MAT || k == MATX || k == STD_VECTOR || k == STD_BOOL_VECTOR )
else if( k == MAT || k == MATX || k == STD_VECTOR || k == STD_ARRAY || k == STD_BOOL_VECTOR )
{
Mat m = getMat();
m.copyTo(arr, mask);
@ -2436,6 +2554,14 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i,
return;
}
if( k == STD_ARRAY )
{
int type0 = CV_MAT_TYPE(flags);
CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == 1 && ((1 << type0) & fixedDepthMask) != 0) );
CV_Assert( d == 2 && sz.area() == sizes[0]*sizes[1]);
return;
}
if( k == STD_VECTOR || k == STD_VECTOR_VECTOR )
{
CV_Assert( d == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) );
@ -2583,6 +2709,65 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i,
return;
}
if( k == STD_ARRAY_MAT )
{
Mat* v = (Mat*)obj;
if( i < 0 )
{
CV_Assert( d == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) );
size_t len = sizes[0]*sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0, len0 = sz.height;
CV_Assert(len == len0);
if( fixedType() )
{
int _type = CV_MAT_TYPE(flags);
for( size_t j = len0; j < len; j++ )
{
if( v[j].type() == _type )
continue;
CV_Assert( v[j].empty() );
v[j].flags = (v[j].flags & ~CV_MAT_TYPE_MASK) | _type;
}
}
return;
}
CV_Assert( i < sz.height );
Mat& m = v[i];
if( allowTransposed )
{
if( !m.isContinuous() )
{
CV_Assert(!fixedType() && !fixedSize());
m.release();
}
if( d == 2 && m.dims == 2 && m.data &&
m.type() == mtype && m.rows == sizes[1] && m.cols == sizes[0] )
return;
}
if(fixedType())
{
if(CV_MAT_CN(mtype) == m.channels() && ((1 << CV_MAT_TYPE(flags)) & fixedDepthMask) != 0 )
mtype = m.type();
else
CV_Assert(CV_MAT_TYPE(mtype) == m.type());
}
if(fixedSize())
{
CV_Assert(m.dims == d);
for(int j = 0; j < d; ++j)
CV_Assert(m.size[j] == sizes[j]);
}
m.create(d, sizes, mtype);
return;
}
if( k == STD_VECTOR_UMAT )
{
std::vector<UMat>& v = *(std::vector<UMat>*)obj;
@ -2748,13 +2933,21 @@ Mat& _OutputArray::getMatRef(int i) const
CV_Assert( k == MAT );
return *(Mat*)obj;
}
else
CV_Assert( k == STD_VECTOR_MAT || k == STD_ARRAY_MAT );
if( k == STD_VECTOR_MAT )
{
CV_Assert( k == STD_VECTOR_MAT );
std::vector<Mat>& v = *(std::vector<Mat>*)obj;
CV_Assert( i < (int)v.size() );
return v[i];
}
else
{
Mat* v = (Mat*)obj;
CV_Assert( 0 <= i && i < sz.height );
return v[i];
}
}
UMat& _OutputArray::getUMatRef(int i) const
@ -2807,7 +3000,7 @@ void _OutputArray::setTo(const _InputArray& arr, const _InputArray & mask) const
if( k == NONE )
;
else if( k == MAT || k == MATX || k == STD_VECTOR )
else if( k == MAT || k == MATX || k == STD_VECTOR || k == STD_ARRAY )
{
Mat m = getMat();
m.setTo(arr, mask);

@ -1634,3 +1634,95 @@ TEST(Mat, regression_7873_mat_vector_initialize)
ASSERT_EQ(3, sub_mat.size[1]);
ASSERT_EQ(2, sub_mat.size[2]);
}
#ifdef CV_CXX_STD_ARRAY
TEST(Core_Mat_array, outputArray_create_getMat)
{
cv::Mat_<uchar> src_base(5, 1);
std::array<uchar, 5> dst8;
src_base << 1, 2, 3, 4, 5;
Mat src(src_base);
OutputArray _dst(dst8);
{
_dst.create(src.rows, src.cols, src.type());
Mat dst = _dst.getMat();
EXPECT_EQ(src.dims, dst.dims);
EXPECT_EQ(src.cols, dst.cols);
EXPECT_EQ(src.rows, dst.rows);
}
}
TEST(Core_Mat_array, copyTo_roi_column)
{
cv::Mat_<uchar> src_base(5, 2);
src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
Mat src_full(src_base);
Mat src(src_full.col(0));
std::array<uchar, 5> dst1;
src.copyTo(dst1);
std::cout << "src = " << src << std::endl;
std::cout << "dst = " << Mat(dst1) << std::endl;
EXPECT_EQ((size_t)5, dst1.size());
EXPECT_EQ(1, (int)dst1[0]);
EXPECT_EQ(3, (int)dst1[1]);
EXPECT_EQ(5, (int)dst1[2]);
EXPECT_EQ(7, (int)dst1[3]);
EXPECT_EQ(9, (int)dst1[4]);
}
TEST(Core_Mat_array, copyTo_roi_row)
{
cv::Mat_<uchar> src_base(2, 5);
std::array<uchar, 5> dst1;
src_base << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
Mat src_full(src_base);
Mat src(src_full.row(0));
OutputArray _dst(dst1);
{
_dst.create(5, 1, src.type());
Mat dst = _dst.getMat();
EXPECT_EQ(src.dims, dst.dims);
EXPECT_EQ(1, dst.cols);
EXPECT_EQ(5, dst.rows);
}
std::array<uchar, 5> dst2;
src.copyTo(dst2);
std::cout << "src = " << src << std::endl;
std::cout << "dst = " << Mat(dst2) << std::endl;
EXPECT_EQ(1, (int)dst2[0]);
EXPECT_EQ(2, (int)dst2[1]);
EXPECT_EQ(3, (int)dst2[2]);
EXPECT_EQ(4, (int)dst2[3]);
EXPECT_EQ(5, (int)dst2[4]);
}
TEST(Core_Mat_array, SplitMerge)
{
std::array<cv::Mat, 3> src;
for(size_t i=0; i<src.size(); ++i) {
src[i].create(10, 10, CV_8U);
src[i] = 127 * i;
}
Mat merged;
merge(src, merged);
std::array<cv::Mat, 3> dst;
split(merged, dst);
Mat diff;
for(size_t i=0; i<dst.size(); ++i) {
absdiff(src[i], dst[i], diff);
EXPECT_EQ(0, countNonZero(diff));
}
}
#endif
Loading…
Cancel
Save