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
#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 #endif // OPENCV_CORE_CVDEF_H

@ -165,7 +165,9 @@ public:
UMAT =10 << KIND_SHIFT, UMAT =10 << KIND_SHIFT,
STD_VECTOR_UMAT =11 << KIND_SHIFT, STD_VECTOR_UMAT =11 << KIND_SHIFT,
STD_BOOL_VECTOR =12 << 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(); _InputArray();
@ -189,6 +191,11 @@ public:
_InputArray(const UMat& um); _InputArray(const UMat& um);
_InputArray(const std::vector<UMat>& umv); _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;
Mat getMat_(int idx=-1) const; Mat getMat_(int idx=-1) const;
UMat getUMat(int idx=-1) const; UMat getUMat(int idx=-1) const;
@ -316,6 +323,13 @@ public:
_OutputArray(const UMat& m); _OutputArray(const UMat& m);
_OutputArray(const std::vector<UMat>& vec); _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 fixedSize() const;
bool fixedType() const; bool fixedType() const;
bool needed() const; bool needed() const;
@ -374,6 +388,14 @@ public:
template<typename _Tp, int m, int n> _InputOutputArray(const Matx<_Tp, m, n>& matx); template<typename _Tp, int m, int n> _InputOutputArray(const Matx<_Tp, m, n>& matx);
_InputOutputArray(const UMat& m); _InputOutputArray(const UMat& m);
_InputOutputArray(const std::vector<UMat>& vec); _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; typedef const _InputArray& InputArray;
@ -955,6 +977,12 @@ public:
*/ */
template<typename _Tp> explicit Mat(const std::vector<_Tp>& vec, bool copyData=false); 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 /** @overload
*/ */
template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true); 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 n> operator Vec<_Tp, n>() const;
template<typename _Tp, int m, int n> operator Matx<_Tp, m, 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. /** @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 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 Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer); 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);
Mat_& operator = (const Mat_& m); Mat_& operator = (const Mat_& m);
//! set all the elements to s. //! set all the elements to s.
@ -2207,6 +2243,12 @@ public:
//! conversion to vector. //! conversion to vector.
operator std::vector<_Tp>() const; 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 //! conversion to Vec
template<int n> operator Vec<typename DataType<_Tp>::channel_type, n>() const; template<int n> operator Vec<typename DataType<_Tp>::channel_type, n>() const;
//! conversion to Matx //! conversion to Matx
@ -2281,6 +2323,7 @@ public:
UMat(const UMat& m, const std::vector<Range>& ranges); UMat(const UMat& m, const std::vector<Range>& ranges);
//! builds matrix from std::vector with or without copying the data //! builds matrix from std::vector with or without copying the data
template<typename _Tp> explicit UMat(const std::vector<_Tp>& vec, bool copyData=false); template<typename _Tp> explicit UMat(const std::vector<_Tp>& vec, bool copyData=false);
//! builds matrix from cv::Vec; the data is copied by default //! 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); 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 //! 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) _InputArray::_InputArray(const std::vector<_Tp>& vec)
{ init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_READ, &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 inline
_InputArray::_InputArray(const std::vector<bool>& vec) _InputArray::_InputArray(const std::vector<bool>& vec)
{ init(FIXED_TYPE + STD_BOOL_VECTOR + DataType<bool>::type + ACCESS_READ, &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::isMatVector() const { return kind() == _InputArray::STD_VECTOR_MAT; }
inline bool _InputArray::isUMatVector() const { return kind() == _InputArray::STD_VECTOR_UMAT; } inline bool _InputArray::isUMatVector() const { return kind() == _InputArray::STD_VECTOR_UMAT; }
inline bool _InputArray::isMatx() const { return kind() == _InputArray::MATX; } 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; } 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) _OutputArray::_OutputArray(std::vector<_Tp>& vec)
{ init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &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 inline
_OutputArray::_OutputArray(std::vector<bool>&) _OutputArray::_OutputArray(std::vector<bool>&)
{ CV_Error(Error::StsUnsupportedFormat, "std::vector<bool> cannot be an output array\n"); } { 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) _OutputArray::_OutputArray(const std::vector<_Tp>& vec)
{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &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 template<typename _Tp> inline
_OutputArray::_OutputArray(const std::vector<std::vector<_Tp> >& vec) _OutputArray::_OutputArray(const std::vector<std::vector<_Tp> >& vec)
{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &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) _InputOutputArray::_InputOutputArray(std::vector<_Tp>& vec)
{ init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &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>&) inline _InputOutputArray::_InputOutputArray(std::vector<bool>&)
{ CV_Error(Error::StsUnsupportedFormat, "std::vector<bool> cannot be an input/output array\n"); } { 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) _InputOutputArray::_InputOutputArray(const std::vector<_Tp>& vec)
{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &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 template<typename _Tp> inline
_InputOutputArray::_InputOutputArray(const std::vector<std::vector<_Tp> >& vec) _InputOutputArray::_InputOutputArray(const std::vector<std::vector<_Tp> >& vec)
{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_RW, &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); 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 template<typename _Tp, int n> inline
Mat::Mat(const Vec<_Tp, n>& vec, bool copyData) 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), : 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; 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 template<typename _Tp, int n> inline
Mat::operator Vec<_Tp, n>() const Mat::operator Vec<_Tp, n>() const
{ {
@ -1468,6 +1549,13 @@ Mat_<_Tp>::Mat_(const std::vector<_Tp>& vec, bool copyData)
: Mat(vec, 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 template<typename _Tp> inline
Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m) Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
{ {
@ -1745,6 +1833,16 @@ Mat_<_Tp>::operator std::vector<_Tp>() const
return v; 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 template<typename _Tp> template<int n> inline
Mat_<_Tp>::operator Vec<typename DataType<_Tp>::channel_type, n>() const 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); Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
} }
inline inline
UMat& UMat::operator = (const UMat& m) UMat& UMat::operator = (const UMat& m)
{ {

@ -637,9 +637,11 @@ void cv::mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst,
ocl_mixChannels(src, dst, fromTo, npairs)) ocl_mixChannels(src, dst, fromTo, npairs))
bool src_is_mat = src.kind() != _InputArray::STD_VECTOR_MAT && 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_VECTOR &&
src.kind() != _InputArray::STD_VECTOR_UMAT; src.kind() != _InputArray::STD_VECTOR_UMAT;
bool dst_is_mat = dst.kind() != _InputArray::STD_VECTOR_MAT && 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_VECTOR &&
dst.kind() != _InputArray::STD_VECTOR_UMAT; dst.kind() != _InputArray::STD_VECTOR_UMAT;
int i; int i;
@ -668,9 +670,11 @@ void cv::mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst,
ocl_mixChannels(src, dst, &fromTo[0], fromTo.size()>>1)) ocl_mixChannels(src, dst, &fromTo[0], fromTo.size()>>1))
bool src_is_mat = src.kind() != _InputArray::STD_VECTOR_MAT && 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_VECTOR &&
src.kind() != _InputArray::STD_VECTOR_UMAT; src.kind() != _InputArray::STD_VECTOR_UMAT;
bool dst_is_mat = dst.kind() != _InputArray::STD_VECTOR_MAT && 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_VECTOR &&
dst.kind() != _InputArray::STD_VECTOR_UMAT; dst.kind() != _InputArray::STD_VECTOR_UMAT;
int i; 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) { 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 // 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<...> >)."; 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); CV_Error(Error::StsBadArg, error_message);
} }
@ -1096,6 +1097,7 @@ void LDA::lda(InputArrayOfArrays _src, InputArray _lbls) {
void LDA::compute(InputArrayOfArrays _src, InputArray _lbls) { void LDA::compute(InputArrayOfArrays _src, InputArray _lbls) {
switch(_src.kind()) { switch(_src.kind()) {
case _InputArray::STD_VECTOR_MAT: case _InputArray::STD_VECTOR_MAT:
case _InputArray::STD_ARRAY_MAT:
lda(asRowMatrix(_src, CV_64FC1), _lbls); lda(asRowMatrix(_src, CV_64FC1), _lbls);
break; break;
case _InputArray::MAT: case _InputArray::MAT:

@ -2579,7 +2579,7 @@ void cv::calcCovarMatrix( InputArray _src, OutputArray _covar, InputOutputArray
{ {
CV_INSTRUMENT_REGION() 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; std::vector<cv::Mat> src;
_src.getMatVector(src); _src.getMatVector(src);

@ -1235,7 +1235,7 @@ Mat _InputArray::getMat_(int i) const
return (Mat)*((const MatExpr*)obj); return (Mat)*((const MatExpr*)obj);
} }
if( k == MATX ) if( k == MATX || k == STD_ARRAY )
{ {
CV_Assert( i < 0 ); CV_Assert( i < 0 );
return Mat(sz, flags, obj); return Mat(sz, flags, obj);
@ -1286,6 +1286,14 @@ Mat _InputArray::getMat_(int i) const
return v[i]; 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 ) if( k == STD_VECTOR_UMAT )
{ {
const std::vector<UMat>& v = *(const std::vector<UMat>*)obj; const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
@ -1381,7 +1389,7 @@ void _InputArray::getMatVector(std::vector<Mat>& mv) const
return; return;
} }
if( k == MATX ) if( k == MATX || k == STD_ARRAY )
{ {
size_t n = sz.height, esz = CV_ELEM_SIZE(flags); size_t n = sz.height, esz = CV_ELEM_SIZE(flags);
mv.resize(n); mv.resize(n);
@ -1436,6 +1444,17 @@ void _InputArray::getMatVector(std::vector<Mat>& mv) const
return; 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 ) if( k == STD_VECTOR_UMAT )
{ {
const std::vector<UMat>& v = *(const std::vector<UMat>*)obj; const std::vector<UMat>& v = *(const std::vector<UMat>*)obj;
@ -1472,6 +1491,17 @@ void _InputArray::getUMatVector(std::vector<UMat>& umv) const
return; 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 ) if( k == STD_VECTOR_UMAT )
{ {
const std::vector<UMat>& v = *(const std::vector<UMat>*)obj; 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(); return ((const UMat*)obj)->size();
} }
if( k == MATX ) if( k == MATX || k == STD_ARRAY )
{ {
CV_Assert( i < 0 ); CV_Assert( i < 0 );
return sz; return sz;
@ -1631,6 +1661,16 @@ Size _InputArray::size(int i) const
return vv[i].size(); 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) if (k == STD_VECTOR_CUDA_GPU_MAT)
{ {
const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj; 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++) for(j = 0; j < d; j++)
arrsz[j] = m.size.p[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 ) else if( k == STD_VECTOR_UMAT && i >= 0 )
{ {
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj; 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; return ((const UMat*)obj)->dims;
} }
if( k == MATX ) if( k == MATX || k == STD_ARRAY )
{ {
CV_Assert( i < 0 ); CV_Assert( i < 0 );
return 2; return 2;
@ -1823,6 +1873,16 @@ int _InputArray::dims(int i) const
return vv[i].dims; 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 ) if( k == STD_VECTOR_UMAT )
{ {
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj; 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(); 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 ) if( k == STD_VECTOR_UMAT )
{ {
@ -1908,7 +1977,7 @@ int _InputArray::type(int i) const
if( k == EXPR ) if( k == EXPR )
return ((const MatExpr*)obj)->type(); 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); return CV_MAT_TYPE(flags);
if( k == NONE ) if( k == NONE )
@ -1938,6 +2007,18 @@ int _InputArray::type(int i) const
return vv[i >= 0 ? i : 0].type(); 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) if (k == STD_VECTOR_CUDA_GPU_MAT)
{ {
const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj; const std::vector<cuda::GpuMat>& vv = *(const std::vector<cuda::GpuMat>*)obj;
@ -1986,7 +2067,7 @@ bool _InputArray::empty() const
if( k == EXPR ) if( k == EXPR )
return false; return false;
if( k == MATX ) if( k == MATX || k == STD_ARRAY )
return false; return false;
if( k == STD_VECTOR ) if( k == STD_VECTOR )
@ -2016,6 +2097,11 @@ bool _InputArray::empty() const
return vv.empty(); return vv.empty();
} }
if( k == STD_ARRAY_MAT )
{
return sz.height == 0;
}
if( k == STD_VECTOR_UMAT ) if( k == STD_VECTOR_UMAT )
{ {
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj; const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
@ -2051,7 +2137,7 @@ bool _InputArray::isContinuous(int i) const
if( k == UMAT ) if( k == UMAT )
return i < 0 ? ((const UMat*)obj)->isContinuous() : true; 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 ) k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
return true; return true;
@ -2062,6 +2148,13 @@ bool _InputArray::isContinuous(int i) const
return vv[i].isContinuous(); 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 ) if( k == STD_VECTOR_UMAT )
{ {
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj; const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
@ -2086,7 +2179,7 @@ bool _InputArray::isSubmatrix(int i) const
if( k == UMAT ) if( k == UMAT )
return i < 0 ? ((const UMat*)obj)->isSubmatrix() : false; 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 ) k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
return false; return false;
@ -2097,6 +2190,13 @@ bool _InputArray::isSubmatrix(int i) const
return vv[i].isSubmatrix(); 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 ) if( k == STD_VECTOR_UMAT )
{ {
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj; 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; 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 ) k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
return 0; return 0;
@ -2139,6 +2239,15 @@ size_t _InputArray::offset(int i) const
return (size_t)(vv[i].ptr() - vv[i].datastart); 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 ) if( k == STD_VECTOR_UMAT )
{ {
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj; 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; 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 ) k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR )
return 0; return 0;
@ -2193,6 +2302,15 @@ size_t _InputArray::step(int i) const
return vv[i].step; 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 ) if( k == STD_VECTOR_UMAT )
{ {
const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj; const std::vector<UMat>& vv = *(const std::vector<UMat>*)obj;
@ -2222,7 +2340,7 @@ void _InputArray::copyTo(const _OutputArray& arr) const
if( k == NONE ) if( k == NONE )
arr.release(); 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(); Mat m = getMat();
m.copyTo(arr); m.copyTo(arr);
@ -2247,7 +2365,7 @@ void _InputArray::copyTo(const _OutputArray& arr, const _InputArray & mask) cons
if( k == NONE ) if( k == NONE )
arr.release(); 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(); Mat m = getMat();
m.copyTo(arr, mask); m.copyTo(arr, mask);
@ -2436,6 +2554,14 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i,
return; 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 ) if( k == STD_VECTOR || k == STD_VECTOR_VECTOR )
{ {
CV_Assert( d == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0) ); 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; 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 ) if( k == STD_VECTOR_UMAT )
{ {
std::vector<UMat>& v = *(std::vector<UMat>*)obj; std::vector<UMat>& v = *(std::vector<UMat>*)obj;
@ -2748,13 +2933,21 @@ Mat& _OutputArray::getMatRef(int i) const
CV_Assert( k == MAT ); CV_Assert( k == MAT );
return *(Mat*)obj; 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; std::vector<Mat>& v = *(std::vector<Mat>*)obj;
CV_Assert( i < (int)v.size() ); CV_Assert( i < (int)v.size() );
return v[i]; return v[i];
} }
else
{
Mat* v = (Mat*)obj;
CV_Assert( 0 <= i && i < sz.height );
return v[i];
}
} }
UMat& _OutputArray::getUMatRef(int i) const UMat& _OutputArray::getUMatRef(int i) const
@ -2807,7 +3000,7 @@ void _OutputArray::setTo(const _InputArray& arr, const _InputArray & mask) const
if( k == NONE ) 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(); Mat m = getMat();
m.setTo(arr, mask); m.setTo(arr, mask);

@ -1634,3 +1634,95 @@ TEST(Mat, regression_7873_mat_vector_initialize)
ASSERT_EQ(3, sub_mat.size[1]); ASSERT_EQ(3, sub_mat.size[1]);
ASSERT_EQ(2, sub_mat.size[2]); 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