From 72f789bf34575ed9b9756028d25ef883568c9fd4 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 9 Feb 2017 14:52:27 +0300 Subject: [PATCH 1/6] core: fix type traits --- doc/Doxyfile.in | 2 +- .../core/include/opencv2/core/cvstd.inl.hpp | 2 +- modules/core/include/opencv2/core/mat.hpp | 5 + modules/core/include/opencv2/core/mat.inl.hpp | 249 +++++++++--------- modules/core/include/opencv2/core/matx.hpp | 44 +++- .../core/include/opencv2/core/persistence.hpp | 14 +- modules/core/include/opencv2/core/traits.hpp | 71 +++++ modules/core/test/test_operations.cpp | 2 +- modules/python/src2/cv2.cpp | 6 +- 9 files changed, 254 insertions(+), 141 deletions(-) diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index dd8d325c4d..1db5427338 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -107,7 +107,7 @@ RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = *.inl.hpp *.impl.hpp *_detail.hpp */cudev/**/detail/*.hpp *.m -EXCLUDE_SYMBOLS = cv::DataType<*> int void +EXCLUDE_SYMBOLS = cv::DataType<*> cv::traits::* int void CV__* EXAMPLE_PATH = @CMAKE_DOXYGEN_EXAMPLE_PATH@ EXAMPLE_PATTERNS = * EXAMPLE_RECURSIVE = YES diff --git a/modules/core/include/opencv2/core/cvstd.inl.hpp b/modules/core/include/opencv2/core/cvstd.inl.hpp index fb5d8ab1bb..85230f595d 100644 --- a/modules/core/include/opencv2/core/cvstd.inl.hpp +++ b/modules/core/include/opencv2/core/cvstd.inl.hpp @@ -233,7 +233,7 @@ template static inline std::ostream& operator << (std::ostream& out, const Vec<_Tp, n>& vec) { out << "["; - if(Vec<_Tp, n>::depth < CV_32F) + if (cv::traits::Depth<_Tp>::value <= CV_32S) { for (int i = 0; i < n - 1; ++i) { out << (int)vec[i] << ", "; diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index 990deb87de..8e35fd4dc4 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -1531,6 +1531,11 @@ public: */ template void push_back(const Mat_<_Tp>& elem); + /** @overload + @param elem Added element(s). + */ + template void push_back(const std::vector<_Tp>& elem); + /** @overload @param m Added line(s). */ diff --git a/modules/core/include/opencv2/core/mat.inl.hpp b/modules/core/include/opencv2/core/mat.inl.hpp index f1d69b4b04..934a8f07cb 100644 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@ -82,12 +82,12 @@ inline _InputArray::_InputArray(const std::vector& vec) { init(STD_VECTOR_ template inline _InputArray::_InputArray(const std::vector<_Tp>& vec) -{ init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_READ, &vec); } +{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec); } #ifdef CV_CXX_STD_ARRAY template inline _InputArray::_InputArray(const std::array<_Tp, _Nm>& arr) -{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + DataType<_Tp>::type + ACCESS_READ, arr.data(), Size(1, _Nm)); } +{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_READ, arr.data(), Size(1, _Nm)); } template inline _InputArray::_InputArray(const std::array& arr) @@ -96,11 +96,11 @@ _InputArray::_InputArray(const std::array& arr) inline _InputArray::_InputArray(const std::vector& vec) -{ init(FIXED_TYPE + STD_BOOL_VECTOR + DataType::type + ACCESS_READ, &vec); } +{ init(FIXED_TYPE + STD_BOOL_VECTOR + traits::Type::value + ACCESS_READ, &vec); } template inline _InputArray::_InputArray(const std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_READ, &vec); } +{ init(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec); } inline _InputArray::_InputArray(const std::vector >&) @@ -108,19 +108,19 @@ _InputArray::_InputArray(const std::vector >&) template inline _InputArray::_InputArray(const std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_READ, &vec); } +{ init(FIXED_TYPE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_READ, &vec); } template inline _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_READ, &mtx, Size(n, m)); } +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_READ, &mtx, Size(n, m)); } template inline _InputArray::_InputArray(const _Tp* vec, int n) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_READ, vec, Size(n, 1)); } +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_READ, vec, Size(n, 1)); } template inline _InputArray::_InputArray(const Mat_<_Tp>& m) -{ init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_READ, &m); } +{ init(FIXED_TYPE + MAT + traits::Type<_Tp>::value + ACCESS_READ, &m); } inline _InputArray::_InputArray(const double& val) { init(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F + ACCESS_READ, &val, Size(1,1)); } @@ -170,12 +170,12 @@ inline _OutputArray::_OutputArray(std::vector& vec) { init(STD_VECTOR_UMAT template inline _OutputArray::_OutputArray(std::vector<_Tp>& vec) -{ init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); } +{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } #ifdef CV_CXX_STD_ARRAY template inline _OutputArray::_OutputArray(std::array<_Tp, _Nm>& arr) -{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + DataType<_Tp>::type + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } +{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } template inline _OutputArray::_OutputArray(std::array& arr) @@ -188,7 +188,7 @@ _OutputArray::_OutputArray(std::vector&) template inline _OutputArray::_OutputArray(std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); } +{ init(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } inline _OutputArray::_OutputArray(std::vector >&) @@ -196,28 +196,28 @@ _OutputArray::_OutputArray(std::vector >&) template inline _OutputArray::_OutputArray(std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_WRITE, &vec); } +{ init(FIXED_TYPE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } template inline _OutputArray::_OutputArray(Mat_<_Tp>& m) -{ init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_WRITE, &m); } +{ init(FIXED_TYPE + MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &m); } template inline _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, &mtx, Size(n, m)); } +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, &mtx, Size(n, m)); } template inline _OutputArray::_OutputArray(_Tp* vec, int n) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, vec, Size(n, 1)); } +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, vec, Size(n, 1)); } template inline _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 + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } #ifdef CV_CXX_STD_ARRAY template inline _OutputArray::_OutputArray(const std::array<_Tp, _Nm>& arr) -{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + DataType<_Tp>::type + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } +{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } template inline _OutputArray::_OutputArray(const std::array& arr) @@ -226,23 +226,23 @@ _OutputArray::_OutputArray(const std::array& arr) template inline _OutputArray::_OutputArray(const std::vector >& vec) -{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_WRITE, &vec); } +{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } template inline _OutputArray::_OutputArray(const std::vector >& vec) -{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_WRITE, &vec); } +{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } template inline _OutputArray::_OutputArray(const Mat_<_Tp>& m) -{ init(FIXED_TYPE + FIXED_SIZE + MAT + DataType<_Tp>::type + ACCESS_WRITE, &m); } +{ init(FIXED_TYPE + FIXED_SIZE + MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &m); } template inline _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, &mtx, Size(n, m)); } +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, &mtx, Size(n, m)); } template inline _OutputArray::_OutputArray(const _Tp* vec, int n) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_WRITE, vec, Size(n, 1)); } +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, vec, Size(n, 1)); } inline _OutputArray::_OutputArray(cuda::GpuMat& d_mat) { init(CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); } @@ -289,12 +289,12 @@ inline _InputOutputArray::_InputOutputArray(std::vector& vec) { init(STD_V template inline _InputOutputArray::_InputOutputArray(std::vector<_Tp>& vec) -{ init(FIXED_TYPE + STD_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); } +{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec); } #ifdef CV_CXX_STD_ARRAY template inline _InputOutputArray::_InputOutputArray(std::array<_Tp, _Nm>& arr) -{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + DataType<_Tp>::type + ACCESS_RW, arr.data(), Size(1, _Nm)); } +{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_RW, arr.data(), Size(1, _Nm)); } template inline _InputOutputArray::_InputOutputArray(std::array& arr) @@ -306,32 +306,32 @@ inline _InputOutputArray::_InputOutputArray(std::vector&) template inline _InputOutputArray::_InputOutputArray(std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); } +{ init(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec); } template inline _InputOutputArray::_InputOutputArray(std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_RW, &vec); } +{ init(FIXED_TYPE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_RW, &vec); } template inline _InputOutputArray::_InputOutputArray(Mat_<_Tp>& m) -{ init(FIXED_TYPE + MAT + DataType<_Tp>::type + ACCESS_RW, &m); } +{ init(FIXED_TYPE + MAT + traits::Type<_Tp>::value + ACCESS_RW, &m); } template inline _InputOutputArray::_InputOutputArray(Matx<_Tp, m, n>& mtx) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, &mtx, Size(n, m)); } +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, &mtx, Size(n, m)); } template inline _InputOutputArray::_InputOutputArray(_Tp* vec, int n) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, vec, Size(n, 1)); } +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, vec, Size(n, 1)); } template inline _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 + traits::Type<_Tp>::value + ACCESS_RW, &vec); } #ifdef CV_CXX_STD_ARRAY template inline _InputOutputArray::_InputOutputArray(const std::array<_Tp, _Nm>& arr) -{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + DataType<_Tp>::type + ACCESS_RW, arr.data(), Size(1, _Nm)); } +{ init(FIXED_TYPE + FIXED_SIZE + STD_ARRAY + traits::Type<_Tp>::value + ACCESS_RW, arr.data(), Size(1, _Nm)); } template inline _InputOutputArray::_InputOutputArray(const std::array& arr) @@ -340,23 +340,23 @@ _InputOutputArray::_InputOutputArray(const std::array& arr) template inline _InputOutputArray::_InputOutputArray(const std::vector >& vec) -{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + DataType<_Tp>::type + ACCESS_RW, &vec); } +{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec); } template inline _InputOutputArray::_InputOutputArray(const std::vector >& vec) -{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + DataType<_Tp>::type + ACCESS_RW, &vec); } +{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_RW, &vec); } template inline _InputOutputArray::_InputOutputArray(const Mat_<_Tp>& m) -{ init(FIXED_TYPE + FIXED_SIZE + MAT + DataType<_Tp>::type + ACCESS_RW, &m); } +{ init(FIXED_TYPE + FIXED_SIZE + MAT + traits::Type<_Tp>::value + ACCESS_RW, &m); } template inline _InputOutputArray::_InputOutputArray(const Matx<_Tp, m, n>& mtx) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, &mtx, Size(n, m)); } +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, &mtx, Size(n, m)); } template inline _InputOutputArray::_InputOutputArray(const _Tp* vec, int n) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + DataType<_Tp>::type + ACCESS_RW, vec, Size(n, 1)); } +{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, vec, Size(n, 1)); } inline _InputOutputArray::_InputOutputArray(cuda::GpuMat& d_mat) { init(CUDA_GPU_MAT + ACCESS_RW, &d_mat); } @@ -559,7 +559,7 @@ Mat::Mat(Size _sz, int _type, void* _data, size_t _step) template inline Mat::Mat(const std::vector<_Tp>& vec, bool copyData) - : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()), + : flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()), cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) { if(vec.empty()) @@ -571,25 +571,25 @@ Mat::Mat(const std::vector<_Tp>& vec, bool copyData) datalimit = dataend = datastart + rows * step[0]; } else - Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this); + Mat((int)vec.size(), 1, traits::Type<_Tp>::value, (uchar*)&vec[0]).copyTo(*this); } #ifdef CV_CXX11 template inline Mat::Mat(const std::initializer_list<_Tp> list) - : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)list.size()), + : flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows((int)list.size()), cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) { if(list.size() == 0) return; - Mat((int)list.size(), 1, DataType<_Tp>::type, (uchar*)list.begin()).copyTo(*this); + Mat((int)list.size(), 1, traits::Type<_Tp>::value, (uchar*)list.begin()).copyTo(*this); } #endif #ifdef CV_CXX_STD_ARRAY template inline Mat::Mat(const std::array<_Tp, _Nm>& arr, bool copyData) - : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)arr.size()), + : flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows((int)arr.size()), cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) { if(arr.empty()) @@ -601,13 +601,13 @@ Mat::Mat(const std::array<_Tp, _Nm>& arr, bool copyData) datalimit = dataend = datastart + rows * step[0]; } else - Mat((int)arr.size(), 1, DataType<_Tp>::type, (uchar*)arr.data()).copyTo(*this); + Mat((int)arr.size(), 1, traits::Type<_Tp>::value, (uchar*)arr.data()).copyTo(*this); } #endif template 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), + : flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) { if( !copyData ) @@ -617,13 +617,13 @@ Mat::Mat(const Vec<_Tp, n>& vec, bool copyData) datalimit = dataend = datastart + rows * step[0]; } else - Mat(n, 1, DataType<_Tp>::type, (void*)vec.val).copyTo(*this); + Mat(n, 1, traits::Type<_Tp>::value, (void*)vec.val).copyTo(*this); } template inline Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData) - : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(m), cols(n), data(0), + : 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) { if( !copyData ) @@ -634,12 +634,12 @@ Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData) datalimit = dataend = datastart + rows * step[0]; } else - Mat(m, n, DataType<_Tp>::type, (uchar*)M.val).copyTo(*this); + Mat(m, n, traits::Type<_Tp>::value, (uchar*)M.val).copyTo(*this); } template inline Mat::Mat(const Point_<_Tp>& pt, bool copyData) - : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0), + : flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0) { if( !copyData ) @@ -650,7 +650,7 @@ Mat::Mat(const Point_<_Tp>& pt, bool copyData) } else { - create(2, 1, DataType<_Tp>::type); + create(2, 1, traits::Type<_Tp>::value); ((_Tp*)data)[0] = pt.x; ((_Tp*)data)[1] = pt.y; } @@ -658,7 +658,7 @@ Mat::Mat(const Point_<_Tp>& pt, bool copyData) template inline Mat::Mat(const Point3_<_Tp>& pt, bool copyData) - : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0), + : 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) { if( !copyData ) @@ -669,7 +669,7 @@ Mat::Mat(const Point3_<_Tp>& pt, bool copyData) } else { - create(3, 1, DataType<_Tp>::type); + create(3, 1, traits::Type<_Tp>::value); ((_Tp*)data)[0] = pt.x; ((_Tp*)data)[1] = pt.y; ((_Tp*)data)[2] = pt.z; @@ -678,7 +678,7 @@ Mat::Mat(const Point3_<_Tp>& pt, bool copyData) template inline Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer) - : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0), + : 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) { *this = commaInitializer.operator Mat_<_Tp>(); @@ -1065,7 +1065,7 @@ _Tp& Mat::at(int i0, int i1) CV_DbgAssert(data); CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels())); - CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1()); + CV_DbgAssert(CV_ELEM_SIZE1(traits::Depth<_Tp>::value) == elemSize1()); return ((_Tp*)(data + step.p[0] * i0))[i1]; } @@ -1076,7 +1076,7 @@ const _Tp& Mat::at(int i0, int i1) const CV_DbgAssert(data); CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels())); - CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1()); + CV_DbgAssert(CV_ELEM_SIZE1(traits::Depth<_Tp>::value) == elemSize1()); return ((const _Tp*)(data + step.p[0] * i0))[i1]; } @@ -1087,7 +1087,7 @@ _Tp& Mat::at(Point pt) CV_DbgAssert(data); CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]); CV_DbgAssert((unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels())); - CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1()); + CV_DbgAssert(CV_ELEM_SIZE1(traits::Depth<_Tp>::value) == elemSize1()); return ((_Tp*)(data + step.p[0] * pt.y))[pt.x]; } @@ -1098,7 +1098,7 @@ const _Tp& Mat::at(Point pt) const CV_DbgAssert(data); CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]); CV_DbgAssert((unsigned)(pt.x * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels())); - CV_DbgAssert(CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1()); + CV_DbgAssert(CV_ELEM_SIZE1(traits::Depth<_Tp>::value) == elemSize1()); return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x]; } @@ -1108,7 +1108,7 @@ _Tp& Mat::at(int i0) CV_DbgAssert(dims <= 2); CV_DbgAssert(data); CV_DbgAssert((unsigned)i0 < (unsigned)(size.p[0] * size.p[1])); - CV_DbgAssert(elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type)); + CV_DbgAssert(elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value)); if( isContinuous() || size.p[0] == 1 ) return ((_Tp*)data)[i0]; if( size.p[1] == 1 ) @@ -1123,7 +1123,7 @@ const _Tp& Mat::at(int i0) const CV_DbgAssert(dims <= 2); CV_DbgAssert(data); CV_DbgAssert((unsigned)i0 < (unsigned)(size.p[0] * size.p[1])); - CV_DbgAssert(elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type)); + CV_DbgAssert(elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value)); if( isContinuous() || size.p[0] == 1 ) return ((const _Tp*)data)[i0]; if( size.p[1] == 1 ) @@ -1135,42 +1135,42 @@ const _Tp& Mat::at(int i0) const template inline _Tp& Mat::at(int i0, int i1, int i2) { - CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value) ); return *(_Tp*)ptr(i0, i1, i2); } template inline const _Tp& Mat::at(int i0, int i1, int i2) const { - CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value) ); return *(const _Tp*)ptr(i0, i1, i2); } template inline _Tp& Mat::at(const int* idx) { - CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value) ); return *(_Tp*)ptr(idx); } template inline const _Tp& Mat::at(const int* idx) const { - CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value) ); return *(const _Tp*)ptr(idx); } template inline _Tp& Mat::at(const Vec& idx) { - CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value) ); return *(_Tp*)ptr(idx.val); } template inline const _Tp& Mat::at(const Vec& idx) const { - CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value) ); return *(const _Tp*)ptr(idx.val); } @@ -1241,10 +1241,10 @@ Mat::operator Vec<_Tp, n>() const CV_Assert( data && dims <= 2 && (rows == 1 || cols == 1) && rows + cols - 1 == n && channels() == 1 ); - if( isContinuous() && type() == DataType<_Tp>::type ) + if( isContinuous() && type() == traits::Type<_Tp>::value ) return Vec<_Tp, n>((_Tp*)data); Vec<_Tp, n> v; - Mat tmp(rows, cols, DataType<_Tp>::type, v.val); + Mat tmp(rows, cols, traits::Type<_Tp>::value, v.val); convertTo(tmp, tmp.type()); return v; } @@ -1254,10 +1254,10 @@ Mat::operator Matx<_Tp, m, n>() const { CV_Assert( data && dims <= 2 && rows == m && cols == n && channels() == 1 ); - if( isContinuous() && type() == DataType<_Tp>::type ) + if( isContinuous() && type() == traits::Type<_Tp>::value ) return Matx<_Tp, m, n>((_Tp*)data); Matx<_Tp, m, n> mtx; - Mat tmp(rows, cols, DataType<_Tp>::type, mtx.val); + Mat tmp(rows, cols, traits::Type<_Tp>::value, mtx.val); convertTo(tmp, tmp.type()); return mtx; } @@ -1267,10 +1267,10 @@ void Mat::push_back(const _Tp& elem) { if( !data ) { - *this = Mat(1, 1, DataType<_Tp>::type, (void*)&elem).clone(); + *this = Mat(1, 1, traits::Type<_Tp>::value, (void*)&elem).clone(); return; } - CV_Assert(DataType<_Tp>::type == type() && cols == 1 + CV_Assert(traits::Type<_Tp>::value == type() && cols == 1 /* && dims == 2 (cols == 1 implies dims == 2) */); const uchar* tmp = dataend + step[0]; if( !isSubmatrix() && isContinuous() && tmp <= datalimit ) @@ -1294,6 +1294,13 @@ void Mat::push_back(const MatExpr& expr) push_back(static_cast(expr)); } + +template inline +void Mat::push_back(const std::vector<_Tp>& v) +{ + push_back(Mat(v)); +} + #ifdef CV_CXX_MOVE_SEMANTICS inline @@ -1462,47 +1469,47 @@ template inline Mat_<_Tp>::Mat_() : Mat() { - flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; + flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value; } template inline Mat_<_Tp>::Mat_(int _rows, int _cols) - : Mat(_rows, _cols, DataType<_Tp>::type) + : Mat(_rows, _cols, traits::Type<_Tp>::value) { } template inline Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value) - : Mat(_rows, _cols, DataType<_Tp>::type) + : Mat(_rows, _cols, traits::Type<_Tp>::value) { *this = value; } template inline Mat_<_Tp>::Mat_(Size _sz) - : Mat(_sz.height, _sz.width, DataType<_Tp>::type) + : Mat(_sz.height, _sz.width, traits::Type<_Tp>::value) {} template inline Mat_<_Tp>::Mat_(Size _sz, const _Tp& value) - : Mat(_sz.height, _sz.width, DataType<_Tp>::type) + : Mat(_sz.height, _sz.width, traits::Type<_Tp>::value) { *this = value; } template inline Mat_<_Tp>::Mat_(int _dims, const int* _sz) - : Mat(_dims, _sz, DataType<_Tp>::type) + : Mat(_dims, _sz, traits::Type<_Tp>::value) {} template inline Mat_<_Tp>::Mat_(int _dims, const int* _sz, const _Tp& _s) - : Mat(_dims, _sz, DataType<_Tp>::type, Scalar(_s)) + : Mat(_dims, _sz, traits::Type<_Tp>::value, Scalar(_s)) {} template inline Mat_<_Tp>::Mat_(int _dims, const int* _sz, _Tp* _data, const size_t* _steps) - : Mat(_dims, _sz, DataType<_Tp>::type, _data, _steps) + : Mat(_dims, _sz, traits::Type<_Tp>::value, _data, _steps) {} template inline @@ -1519,7 +1526,7 @@ template inline Mat_<_Tp>::Mat_(const Mat& m) : Mat() { - flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; + flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value; *this = m; } @@ -1530,7 +1537,7 @@ Mat_<_Tp>::Mat_(const Mat_& m) template inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t steps) - : Mat(_rows, _cols, DataType<_Tp>::type, _data, steps) + : Mat(_rows, _cols, traits::Type<_Tp>::value, _data, steps) {} template inline @@ -1545,7 +1552,7 @@ Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi) template template inline Mat_<_Tp>::Mat_(const Vec::channel_type, n>& vec, bool copyData) - : Mat(n / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&vec) + : Mat(n / DataType<_Tp>::channels, 1, traits::Type<_Tp>::value, (void*)&vec) { CV_Assert(n%DataType<_Tp>::channels == 0); if( copyData ) @@ -1554,7 +1561,7 @@ Mat_<_Tp>::Mat_(const Vec::channel_type, n>& vec, bool co template template inline Mat_<_Tp>::Mat_(const Matx::channel_type, m, n>& M, bool copyData) - : Mat(m, n / DataType<_Tp>::channels, DataType<_Tp>::type, (void*)&M) + : Mat(m, n / DataType<_Tp>::channels, traits::Type<_Tp>::value, (void*)&M) { CV_Assert(n % DataType<_Tp>::channels == 0); if( copyData ) @@ -1563,7 +1570,7 @@ Mat_<_Tp>::Mat_(const Matx::channel_type, m, n>& M, bool template inline Mat_<_Tp>::Mat_(const Point_::channel_type>& pt, bool copyData) - : Mat(2 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt) + : Mat(2 / DataType<_Tp>::channels, 1, traits::Type<_Tp>::value, (void*)&pt) { CV_Assert(2 % DataType<_Tp>::channels == 0); if( copyData ) @@ -1572,7 +1579,7 @@ Mat_<_Tp>::Mat_(const Point_::channel_type>& pt, bool cop template inline Mat_<_Tp>::Mat_(const Point3_::channel_type>& pt, bool copyData) - : Mat(3 / DataType<_Tp>::channels, 1, DataType<_Tp>::type, (void*)&pt) + : Mat(3 / DataType<_Tp>::channels, 1, traits::Type<_Tp>::value, (void*)&pt) { CV_Assert(3 % DataType<_Tp>::channels == 0); if( copyData ) @@ -1606,12 +1613,12 @@ Mat_<_Tp>::Mat_(const std::array<_Tp, _Nm>& arr, bool copyData) template inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m) { - if( DataType<_Tp>::type == m.type() ) + if( traits::Type<_Tp>::value == m.type() ) { Mat::operator = (m); return *this; } - if( DataType<_Tp>::depth == m.depth() ) + if( traits::Depth<_Tp>::value == m.depth() ) { return (*this = m.reshape(DataType<_Tp>::channels, m.dims, 0)); } @@ -1638,19 +1645,19 @@ Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s) template inline void Mat_<_Tp>::create(int _rows, int _cols) { - Mat::create(_rows, _cols, DataType<_Tp>::type); + Mat::create(_rows, _cols, traits::Type<_Tp>::value); } template inline void Mat_<_Tp>::create(Size _sz) { - Mat::create(_sz, DataType<_Tp>::type); + Mat::create(_sz, traits::Type<_Tp>::value); } template inline void Mat_<_Tp>::create(int _dims, const int* _sz) { - Mat::create(_dims, _sz, DataType<_Tp>::type); + Mat::create(_dims, _sz, traits::Type<_Tp>::value); } template inline @@ -1715,15 +1722,15 @@ size_t Mat_<_Tp>::elemSize1() const template inline int Mat_<_Tp>::type() const { - CV_DbgAssert( Mat::type() == DataType<_Tp>::type ); - return DataType<_Tp>::type; + CV_DbgAssert( Mat::type() == traits::Type<_Tp>::value ); + return traits::Type<_Tp>::value; } template inline int Mat_<_Tp>::depth() const { - CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth ); - return DataType<_Tp>::depth; + CV_DbgAssert( Mat::depth() == traits::Depth<_Tp>::value ); + return traits::Depth<_Tp>::value; } template inline @@ -1796,7 +1803,7 @@ _Tp& Mat_<_Tp>::operator ()(int i0, int i1) CV_DbgAssert(data); CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]); - CV_DbgAssert(type() == DataType<_Tp>::type); + CV_DbgAssert(type() == traits::Type<_Tp>::value); return ((_Tp*)(data + step.p[0] * i0))[i1]; } @@ -1807,7 +1814,7 @@ const _Tp& Mat_<_Tp>::operator ()(int i0, int i1) const CV_DbgAssert(data); CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]); CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]); - CV_DbgAssert(type() == DataType<_Tp>::type); + CV_DbgAssert(type() == traits::Type<_Tp>::value); return ((const _Tp*)(data + step.p[0] * i0))[i1]; } @@ -1818,7 +1825,7 @@ _Tp& Mat_<_Tp>::operator ()(Point pt) CV_DbgAssert(data); CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]); CV_DbgAssert((unsigned)pt.x < (unsigned)size.p[1]); - CV_DbgAssert(type() == DataType<_Tp>::type); + CV_DbgAssert(type() == traits::Type<_Tp>::value); return ((_Tp*)(data + step.p[0] * pt.y))[pt.x]; } @@ -1829,7 +1836,7 @@ const _Tp& Mat_<_Tp>::operator ()(Point pt) const CV_DbgAssert(data); CV_DbgAssert((unsigned)pt.y < (unsigned)size.p[0]); CV_DbgAssert((unsigned)pt.x < (unsigned)size.p[1]); - CV_DbgAssert(type() == DataType<_Tp>::type); + CV_DbgAssert(type() == traits::Type<_Tp>::value); return ((const _Tp*)(data + step.p[0] * pt.y))[pt.x]; } @@ -1980,19 +1987,19 @@ template inline Mat_<_Tp>::Mat_(Mat&& m) : Mat() { - flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; + flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value; *this = m; } template inline Mat_<_Tp>& Mat_<_Tp>::operator = (Mat&& m) { - if( DataType<_Tp>::type == m.type() ) + if( traits::Type<_Tp>::value == m.type() ) { Mat::operator = ((Mat&&)m); return *this; } - if( DataType<_Tp>::depth == m.depth() ) + if( traits::Depth<_Tp>::value == m.depth() ) { Mat::operator = ((Mat&&)m.reshape(DataType<_Tp>::channels, m.dims, 0)); return *this; @@ -2006,7 +2013,7 @@ template inline Mat_<_Tp>::Mat_(MatExpr&& e) : Mat() { - flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; + flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value; *this = Mat(e); } @@ -2343,21 +2350,21 @@ SparseMatConstIterator_<_Tp> SparseMat::end() const template inline SparseMat_<_Tp>::SparseMat_() { - flags = MAGIC_VAL | DataType<_Tp>::type; + flags = MAGIC_VAL | traits::Type<_Tp>::value; } template inline SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes) - : SparseMat(_dims, _sizes, DataType<_Tp>::type) + : SparseMat(_dims, _sizes, traits::Type<_Tp>::value) {} template inline SparseMat_<_Tp>::SparseMat_(const SparseMat& m) { - if( m.type() == DataType<_Tp>::type ) + if( m.type() == traits::Type<_Tp>::value ) *this = (const SparseMat_<_Tp>&)m; else - m.convertTo(*this, DataType<_Tp>::type); + m.convertTo(*this, traits::Type<_Tp>::value); } template inline @@ -2392,9 +2399,9 @@ SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m) template inline SparseMat_<_Tp>& SparseMat_<_Tp>::operator = (const SparseMat& m) { - if( m.type() == DataType<_Tp>::type ) + if( m.type() == traits::Type<_Tp>::value ) return (*this = (const SparseMat_<_Tp>&)m); - m.convertTo(*this, DataType<_Tp>::type); + m.convertTo(*this, traits::Type<_Tp>::value); return *this; } @@ -2415,19 +2422,19 @@ SparseMat_<_Tp> SparseMat_<_Tp>::clone() const template inline void SparseMat_<_Tp>::create(int _dims, const int* _sizes) { - SparseMat::create(_dims, _sizes, DataType<_Tp>::type); + SparseMat::create(_dims, _sizes, traits::Type<_Tp>::value); } template inline int SparseMat_<_Tp>::type() const { - return DataType<_Tp>::type; + return traits::Type<_Tp>::value; } template inline int SparseMat_<_Tp>::depth() const { - return DataType<_Tp>::depth; + return traits::Depth<_Tp>::value; } template inline @@ -3128,7 +3135,7 @@ template inline SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat* _m) : SparseMatConstIterator(_m) { - CV_Assert( _m->type() == DataType<_Tp>::type ); + CV_Assert( _m->type() == traits::Type<_Tp>::value ); } template inline @@ -3264,50 +3271,50 @@ Mat& Mat::operator = (const MatExpr& e) template inline Mat_<_Tp>::Mat_(const MatExpr& e) { - e.op->assign(e, *this, DataType<_Tp>::type); + e.op->assign(e, *this, traits::Type<_Tp>::value); } template inline Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e) { - e.op->assign(e, *this, DataType<_Tp>::type); + e.op->assign(e, *this, traits::Type<_Tp>::value); return *this; } template inline MatExpr Mat_<_Tp>::zeros(int rows, int cols) { - return Mat::zeros(rows, cols, DataType<_Tp>::type); + return Mat::zeros(rows, cols, traits::Type<_Tp>::value); } template inline MatExpr Mat_<_Tp>::zeros(Size sz) { - return Mat::zeros(sz, DataType<_Tp>::type); + return Mat::zeros(sz, traits::Type<_Tp>::value); } template inline MatExpr Mat_<_Tp>::ones(int rows, int cols) { - return Mat::ones(rows, cols, DataType<_Tp>::type); + return Mat::ones(rows, cols, traits::Type<_Tp>::value); } template inline MatExpr Mat_<_Tp>::ones(Size sz) { - return Mat::ones(sz, DataType<_Tp>::type); + return Mat::ones(sz, traits::Type<_Tp>::value); } template inline MatExpr Mat_<_Tp>::eye(int rows, int cols) { - return Mat::eye(rows, cols, DataType<_Tp>::type); + return Mat::eye(rows, cols, traits::Type<_Tp>::value); } template inline MatExpr Mat_<_Tp>::eye(Size sz) { - return Mat::eye(sz, DataType<_Tp>::type); + return Mat::eye(sz, traits::Type<_Tp>::value); } inline @@ -3333,7 +3340,7 @@ template inline MatExpr::operator Mat_<_Tp>() const { Mat_<_Tp> m; - op->assign(*this, m, DataType<_Tp>::type); + op->assign(*this, m, traits::Type<_Tp>::value); return m; } @@ -3566,7 +3573,7 @@ UMat::UMat(const UMat& m) template inline UMat::UMat(const std::vector<_Tp>& vec, bool copyData) -: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()), +: flags(MAGIC_VAL | traits::Type<_Tp>::value | CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()), cols(1), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows) { if(vec.empty()) @@ -3577,7 +3584,7 @@ cols(1), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows) CV_Error(Error::StsNotImplemented, ""); } else - Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this); + Mat((int)vec.size(), 1, traits::Type<_Tp>::value, (uchar*)&vec[0]).copyTo(*this); } inline diff --git a/modules/core/include/opencv2/core/matx.hpp b/modules/core/include/opencv2/core/matx.hpp index 6469962c63..1d1ab4a43c 100644 --- a/modules/core/include/opencv2/core/matx.hpp +++ b/modules/core/include/opencv2/core/matx.hpp @@ -100,11 +100,14 @@ In case if C++11 features are avaliable, std::initializer_list can be also used template class Matx { public: - enum { depth = DataType<_Tp>::depth, + enum { rows = m, cols = n, channels = rows*cols, +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + depth = traits::Type<_Tp>::value, type = CV_MAKETYPE(depth, channels), +#endif shortdim = (m < n ? m : n) }; @@ -259,13 +262,23 @@ public: typedef value_type vec_type; enum { generic_type = 0, - depth = DataType::depth, channels = m * n, - fmt = DataType::fmt + ((channels - 1) << 8), - type = CV_MAKETYPE(depth, channels) + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif }; }; +namespace traits { +template +struct Depth< Matx<_Tp, m, n> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Matx<_Tp, m, n> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, n*m) }; }; +} // namespace + + /** @brief Comma-separated Matrix Initializer */ template class MatxCommaInitializer @@ -323,9 +336,13 @@ template class Vec : public Matx<_Tp, cn, 1> { public: typedef _Tp value_type; - enum { depth = Matx<_Tp, cn, 1>::depth, + enum { channels = cn, - type = CV_MAKETYPE(depth, channels) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + depth = Matx<_Tp, cn, 1>::depth, + type = CV_MAKETYPE(depth, channels), +#endif + _dummy_enum_finalizer = 0 }; //! default constructor @@ -422,13 +439,24 @@ public: typedef value_type vec_type; enum { generic_type = 0, - depth = DataType::depth, channels = cn, fmt = DataType::fmt + ((channels - 1) << 8), - type = CV_MAKETYPE(depth, channels) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + depth = DataType::depth, + type = CV_MAKETYPE(depth, channels), +#endif + _dummy_enum_finalizer = 0 }; }; +namespace traits { +template +struct Depth< Vec<_Tp, cn> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Vec<_Tp, cn> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, cn) }; }; +} // namespace + + /** @brief Comma-separated Vec Initializer */ template class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1> diff --git a/modules/core/include/opencv2/core/persistence.hpp b/modules/core/include/opencv2/core/persistence.hpp index 65d6a69b1f..e0a6efa465 100644 --- a/modules/core/include/opencv2/core/persistence.hpp +++ b/modules/core/include/opencv2/core/persistence.hpp @@ -815,7 +815,7 @@ namespace internal VecWriterProxy( FileStorage* _fs ) : fs(_fs) {} void operator()(const std::vector<_Tp>& vec) const { - int _fmt = DataType<_Tp>::fmt; + int _fmt = traits::SafeFmt<_Tp>::fmt; char fmt[] = { (char)((_fmt >> 8) + '1'), (char)_fmt, '\0' }; fs->writeRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, vec.size() * sizeof(_Tp)); } @@ -846,7 +846,7 @@ namespace internal { size_t remaining = it->remaining; size_t cn = DataType<_Tp>::channels; - int _fmt = DataType<_Tp>::fmt; + int _fmt = traits::SafeFmt<_Tp>::fmt; char fmt[] = { (char)((_fmt >> 8)+'1'), (char)_fmt, '\0' }; size_t remaining1 = remaining / cn; count = count < remaining1 ? count : remaining1; @@ -999,7 +999,7 @@ void write( FileStorage& fs, const std::vector& vec ) template static inline void write( FileStorage& fs, const std::vector<_Tp>& vec ) { - cv::internal::VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs); + cv::internal::VecWriterProxy<_Tp, traits::SafeFmt<_Tp>::fmt != 0> w(&fs); w(vec); } @@ -1076,7 +1076,7 @@ void write(FileStorage& fs, const String& name, const DMatch& r ) template static inline void write( FileStorage& fs, const String& name, const std::vector<_Tp>& vec ) { - cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+(DataType<_Tp>::fmt != 0 ? FileNode::FLOW : 0)); + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+(traits::SafeFmt<_Tp>::fmt != 0 ? FileNode::FLOW : 0)); write(fs, vec); } @@ -1086,7 +1086,7 @@ void write( FileStorage& fs, const String& name, const std::vector< std::vector< cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ); for(size_t i = 0; i < vec.size(); i++) { - cv::internal::WriteStructContext ws_(fs, name, FileNode::SEQ+(DataType<_Tp>::fmt != 0 ? FileNode::FLOW : 0)); + cv::internal::WriteStructContext ws_(fs, name, FileNode::SEQ+(traits::SafeFmt<_Tp>::fmt != 0 ? FileNode::FLOW : 0)); write(fs, vec[i]); } } @@ -1139,7 +1139,7 @@ void read(const FileNode& node, short& value, short default_value) template static inline void read( FileNodeIterator& it, std::vector<_Tp>& vec, size_t maxCount = (size_t)INT_MAX ) { - cv::internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it); + cv::internal::VecReaderProxy<_Tp, traits::SafeFmt<_Tp>::fmt != 0> r(&it); r(vec, maxCount); } @@ -1228,7 +1228,7 @@ FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value) template static inline FileNodeIterator& operator >> (FileNodeIterator& it, std::vector<_Tp>& vec) { - cv::internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it); + cv::internal::VecReaderProxy<_Tp, traits::SafeFmt<_Tp>::fmt != 0> r(&it); r(vec, (size_t)INT_MAX); return it; } diff --git a/modules/core/include/opencv2/core/traits.hpp b/modules/core/include/opencv2/core/traits.hpp index f83b05f06d..6cb10f44cf 100644 --- a/modules/core/include/opencv2/core/traits.hpp +++ b/modules/core/include/opencv2/core/traits.hpp @@ -49,11 +49,15 @@ namespace cv { +//#define OPENCV_TRAITS_ENABLE_DEPRECATED + //! @addtogroup core_basic //! @{ /** @brief Template "trait" class for OpenCV primitive data types. +@note Deprecated. This is replaced by "single purpose" traits: traits::Type and traits::Depth + A primitive OpenCV data type is one of unsigned char, bool, signed char, unsigned short, signed short, int, float, double, or a tuple of values of one of these types, where all the values in the tuple have the same type. Any primitive type from the list can be defined by an identifier in the @@ -102,10 +106,13 @@ So, such traits are used to tell OpenCV which data type you are working with, ev not native to OpenCV. For example, the matrix B initialization above is compiled because OpenCV defines the proper specialized template class DataType\ \> . This mechanism is also useful (and used in OpenCV this way) for generic algorithms implementations. + +@note Default values were dropped to stop confusing developers about using of unsupported types (see #7599) */ template class DataType { public: +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED typedef _Tp value_type; typedef value_type work_type; typedef value_type channel_type; @@ -116,6 +123,7 @@ public: fmt = 0, type = CV_MAKETYPE(depth, channels) }; +#endif }; template<> class DataType @@ -270,11 +278,14 @@ public: }; +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED template class TypeDepth { +#ifdef OPENCV_TRAITS_ENABLE_LEGACY_DEFAULTS enum { depth = CV_USRTYPE1 }; typedef void value_type; +#endif }; template<> class TypeDepth @@ -319,8 +330,68 @@ template<> class TypeDepth typedef double value_type; }; +#endif + //! @} +namespace traits { + +namespace internal { +#define CV_CREATE_MEMBER_CHECK(X) \ +template class CheckMember_##X { \ + struct Fallback { int X; }; \ + struct Derived : T, Fallback { }; \ + template struct Check; \ + typedef char CV_NO[1]; \ + typedef char CV_YES[2]; \ + template static CV_NO & func(Check *); \ + template static CV_YES & func(...); \ +public: \ + typedef CheckMember_##X type; \ + enum { value = sizeof(func(0)) == sizeof(CV_YES) }; \ +}; + +CV_CREATE_MEMBER_CHECK(fmt) +CV_CREATE_MEMBER_CHECK(type) + +} // namespace internal + + +template +struct Depth +{ enum { value = DataType::depth }; }; + +template +struct Type +{ enum { value = DataType::type }; }; + +/** Similar to traits::Type but has value = -1 in case of unknown type (instead of compiler error) */ +template >::value > +struct SafeType {}; + +template +struct SafeType +{ enum { value = -1 }; }; + +template +struct SafeType +{ enum { value = Type::value }; }; + + +template >::value > +struct SafeFmt {}; + +template +struct SafeFmt +{ enum { fmt = 0 }; }; + +template +struct SafeFmt +{ enum { fmt = DataType::fmt }; }; + + +} // namespace + } // cv #endif // OPENCV_CORE_TRAITS_HPP diff --git a/modules/core/test/test_operations.cpp b/modules/core/test/test_operations.cpp index aea5d5daee..c72cc5eb6a 100644 --- a/modules/core/test/test_operations.cpp +++ b/modules/core/test/test_operations.cpp @@ -105,7 +105,7 @@ CV_OperationsTest::~CV_OperationsTest() {} template void CV_OperationsTest::TestType(Size sz, _Tp value) { cv::Mat_<_Tp> m(sz); - CV_Assert(m.cols == sz.width && m.rows == sz.height && m.depth() == DataType<_Tp>::depth && + CV_Assert(m.cols == sz.width && m.rows == sz.height && m.depth() == cv::traits::Depth<_Tp>::value && m.channels() == DataType<_Tp>::channels && m.elemSize() == sizeof(_Tp) && m.step == m.elemSize()*m.cols); for( int y = 0; y < sz.height; y++ ) diff --git a/modules/python/src2/cv2.cpp b/modules/python/src2/cv2.cpp index be8965c6e0..b24ba5110a 100644 --- a/modules/python/src2/cv2.cpp +++ b/modules/python/src2/cv2.cpp @@ -1076,7 +1076,7 @@ template struct pyopencvVecConverter int i, j, n = (int)PySequence_Fast_GET_SIZE(seq); value.resize(n); - int type = DataType<_Tp>::type; + int type = traits::Type<_Tp>::value; int depth = CV_MAT_DEPTH(type), channels = CV_MAT_CN(type); PyObject** items = PySequence_Fast_ITEMS(seq); @@ -1159,7 +1159,9 @@ template struct pyopencvVecConverter { if(value.empty()) return PyTuple_New(0); - Mat src((int)value.size(), DataType<_Tp>::channels, DataType<_Tp>::depth, (uchar*)&value[0]); + int type = traits::Type<_Tp>::value; + int depth = CV_MAT_DEPTH(type), channels = CV_MAT_CN(type); + Mat src((int)value.size(), channels, depth, (uchar*)&value[0]); return pyopencv_from(src); } }; From 7e12c879c20f8487f9e591f3f9ed00078d4ecfe7 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 24 Aug 2017 18:39:41 +0300 Subject: [PATCH 2/6] core: extend traits::Type / traits::Depth for compatible types DMatch and Keypoint are not compatible types (mixed float/int fields) --- .../calib3d/test/test_cameracalibration.cpp | 6 +- modules/core/include/opencv2/core/affine.hpp | 25 +++- modules/core/include/opencv2/core/eigen.hpp | 36 ++--- modules/core/include/opencv2/core/mat.hpp | 4 +- modules/core/include/opencv2/core/mat.inl.hpp | 2 +- modules/core/include/opencv2/core/types.hpp | 137 ++++++++++++++---- 6 files changed, 146 insertions(+), 64 deletions(-) diff --git a/modules/calib3d/test/test_cameracalibration.cpp b/modules/calib3d/test/test_cameracalibration.cpp index d738341eeb..85c37516f9 100644 --- a/modules/calib3d/test/test_cameracalibration.cpp +++ b/modules/calib3d/test/test_cameracalibration.cpp @@ -1911,9 +1911,9 @@ double CV_StereoCalibrationTest_C::calibrateStereoCamera( const vector::type ), - imgPt( 1, total, DataType::type ), - imgPt2( 1, total, DataType::type ); + objPt( 1, total, traits::Type::value ), + imgPt( 1, total, traits::Type::value ), + imgPt2( 1, total, traits::Type::value ); Point2f* imgPtData2 = imgPt2.ptr(); Point3f* objPtData = objPt.ptr(); diff --git a/modules/core/include/opencv2/core/affine.hpp b/modules/core/include/opencv2/core/affine.hpp index 41de5c6b57..443097a52c 100644 --- a/modules/core/include/opencv2/core/affine.hpp +++ b/modules/core/include/opencv2/core/affine.hpp @@ -153,15 +153,24 @@ namespace cv typedef _Tp channel_type; enum { generic_type = 0, - depth = DataType::depth, channels = 16, - fmt = DataType::fmt + ((channels - 1) << 8), - type = CV_MAKETYPE(depth, channels) + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif }; typedef Vec vec_type; }; + namespace traits { + template + struct Depth< Affine3<_Tp> > { enum { value = Depth<_Tp>::value }; }; + template + struct Type< Affine3<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 16) }; }; + } // namespace + //! @} core } @@ -202,7 +211,7 @@ cv::Affine3::Affine3(const Vec3& _rvec, const Vec3& t) template inline cv::Affine3::Affine3(const cv::Mat& data, const Vec3& t) { - CV_Assert(data.type() == cv::DataType::type); + CV_Assert(data.type() == cv::traits::Type::value); if (data.cols == 4 && data.rows == 4) { @@ -271,7 +280,7 @@ void cv::Affine3::rotation(const Vec3& _rvec) template inline void cv::Affine3::rotation(const cv::Mat& data) { - CV_Assert(data.type() == cv::DataType::type); + CV_Assert(data.type() == cv::traits::Type::value); if (data.cols == 3 && data.rows == 3) { @@ -485,21 +494,21 @@ cv::Vec3d cv::operator*(const cv::Affine3d& affine, const cv::Vec3d& v) template inline cv::Affine3::Affine3(const Eigen::Transform& affine) { - cv::Mat(4, 4, cv::DataType::type, affine.matrix().data()).copyTo(matrix); + cv::Mat(4, 4, cv::traits::Type::value, affine.matrix().data()).copyTo(matrix); } template inline cv::Affine3::Affine3(const Eigen::Transform& affine) { Eigen::Transform a = affine; - cv::Mat(4, 4, cv::DataType::type, a.matrix().data()).copyTo(matrix); + cv::Mat(4, 4, cv::traits::Type::value, a.matrix().data()).copyTo(matrix); } template inline cv::Affine3::operator Eigen::Transform() const { Eigen::Transform r; - cv::Mat hdr(4, 4, cv::DataType::type, r.matrix().data()); + cv::Mat hdr(4, 4, cv::traits::Type::value, r.matrix().data()); cv::Mat(matrix, false).copyTo(hdr); return r; } diff --git a/modules/core/include/opencv2/core/eigen.hpp b/modules/core/include/opencv2/core/eigen.hpp index c2f1ee6a83..35a4c81145 100644 --- a/modules/core/include/opencv2/core/eigen.hpp +++ b/modules/core/include/opencv2/core/eigen.hpp @@ -64,13 +64,13 @@ void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCo { if( !(src.Flags & Eigen::RowMajorBit) ) { - Mat _src(src.cols(), src.rows(), DataType<_Tp>::type, + Mat _src(src.cols(), src.rows(), traits::Type<_Tp>::value, (void*)src.data(), src.stride()*sizeof(_Tp)); transpose(_src, dst); } else { - Mat _src(src.rows(), src.cols(), DataType<_Tp>::type, + Mat _src(src.rows(), src.cols(), traits::Type<_Tp>::value, (void*)src.data(), src.stride()*sizeof(_Tp)); _src.copyTo(dst); } @@ -98,7 +98,7 @@ void cv2eigen( const Mat& src, CV_DbgAssert(src.rows == _rows && src.cols == _cols); if( !(dst.Flags & Eigen::RowMajorBit) ) { - const Mat _dst(src.cols, src.rows, DataType<_Tp>::type, + const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); if( src.type() == _dst.type() ) transpose(src, _dst); @@ -112,7 +112,7 @@ void cv2eigen( const Mat& src, } else { - const Mat _dst(src.rows, src.cols, DataType<_Tp>::type, + const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); src.convertTo(_dst, _dst.type()); } @@ -125,13 +125,13 @@ void cv2eigen( const Matx<_Tp, _rows, _cols>& src, { if( !(dst.Flags & Eigen::RowMajorBit) ) { - const Mat _dst(_cols, _rows, DataType<_Tp>::type, + const Mat _dst(_cols, _rows, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); transpose(src, _dst); } else { - const Mat _dst(_rows, _cols, DataType<_Tp>::type, + const Mat _dst(_rows, _cols, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); Mat(src).copyTo(_dst); } @@ -144,7 +144,7 @@ void cv2eigen( const Mat& src, dst.resize(src.rows, src.cols); if( !(dst.Flags & Eigen::RowMajorBit) ) { - const Mat _dst(src.cols, src.rows, DataType<_Tp>::type, + const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); if( src.type() == _dst.type() ) transpose(src, _dst); @@ -158,7 +158,7 @@ void cv2eigen( const Mat& src, } else { - const Mat _dst(src.rows, src.cols, DataType<_Tp>::type, + const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); src.convertTo(_dst, _dst.type()); } @@ -172,13 +172,13 @@ void cv2eigen( const Matx<_Tp, _rows, _cols>& src, dst.resize(_rows, _cols); if( !(dst.Flags & Eigen::RowMajorBit) ) { - const Mat _dst(_cols, _rows, DataType<_Tp>::type, + const Mat _dst(_cols, _rows, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); transpose(src, _dst); } else { - const Mat _dst(_rows, _cols, DataType<_Tp>::type, + const Mat _dst(_rows, _cols, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); Mat(src).copyTo(_dst); } @@ -193,7 +193,7 @@ void cv2eigen( const Mat& src, if( !(dst.Flags & Eigen::RowMajorBit) ) { - const Mat _dst(src.cols, src.rows, DataType<_Tp>::type, + const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); if( src.type() == _dst.type() ) transpose(src, _dst); @@ -202,7 +202,7 @@ void cv2eigen( const Mat& src, } else { - const Mat _dst(src.rows, src.cols, DataType<_Tp>::type, + const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); src.convertTo(_dst, _dst.type()); } @@ -217,13 +217,13 @@ void cv2eigen( const Matx<_Tp, _rows, 1>& src, if( !(dst.Flags & Eigen::RowMajorBit) ) { - const Mat _dst(1, _rows, DataType<_Tp>::type, + const Mat _dst(1, _rows, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); transpose(src, _dst); } else { - const Mat _dst(_rows, 1, DataType<_Tp>::type, + const Mat _dst(_rows, 1, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); src.copyTo(_dst); } @@ -238,7 +238,7 @@ void cv2eigen( const Mat& src, dst.resize(src.cols); if( !(dst.Flags & Eigen::RowMajorBit) ) { - const Mat _dst(src.cols, src.rows, DataType<_Tp>::type, + const Mat _dst(src.cols, src.rows, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); if( src.type() == _dst.type() ) transpose(src, _dst); @@ -247,7 +247,7 @@ void cv2eigen( const Mat& src, } else { - const Mat _dst(src.rows, src.cols, DataType<_Tp>::type, + const Mat _dst(src.rows, src.cols, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); src.convertTo(_dst, _dst.type()); } @@ -261,13 +261,13 @@ void cv2eigen( const Matx<_Tp, 1, _cols>& src, dst.resize(_cols); if( !(dst.Flags & Eigen::RowMajorBit) ) { - const Mat _dst(_cols, 1, DataType<_Tp>::type, + const Mat _dst(_cols, 1, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); transpose(src, _dst); } else { - const Mat _dst(1, _cols, DataType<_Tp>::type, + const Mat _dst(1, _cols, traits::Type<_Tp>::value, dst.data(), (size_t)(dst.stride()*sizeof(_Tp))); Mat(src).copyTo(_dst); } diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index 8e35fd4dc4..31d182c713 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -1666,7 +1666,7 @@ public: inv_scale = 1.f/alpha_scale; CV_Assert( src1.type() == src2.type() && - src1.type() == CV_MAKETYPE(DataType::depth, 4) && + src1.type() == CV_MAKETYPE(traits::Depth::value, 4) && src1.size() == src2.size()); Size size = src1.size(); dst.create(size, src1.type()); @@ -1946,7 +1946,7 @@ public: inv_scale = 1.f/alpha_scale; CV_Assert( src1.type() == src2.type() && - src1.type() == DataType::type && + src1.type() == traits::Type::value && src1.size() == src2.size()); Size size = src1.size(); dst.create(size, src1.type()); diff --git a/modules/core/include/opencv2/core/mat.inl.hpp b/modules/core/include/opencv2/core/mat.inl.hpp index 934a8f07cb..3afdb0f247 100644 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@ -1665,7 +1665,7 @@ void Mat_<_Tp>::release() { Mat::release(); #ifdef _DEBUG - flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; + flags = (flags & ~CV_MAT_TYPE_MASK) | traits::Type<_Tp>::value; #endif } diff --git a/modules/core/include/opencv2/core/types.hpp b/modules/core/include/opencv2/core/types.hpp index a99346a0c5..f3a7b518bf 100644 --- a/modules/core/include/opencv2/core/types.hpp +++ b/modules/core/include/opencv2/core/types.hpp @@ -98,14 +98,23 @@ public: typedef _Tp channel_type; enum { generic_type = 0, - depth = DataType::depth, channels = 2, - fmt = DataType::fmt + ((channels - 1) << 8), - type = CV_MAKETYPE(depth, channels) }; + fmt = DataType::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif + }; typedef Vec vec_type; }; +namespace traits { +template +struct Depth< Complex<_Tp> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Complex<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 2) }; }; +} // namespace //////////////////////////////// Point_ //////////////////////////////// @@ -190,15 +199,23 @@ public: typedef _Tp channel_type; enum { generic_type = 0, - depth = DataType::depth, channels = 2, - fmt = DataType::fmt + ((channels - 1) << 8), - type = CV_MAKETYPE(depth, channels) + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif }; typedef Vec vec_type; }; +namespace traits { +template +struct Depth< Point_<_Tp> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Point_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 2) }; }; +} // namespace //////////////////////////////// Point3_ //////////////////////////////// @@ -261,16 +278,23 @@ public: typedef _Tp channel_type; enum { generic_type = 0, - depth = DataType::depth, channels = 3, - fmt = DataType::fmt + ((channels - 1) << 8), - type = CV_MAKETYPE(depth, channels) + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif }; typedef Vec vec_type; }; - +namespace traits { +template +struct Depth< Point3_<_Tp> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Point3_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 3) }; }; +} // namespace //////////////////////////////// Size_ //////////////////////////////// @@ -324,16 +348,23 @@ public: typedef _Tp channel_type; enum { generic_type = 0, - depth = DataType::depth, channels = 2, - fmt = DataType::fmt + ((channels - 1) << 8), - type = CV_MAKETYPE(depth, channels) + fmt = DataType::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif }; typedef Vec vec_type; }; - +namespace traits { +template +struct Depth< Size_<_Tp> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Size_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 2) }; }; +} // namespace //////////////////////////////// Rect_ //////////////////////////////// @@ -427,16 +458,23 @@ public: typedef _Tp channel_type; enum { generic_type = 0, - depth = DataType::depth, channels = 4, - fmt = DataType::fmt + ((channels - 1) << 8), - type = CV_MAKETYPE(depth, channels) + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif }; typedef Vec vec_type; }; - +namespace traits { +template +struct Depth< Rect_<_Tp> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Rect_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 4) }; }; +} // namespace ///////////////////////////// RotatedRect ///////////////////////////// @@ -505,15 +543,23 @@ public: typedef float channel_type; enum { generic_type = 0, - depth = DataType::depth, channels = (int)sizeof(value_type)/sizeof(channel_type), // 5 - fmt = DataType::fmt + ((channels - 1) << 8), - type = CV_MAKETYPE(depth, channels) + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif }; typedef Vec vec_type; }; +namespace traits { +template<> +struct Depth< RotatedRect > { enum { value = Depth::value }; }; +template<> +struct Type< RotatedRect > { enum { value = CV_MAKETYPE(Depth::value, (int)sizeof(RotatedRect)/sizeof(float)) }; }; +} // namespace //////////////////////////////// Range ///////////////////////////////// @@ -561,15 +607,23 @@ public: typedef int channel_type; enum { generic_type = 0, - depth = DataType::depth, channels = 2, - fmt = DataType::fmt + ((channels - 1) << 8), - type = CV_MAKETYPE(depth, channels) + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif }; typedef Vec vec_type; }; +namespace traits { +template<> +struct Depth< Range > { enum { value = Depth::value }; }; +template<> +struct Type< Range > { enum { value = CV_MAKETYPE(Depth::value, 2) }; }; +} // namespace //////////////////////////////// Scalar_ /////////////////////////////// @@ -617,15 +671,23 @@ public: typedef _Tp channel_type; enum { generic_type = 0, - depth = DataType::depth, channels = 4, - fmt = DataType::fmt + ((channels - 1) << 8), - type = CV_MAKETYPE(depth, channels) + fmt = traits::SafeFmt::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif }; typedef Vec vec_type; }; +namespace traits { +template +struct Depth< Scalar_<_Tp> > { enum { value = Depth<_Tp>::value }; }; +template +struct Type< Scalar_<_Tp> > { enum { value = CV_MAKETYPE(Depth<_Tp>::value, 4) }; }; +} // namespace /////////////////////////////// KeyPoint //////////////////////////////// @@ -712,6 +774,7 @@ public: CV_PROP_RW int class_id; //!< object class (if the keypoints need to be clustered by an object they belong to) }; +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED template<> class DataType { public: @@ -728,7 +791,7 @@ public: typedef Vec vec_type; }; - +#endif //////////////////////////////// DMatch ///////////////////////////////// @@ -755,6 +818,7 @@ public: bool operator<(const DMatch &m) const; }; +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED template<> class DataType { public: @@ -771,7 +835,7 @@ public: typedef Vec vec_type; }; - +#endif ///////////////////////////// TermCriteria ////////////////////////////// @@ -885,15 +949,24 @@ public: typedef double channel_type; enum { generic_type = 0, - depth = DataType::depth, channels = (int)(sizeof(value_type)/sizeof(channel_type)), // 24 - fmt = DataType::fmt + ((channels - 1) << 8), - type = CV_MAKETYPE(depth, channels) + fmt = DataType::fmt + ((channels - 1) << 8) +#ifdef OPENCV_TRAITS_ENABLE_DEPRECATED + ,depth = DataType::depth + ,type = CV_MAKETYPE(depth, channels) +#endif }; typedef Vec vec_type; }; +namespace traits { +template<> +struct Depth< Moments > { enum { value = Depth::value }; }; +template<> +struct Type< Moments > { enum { value = CV_MAKETYPE(Depth::value, (int)(sizeof(Moments)/sizeof(double))) }; }; +} // namespace + //! @} imgproc_shape //! @cond IGNORED From 01519313d7ed16780867a0d0e0f75494d81931cf Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 24 Aug 2017 19:43:45 +0300 Subject: [PATCH 3/6] dnn: invalid bindings --- modules/dnn/include/opencv2/dnn/dnn.hpp | 22 +++++++++---------- .../dnn/misc/java/src/cpp/dnn_converters.cpp | 12 ---------- .../dnn/misc/java/src/cpp/dnn_converters.hpp | 4 ---- .../java/generator/src/cpp/listconverters.cpp | 17 -------------- .../java/generator/src/cpp/listconverters.hpp | 5 ----- 5 files changed, 11 insertions(+), 49 deletions(-) diff --git a/modules/dnn/include/opencv2/dnn/dnn.hpp b/modules/dnn/include/opencv2/dnn/dnn.hpp index 01e0021ccb..da0a407262 100644 --- a/modules/dnn/include/opencv2/dnn/dnn.hpp +++ b/modules/dnn/include/opencv2/dnn/dnn.hpp @@ -345,7 +345,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN CV_WRAP Ptr getLayer(LayerId layerId); /** @brief Returns pointers to input layers of specific layer. */ - CV_WRAP std::vector > getLayerInputs(LayerId layerId); + std::vector > getLayerInputs(LayerId layerId); // FIXIT: CV_WRAP /** @brief Delete layer for the network (not implemented yet) */ CV_WRAP void deleteLayer(LayerId layer); @@ -502,16 +502,16 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN * @param outLayerShapes output parameter for output layers shapes; * order is the same as in layersIds */ - CV_WRAP void getLayerShapes(const MatShape& netInputShape, + void getLayerShapes(const MatShape& netInputShape, const int layerId, CV_OUT std::vector& inLayerShapes, - CV_OUT std::vector& outLayerShapes) const; + CV_OUT std::vector& outLayerShapes) const; // FIXIT: CV_WRAP /** @overload */ - CV_WRAP void getLayerShapes(const std::vector& netInputShapes, + void getLayerShapes(const std::vector& netInputShapes, const int layerId, CV_OUT std::vector& inLayerShapes, - CV_OUT std::vector& outLayerShapes) const; + CV_OUT std::vector& outLayerShapes) const; // FIXIT: CV_WRAP /** @brief Computes FLOP for whole loaded model with specified input shapes. * @param netInputShapes vector of shapes for all net inputs. @@ -544,8 +544,8 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN * @param weights output parameter to store resulting bytes for weights. * @param blobs output parameter to store resulting bytes for intermediate blobs. */ - CV_WRAP void getMemoryConsumption(const std::vector& netInputShapes, - CV_OUT size_t& weights, CV_OUT size_t& blobs) const; + void getMemoryConsumption(const std::vector& netInputShapes, + CV_OUT size_t& weights, CV_OUT size_t& blobs) const; // FIXIT: CV_WRAP /** @overload */ CV_WRAP void getMemoryConsumption(const MatShape& netInputShape, CV_OUT size_t& weights, CV_OUT size_t& blobs) const; @@ -565,15 +565,15 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN * @param weights output parameter to store resulting bytes for weights. * @param blobs output parameter to store resulting bytes for intermediate blobs. */ - CV_WRAP void getMemoryConsumption(const std::vector& netInputShapes, + void getMemoryConsumption(const std::vector& netInputShapes, CV_OUT std::vector& layerIds, CV_OUT std::vector& weights, - CV_OUT std::vector& blobs) const; + CV_OUT std::vector& blobs) const; // FIXIT: CV_WRAP /** @overload */ - CV_WRAP void getMemoryConsumption(const MatShape& netInputShape, + void getMemoryConsumption(const MatShape& netInputShape, CV_OUT std::vector& layerIds, CV_OUT std::vector& weights, - CV_OUT std::vector& blobs) const; + CV_OUT std::vector& blobs) const; // FIXIT: CV_WRAP /** @brief Enables or disables layer fusion in the network. * @param fusion true to enable the fusion, false to disable. The fusion is enabled by default. diff --git a/modules/dnn/misc/java/src/cpp/dnn_converters.cpp b/modules/dnn/misc/java/src/cpp/dnn_converters.cpp index 584bd5762b..97ff01cc15 100644 --- a/modules/dnn/misc/java/src/cpp/dnn_converters.cpp +++ b/modules/dnn/misc/java/src/cpp/dnn_converters.cpp @@ -19,18 +19,6 @@ void MatShape_to_Mat(MatShape& matshape, cv::Mat& mat) mat = cv::Mat(matshape, true); } -void Mat_to_vector_size_t(cv::Mat& mat, std::vector& v_size_t) -{ - v_size_t.clear(); - CHECK_MAT(mat.type()==CV_32SC1 && mat.cols==1); - v_size_t = (std::vector) mat; -} - -void vector_size_t_to_Mat(std::vector& v_size_t, cv::Mat& mat) -{ - mat = cv::Mat(v_size_t, true); -} - std::vector List_to_vector_MatShape(JNIEnv* env, jobject list) { static jclass juArrayList = ARRAYLIST(env); diff --git a/modules/dnn/misc/java/src/cpp/dnn_converters.hpp b/modules/dnn/misc/java/src/cpp/dnn_converters.hpp index f590161958..1e152780fb 100644 --- a/modules/dnn/misc/java/src/cpp/dnn_converters.hpp +++ b/modules/dnn/misc/java/src/cpp/dnn_converters.hpp @@ -22,10 +22,6 @@ void Mat_to_MatShape(cv::Mat& mat, MatShape& matshape); void MatShape_to_Mat(MatShape& matshape, cv::Mat& mat); -void Mat_to_vector_size_t(cv::Mat& mat, std::vector& v_size_t); - -void vector_size_t_to_Mat(std::vector& v_size_t, cv::Mat& mat); - std::vector List_to_vector_MatShape(JNIEnv* env, jobject list); jobject vector_Ptr_Layer_to_List(JNIEnv* env, std::vector >& vs); diff --git a/modules/java/generator/src/cpp/listconverters.cpp b/modules/java/generator/src/cpp/listconverters.cpp index 150bdae091..d1f45c65e6 100644 --- a/modules/java/generator/src/cpp/listconverters.cpp +++ b/modules/java/generator/src/cpp/listconverters.cpp @@ -57,20 +57,3 @@ void Copy_vector_String_to_List(JNIEnv* env, std::vector& vs, jobjec env->DeleteLocalRef(element); } } - -#if defined(HAVE_OPENCV_DNN) -void Copy_vector_MatShape_to_List(JNIEnv* env, std::vector& vs, jobject list) -{ - static jclass juArrayList = ARRAYLIST(env); - jmethodID m_clear = LIST_CLEAR(env, juArrayList); - jmethodID m_add = LIST_ADD(env, juArrayList); - - env->CallVoidMethod(list, m_clear); - for (std::vector::iterator it = vs.begin(); it != vs.end(); ++it) - { - jstring element = env->NewStringUTF(""); - env->CallBooleanMethod(list, m_add, element); - env->DeleteLocalRef(element); - } -} -#endif diff --git a/modules/java/generator/src/cpp/listconverters.hpp b/modules/java/generator/src/cpp/listconverters.hpp index 5de2c3a12e..4d63d9d86f 100644 --- a/modules/java/generator/src/cpp/listconverters.hpp +++ b/modules/java/generator/src/cpp/listconverters.hpp @@ -16,9 +16,4 @@ std::vector List_to_vector_String(JNIEnv* env, jobject list); void Copy_vector_String_to_List(JNIEnv* env, std::vector& vs, jobject list); -#if defined(HAVE_OPENCV_DNN) -#include "opencv2/dnn.hpp" -void Copy_vector_MatShape_to_List(JNIEnv* env, std::vector& vs, jobject list); -#endif - #endif /* LISTCONVERTERS_HPP */ From 86b55b392317f988793d914d80daf8c145913fcf Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 25 Aug 2017 15:37:09 +0300 Subject: [PATCH 4/6] core: eliminate CV_ELEM_SIZE() --- modules/core/include/opencv2/core/mat.inl.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/core/include/opencv2/core/mat.inl.hpp b/modules/core/include/opencv2/core/mat.inl.hpp index 3afdb0f247..84452881e9 100644 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@ -1108,7 +1108,7 @@ _Tp& Mat::at(int i0) CV_DbgAssert(dims <= 2); CV_DbgAssert(data); CV_DbgAssert((unsigned)i0 < (unsigned)(size.p[0] * size.p[1])); - CV_DbgAssert(elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value)); + CV_DbgAssert(elemSize() == sizeof(_Tp)); if( isContinuous() || size.p[0] == 1 ) return ((_Tp*)data)[i0]; if( size.p[1] == 1 ) @@ -1123,7 +1123,7 @@ const _Tp& Mat::at(int i0) const CV_DbgAssert(dims <= 2); CV_DbgAssert(data); CV_DbgAssert((unsigned)i0 < (unsigned)(size.p[0] * size.p[1])); - CV_DbgAssert(elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value)); + CV_DbgAssert(elemSize() == sizeof(_Tp)); if( isContinuous() || size.p[0] == 1 ) return ((const _Tp*)data)[i0]; if( size.p[1] == 1 ) @@ -1135,42 +1135,42 @@ const _Tp& Mat::at(int i0) const template inline _Tp& Mat::at(int i0, int i1, int i2) { - CV_DbgAssert( elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value) ); + CV_DbgAssert( elemSize() == sizeof(_Tp) ); return *(_Tp*)ptr(i0, i1, i2); } template inline const _Tp& Mat::at(int i0, int i1, int i2) const { - CV_DbgAssert( elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value) ); + CV_DbgAssert( elemSize() == sizeof(_Tp) ); return *(const _Tp*)ptr(i0, i1, i2); } template inline _Tp& Mat::at(const int* idx) { - CV_DbgAssert( elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value) ); + CV_DbgAssert( elemSize() == sizeof(_Tp) ); return *(_Tp*)ptr(idx); } template inline const _Tp& Mat::at(const int* idx) const { - CV_DbgAssert( elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value) ); + CV_DbgAssert( elemSize() == sizeof(_Tp) ); return *(const _Tp*)ptr(idx); } template inline _Tp& Mat::at(const Vec& idx) { - CV_DbgAssert( elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value) ); + CV_DbgAssert( elemSize() == sizeof(_Tp) ); return *(_Tp*)ptr(idx.val); } template inline const _Tp& Mat::at(const Vec& idx) const { - CV_DbgAssert( elemSize() == CV_ELEM_SIZE(traits::Type<_Tp>::value) ); + CV_DbgAssert( elemSize() == sizeof(_Tp) ); return *(const _Tp*)ptr(idx.val); } From 0451629e22938dc1054581005d747721b8ac67b9 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 25 Aug 2017 18:55:31 +0300 Subject: [PATCH 5/6] core(persistence): resolve DMatch/KeyPoint problem --- .../core/include/opencv2/core/persistence.hpp | 106 ++++---- modules/core/src/persistence.cpp | 61 +++-- modules/core/test/test_io.cpp | 246 +++++++++++++++++- 3 files changed, 331 insertions(+), 82 deletions(-) diff --git a/modules/core/include/opencv2/core/persistence.hpp b/modules/core/include/opencv2/core/persistence.hpp index e0a6efa465..6746be91eb 100644 --- a/modules/core/include/opencv2/core/persistence.hpp +++ b/modules/core/include/opencv2/core/persistence.hpp @@ -44,6 +44,11 @@ #ifndef OPENCV_CORE_PERSISTENCE_HPP #define OPENCV_CORE_PERSISTENCE_HPP +#ifndef CV_DOXYGEN +/// Define to support persistence legacy formats +#define CV__LEGACY_PERSISTENCE +#endif + #ifndef __cplusplus # error persistence.hpp header must be compiled as C++ #endif @@ -700,8 +705,10 @@ CV_EXPORTS void write( FileStorage& fs, const String& name, double value ); CV_EXPORTS void write( FileStorage& fs, const String& name, const String& value ); CV_EXPORTS void write( FileStorage& fs, const String& name, const Mat& value ); CV_EXPORTS void write( FileStorage& fs, const String& name, const SparseMat& value ); +#ifdef CV__LEGACY_PERSISTENCE CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector& value); CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector& value); +#endif CV_EXPORTS void writeScalar( FileStorage& fs, int value ); CV_EXPORTS void writeScalar( FileStorage& fs, float value ); @@ -720,8 +727,12 @@ CV_EXPORTS void read(const FileNode& node, String& value, const String& default_ CV_EXPORTS void read(const FileNode& node, std::string& value, const std::string& default_value); CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat = Mat() ); CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat = SparseMat() ); +#ifdef CV__LEGACY_PERSISTENCE CV_EXPORTS void read(const FileNode& node, std::vector& keypoints); CV_EXPORTS void read(const FileNode& node, std::vector& matches); +#endif +CV_EXPORTS void read(const FileNode& node, KeyPoint& value, const KeyPoint& default_value); +CV_EXPORTS void read(const FileNode& node, DMatch& value, const DMatch& default_value); template static inline void read(const FileNode& node, Point_<_Tp>& value, const Point_<_Tp>& default_value) { @@ -948,27 +959,6 @@ void write(FileStorage& fs, const Scalar_<_Tp>& s ) write(fs, s.val[3]); } -static inline -void write(FileStorage& fs, const KeyPoint& kpt ) -{ - write(fs, kpt.pt.x); - write(fs, kpt.pt.y); - write(fs, kpt.size); - write(fs, kpt.angle); - write(fs, kpt.response); - write(fs, kpt.octave); - write(fs, kpt.class_id); -} - -static inline -void write(FileStorage& fs, const DMatch& m ) -{ - write(fs, m.queryIdx); - write(fs, m.trainIdx); - write(fs, m.imgIdx); - write(fs, m.distance); -} - static inline void write(FileStorage& fs, const Range& r ) { @@ -976,26 +966,6 @@ void write(FileStorage& fs, const Range& r ) write(fs, r.end); } -static inline -void write( FileStorage& fs, const std::vector& vec ) -{ - size_t npoints = vec.size(); - for(size_t i = 0; i < npoints; i++ ) - { - write(fs, vec[i]); - } -} - -static inline -void write( FileStorage& fs, const std::vector& vec ) -{ - size_t npoints = vec.size(); - for(size_t i = 0; i < npoints; i++ ) - { - write(fs, vec[i]); - } -} - template static inline void write( FileStorage& fs, const std::vector<_Tp>& vec ) { @@ -1060,17 +1030,26 @@ void write(FileStorage& fs, const String& name, const Range& r ) } static inline -void write(FileStorage& fs, const String& name, const KeyPoint& r ) +void write(FileStorage& fs, const String& name, const KeyPoint& kpt) { cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); - write(fs, r); + write(fs, kpt.pt.x); + write(fs, kpt.pt.y); + write(fs, kpt.size); + write(fs, kpt.angle); + write(fs, kpt.response); + write(fs, kpt.octave); + write(fs, kpt.class_id); } static inline -void write(FileStorage& fs, const String& name, const DMatch& r ) +void write(FileStorage& fs, const String& name, const DMatch& m) { cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); - write(fs, r); + write(fs, m.queryIdx); + write(fs, m.trainIdx); + write(fs, m.imgIdx); + write(fs, m.distance); } template static inline @@ -1091,6 +1070,24 @@ void write( FileStorage& fs, const String& name, const std::vector< std::vector< } } +#ifdef CV__LEGACY_PERSISTENCE +// This code is not needed anymore, but it is preserved here to keep source compatibility +// Implementation is similar to templates instantiations +static inline void write(FileStorage& fs, const KeyPoint& kpt) { write(fs, String(), kpt); } +static inline void write(FileStorage& fs, const DMatch& m) { write(fs, String(), m); } +static inline void write(FileStorage& fs, const std::vector& vec) +{ + cv::internal::VecWriterProxy w(&fs); + w(vec); +} +static inline void write(FileStorage& fs, const std::vector& vec) +{ + cv::internal::VecWriterProxy w(&fs); + w(vec); + +} +#endif + //! @} FileStorage //! @relates cv::FileNode @@ -1258,12 +1255,6 @@ void operator >> (const FileNode& n, std::vector<_Tp>& vec) /** @brief Reads KeyPoint from a file storage. */ //It needs special handling because it contains two types of fields, int & float. -static inline -void operator >> (const FileNode& n, std::vector& vec) -{ - read(n, vec); -} - static inline void operator >> (const FileNode& n, KeyPoint& kpt) { @@ -1271,15 +1262,22 @@ void operator >> (const FileNode& n, KeyPoint& kpt) it >> kpt.pt.x >> kpt.pt.y >> kpt.size >> kpt.angle >> kpt.response >> kpt.octave >> kpt.class_id; } -/** @brief Reads DMatch from a file storage. -*/ -//It needs special handling because it contains two types of fields, int & float. +#ifdef CV__LEGACY_PERSISTENCE +static inline +void operator >> (const FileNode& n, std::vector& vec) +{ + read(n, vec); +} static inline void operator >> (const FileNode& n, std::vector& vec) { read(n, vec); } +#endif +/** @brief Reads DMatch from a file storage. +*/ +//It needs special handling because it contains two types of fields, int & float. static inline void operator >> (const FileNode& n, DMatch& m) { diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp index e2d223d4b0..f428063d70 100644 --- a/modules/core/src/persistence.cpp +++ b/modules/core/src/persistence.cpp @@ -7333,21 +7333,45 @@ void read( const FileNode& node, SparseMat& mat, const SparseMat& default_mat ) m->copyToSparseMat(mat); } -void write(FileStorage& fs, const String& objname, const std::vector& keypoints) +CV_EXPORTS void read(const FileNode& node, KeyPoint& value, const KeyPoint& default_value) { - cv::internal::WriteStructContext ws(fs, objname, CV_NODE_SEQ + CV_NODE_FLOW); + if( node.empty() ) + { + value = default_value; + return; + } + node >> value; +} - int i, npoints = (int)keypoints.size(); - for( i = 0; i < npoints; i++ ) +CV_EXPORTS void read(const FileNode& node, DMatch& value, const DMatch& default_value) +{ + if( node.empty() ) { - write(fs, keypoints[i]); + value = default_value; + return; } + node >> value; } +#ifdef CV__LEGACY_PERSISTENCE +void write( FileStorage& fs, const String& name, const std::vector& vec) +{ + // from template implementation + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ); + write(fs, vec); +} void read(const FileNode& node, std::vector& keypoints) { - keypoints.resize(0); + FileNode first_node = *(node.begin()); + if (first_node.isSeq()) + { + // modern scheme + FileNodeIterator it = node.begin(); + it >> keypoints; + return; + } + keypoints.clear(); FileNodeIterator it = node.begin(), it_end = node.end(); for( ; it != it_end; ) { @@ -7357,21 +7381,24 @@ void read(const FileNode& node, std::vector& keypoints) } } - -void write(FileStorage& fs, const String& objname, const std::vector& matches) +void write( FileStorage& fs, const String& name, const std::vector& vec) { - cv::internal::WriteStructContext ws(fs, objname, CV_NODE_SEQ + CV_NODE_FLOW); - - int i, n = (int)matches.size(); - for( i = 0; i < n; i++ ) - { - write(fs, matches[i]); - } + // from template implementation + cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ); + write(fs, vec); } void read(const FileNode& node, std::vector& matches) { - matches.resize(0); + FileNode first_node = *(node.begin()); + if (first_node.isSeq()) + { + // modern scheme + FileNodeIterator it = node.begin(); + it >> matches; + return; + } + matches.clear(); FileNodeIterator it = node.begin(), it_end = node.end(); for( ; it != it_end; ) { @@ -7380,7 +7407,7 @@ void read(const FileNode& node, std::vector& matches) matches.push_back(m); } } - +#endif int FileNode::type() const { return !node ? NONE : (node->tag & TYPE_MASK); } bool FileNode::isNamed() const { return !node ? false : (node->tag & NAMED) != 0; } diff --git a/modules/core/test/test_io.cpp b/modules/core/test/test_io.cpp index a70b2aac98..8d1bb324b8 100644 --- a/modules/core/test/test_io.cpp +++ b/modules/core/test/test_io.cpp @@ -1146,15 +1146,19 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector) EXPECT_STREQ(fs_result.c_str(), "%YAML:1.0\n" "---\n" -"dv: [ 1, 2, 3, -1.5000000000000000e+000, 2, 3, 4,\n" -" 1.5000000000000000e+000, 3, 2, 1, 5.0000000000000000e-001 ]\n" +"dv:\n" +" - [ 1, 2, 3, -1.5000000000000000e+000 ]\n" +" - [ 2, 3, 4, 1.5000000000000000e+000 ]\n" +" - [ 3, 2, 1, 5.0000000000000000e-001 ]\n" ); #else EXPECT_STREQ(fs_result.c_str(), "%YAML:1.0\n" "---\n" -"dv: [ 1, 2, 3, -1.5000000000000000e+00, 2, 3, 4, 1.5000000000000000e+00,\n" -" 3, 2, 1, 5.0000000000000000e-01 ]\n" +"dv:\n" +" - [ 1, 2, 3, -1.5000000000000000e+00 ]\n" +" - [ 2, 3, 4, 1.5000000000000000e+00 ]\n" +" - [ 3, 2, 1, 5.0000000000000000e-01 ]\n" ); #endif @@ -1200,19 +1204,26 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector_vector) "%YAML:1.0\n" "---\n" "dvv:\n" -" - [ 1, 2, 3, -1.5000000000000000e+000, 2, 3, 4,\n" -" 1.5000000000000000e+000, 3, 2, 1, 5.0000000000000000e-001 ]\n" -" - [ 3, 2, 1, 5.0000000000000000e-001, 1, 2, 3,\n" -" -1.5000000000000000e+000 ]\n" +" -\n" +" - [ 1, 2, 3, -1.5000000000000000e+000 ]\n" +" - [ 2, 3, 4, 1.5000000000000000e+000 ]\n" +" - [ 3, 2, 1, 5.0000000000000000e-001 ]\n" +" -\n" +" - [ 3, 2, 1, 5.0000000000000000e-001 ]\n" +" - [ 1, 2, 3, -1.5000000000000000e+000 ]\n" ); #else EXPECT_STREQ(fs_result.c_str(), "%YAML:1.0\n" "---\n" "dvv:\n" -" - [ 1, 2, 3, -1.5000000000000000e+00, 2, 3, 4, 1.5000000000000000e+00,\n" -" 3, 2, 1, 5.0000000000000000e-01 ]\n" -" - [ 3, 2, 1, 5.0000000000000000e-01, 1, 2, 3, -1.5000000000000000e+00 ]\n" +" -\n" +" - [ 1, 2, 3, -1.5000000000000000e+00 ]\n" +" - [ 2, 3, 4, 1.5000000000000000e+00 ]\n" +" - [ 3, 2, 1, 5.0000000000000000e-01 ]\n" +" -\n" +" - [ 3, 2, 1, 5.0000000000000000e-01 ]\n" +" - [ 1, 2, 3, -1.5000000000000000e+00 ]\n" ); #endif @@ -1237,6 +1248,219 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector_vector) } } + +TEST(Core_InputOutput, FileStorage_KeyPoint) +{ + cv::FileStorage fs("keypoint.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY); + + cv::KeyPoint k(Point2f(1, 2), 16, 0, 100, 1, -1); + + EXPECT_NO_THROW(fs << "k" << k); + cv::String fs_result = fs.releaseAndGetString(); + EXPECT_STREQ(fs_result.c_str(), +"\n" +"\n" +"\n" +" 1. 2. 16. 0. 100. 1 -1\n" +"\n" +); + + cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY); + + cv::KeyPoint k_read; + ASSERT_NO_THROW(fs_read["k"] >> k_read); + + EXPECT_EQ(k.pt, k_read.pt); + EXPECT_EQ(k.size, k_read.size); + EXPECT_EQ(k.angle, k_read.angle); + EXPECT_EQ(k.response, k_read.response); + EXPECT_EQ(k.octave, k_read.octave); + EXPECT_EQ(k.class_id, k_read.class_id); +} + +TEST(Core_InputOutput, FileStorage_KeyPoint_vector) +{ + cv::FileStorage fs("keypoint.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY); + + cv::KeyPoint k1(Point2f(1, 2), 16, 0, 100, 1, -1); + cv::KeyPoint k2(Point2f(2, 3), 16, 45, 100, 1, -1); + cv::KeyPoint k3(Point2f(1, 2), 16, 90, 100, 1, -1); + std::vector kv; + kv.push_back(k1); + kv.push_back(k2); + kv.push_back(k3); + + EXPECT_NO_THROW(fs << "kv" << kv); + cv::String fs_result = fs.releaseAndGetString(); + EXPECT_STREQ(fs_result.c_str(), +"\n" +"\n" +"\n" +" <_>\n" +" 1. 2. 16. 0. 100. 1 -1\n" +" <_>\n" +" 2. 3. 16. 45. 100. 1 -1\n" +" <_>\n" +" 1. 2. 16. 90. 100. 1 -1\n" +"\n" +); + + cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY); + + std::vector kv_read; + ASSERT_NO_THROW(fs_read["kv"] >> kv_read); + + ASSERT_EQ(kv.size(), kv_read.size()); + for (size_t i = 0; i < kv.size(); i++) + { + EXPECT_EQ(kv[i].pt, kv_read[i].pt); + EXPECT_EQ(kv[i].size, kv_read[i].size); + EXPECT_EQ(kv[i].angle, kv_read[i].angle); + EXPECT_EQ(kv[i].response, kv_read[i].response); + EXPECT_EQ(kv[i].octave, kv_read[i].octave); + EXPECT_EQ(kv[i].class_id, kv_read[i].class_id); + } +} + +TEST(Core_InputOutput, FileStorage_KeyPoint_vector_vector) +{ + cv::FileStorage fs("keypoint.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY); + + cv::KeyPoint k1(Point2f(1, 2), 16, 0, 100, 1, -1); + cv::KeyPoint k2(Point2f(2, 3), 16, 45, 100, 1, -1); + cv::KeyPoint k3(Point2f(1, 2), 16, 90, 100, 1, -1); + std::vector kv1; + kv1.push_back(k1); + kv1.push_back(k2); + kv1.push_back(k3); + + std::vector kv2; + kv2.push_back(k3); + kv2.push_back(k1); + + std::vector< std::vector > kvv; + kvv.push_back(kv1); + kvv.push_back(kv2); + + EXPECT_NO_THROW(fs << "kvv" << kvv); + cv::String fs_result = fs.releaseAndGetString(); + EXPECT_STREQ(fs_result.c_str(), +"\n" +"\n" +"\n" +" <_>\n" +" <_>\n" +" 1. 2. 16. 0. 100. 1 -1\n" +" <_>\n" +" 2. 3. 16. 45. 100. 1 -1\n" +" <_>\n" +" 1. 2. 16. 90. 100. 1 -1\n" +" <_>\n" +" <_>\n" +" 1. 2. 16. 90. 100. 1 -1\n" +" <_>\n" +" 1. 2. 16. 0. 100. 1 -1\n" +"\n" +); + + cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY); + + std::vector< std::vector > kvv_read; + ASSERT_NO_THROW(fs_read["kvv"] >> kvv_read); + + ASSERT_EQ(kvv.size(), kvv_read.size()); + for (size_t j = 0; j < kvv.size(); j++) + { + const std::vector& kv = kvv[j]; + const std::vector& kv_read = kvv_read[j]; + ASSERT_EQ(kvv.size(), kvv_read.size()); + for (size_t i = 0; i < kv.size(); i++) + { + EXPECT_EQ(kv[i].pt, kv_read[i].pt); + EXPECT_EQ(kv[i].size, kv_read[i].size); + EXPECT_EQ(kv[i].angle, kv_read[i].angle); + EXPECT_EQ(kv[i].response, kv_read[i].response); + EXPECT_EQ(kv[i].octave, kv_read[i].octave); + EXPECT_EQ(kv[i].class_id, kv_read[i].class_id); + } + } +} + + +#ifdef CV__LEGACY_PERSISTENCE +TEST(Core_InputOutput, FileStorage_LEGACY_DMatch_vector) +{ + cv::DMatch d1(1, 2, 3, -1.5f); + cv::DMatch d2(2, 3, 4, 1.5f); + cv::DMatch d3(3, 2, 1, 0.5f); + std::vector dv; + dv.push_back(d1); + dv.push_back(d2); + dv.push_back(d3); + + String fs_result = +"\n" +"\n" +"\n" +" 1 2 3 -1.5000000000000000e+00 2 3 4 1.5000000000000000e+00 3 2 1\n" +" 5.0000000000000000e-01\n" +"\n" + ; + + cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY); + + std::vector dv_read; + ASSERT_NO_THROW(fs_read["dv"] >> dv_read); + + ASSERT_EQ(dv.size(), dv_read.size()); + for (size_t i = 0; i < dv.size(); i++) + { + EXPECT_EQ(dv[i].queryIdx, dv_read[i].queryIdx); + EXPECT_EQ(dv[i].trainIdx, dv_read[i].trainIdx); + EXPECT_EQ(dv[i].imgIdx, dv_read[i].imgIdx); + EXPECT_EQ(dv[i].distance, dv_read[i].distance); + } +} + + +TEST(Core_InputOutput, FileStorage_LEGACY_KeyPoint_vector) +{ + cv::KeyPoint k1(Point2f(1, 2), 16, 0, 100, 1, -1); + cv::KeyPoint k2(Point2f(2, 3), 16, 45, 100, 1, -1); + cv::KeyPoint k3(Point2f(1, 2), 16, 90, 100, 1, -1); + std::vector kv; + kv.push_back(k1); + kv.push_back(k2); + kv.push_back(k3); + + cv::String fs_result = +"\n" +"\n" +"\n" +" 1. 2. 16. 0. 100. 1 -1\n" +" 2. 3. 16. 45. 100. 1 -1\n" +" 1. 2. 16. 90. 100. 1 -1\n" +"\n" + ; + + cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY); + + std::vector kv_read; + ASSERT_NO_THROW(fs_read["kv"] >> kv_read); + + ASSERT_EQ(kv.size(), kv_read.size()); + for (size_t i = 0; i < kv.size(); i++) + { + EXPECT_EQ(kv[i].pt, kv_read[i].pt); + EXPECT_EQ(kv[i].size, kv_read[i].size); + EXPECT_EQ(kv[i].angle, kv_read[i].angle); + EXPECT_EQ(kv[i].response, kv_read[i].response); + EXPECT_EQ(kv[i].octave, kv_read[i].octave); + EXPECT_EQ(kv[i].class_id, kv_read[i].class_id); + } +} +#endif + TEST(Core_InputOutput, FileStorage_format_xml) { FileStorage fs; From 164a41b399a2539b066cf741df6f2d911b01ea29 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 31 Aug 2017 19:13:07 +0300 Subject: [PATCH 6/6] fix CUDA build CUDA implementation wants to convert std::vector <-> GpuMat. There is no direct mapping from KeyPoint (mix of int/float fields) into cv::Mat element type, so this conversion must be avoided. Legacy mode is turned back for CUDA builds. --- cmake/OpenCVUtils.cmake | 6 ++++++ modules/core/CMakeLists.txt | 4 ++++ modules/cudaobjdetect/src/cascadeclassifier.cpp | 8 ++++---- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index e3a1358172..ab24750405 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -940,6 +940,12 @@ function(ocv_target_link_libraries target) endif() endfunction() +function(ocv_target_compile_definitions target) + _ocv_fix_target(target) + target_compile_definitions(${target} ${ARGN}) +endfunction() + + function(_ocv_append_target_includes target) if(DEFINED OCV_TARGET_INCLUDE_DIRS_${target}) target_include_directories(${target} PRIVATE ${OCV_TARGET_INCLUDE_DIRS_${target}}) diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 4d6b7bbd82..0f4ccad68b 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -63,5 +63,9 @@ ocv_target_link_libraries(${the_module} LINK_PRIVATE "${OPENCV_HAL_LINKER_LIBS}" ) +if(HAVE_CUDA) + ocv_target_compile_definitions(${the_module} PUBLIC OPENCV_TRAITS_ENABLE_DEPRECATED) +endif() + ocv_add_accuracy_tests() ocv_add_perf_tests() diff --git a/modules/cudaobjdetect/src/cascadeclassifier.cpp b/modules/cudaobjdetect/src/cascadeclassifier.cpp index c3830ad1f1..bade19d237 100644 --- a/modules/cudaobjdetect/src/cascadeclassifier.cpp +++ b/modules/cudaobjdetect/src/cascadeclassifier.cpp @@ -186,7 +186,7 @@ namespace } BufferPool pool(stream); - GpuMat objectsBuf = pool.getBuffer(1, maxNumObjects_, DataType::type); + GpuMat objectsBuf = pool.getBuffer(1, maxNumObjects_, traits::Type::value); unsigned int numDetections; ncvSafeCall( process(image, objectsBuf, ncvMinSize, numDetections) ); @@ -220,7 +220,7 @@ namespace } CV_Assert( gpu_objects.rows == 1 ); - CV_Assert( gpu_objects.type() == DataType::type ); + CV_Assert( gpu_objects.type() == traits::Type::value ); Rect* ptr = gpu_objects.ptr(); objects.assign(ptr, ptr + gpu_objects.cols); @@ -533,7 +533,7 @@ namespace const float grouping_eps = 0.2f; BufferPool pool(stream); - GpuMat objects = pool.getBuffer(1, maxNumObjects_, DataType::type); + GpuMat objects = pool.getBuffer(1, maxNumObjects_, traits::Type::value); // used for debug // candidates.setTo(cv::Scalar::all(0)); @@ -625,7 +625,7 @@ namespace } CV_Assert( gpu_objects.rows == 1 ); - CV_Assert( gpu_objects.type() == DataType::type ); + CV_Assert( gpu_objects.type() == traits::Type::value ); Rect* ptr = gpu_objects.ptr(); objects.assign(ptr, ptr + gpu_objects.cols);