diff --git a/modules/core/include/opencv2/core/array_helpers.hpp b/modules/core/include/opencv2/core/array_helpers.hpp new file mode 100644 index 000000000000..241af6cb76e0 --- /dev/null +++ b/modules/core/include/opencv2/core/array_helpers.hpp @@ -0,0 +1,682 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2013, OpenCV Foundation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef OPENCV_CORE_ARRAY_HELPERS_HPP +#define OPENCV_CORE_ARRAY_HELPERS_HPP + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" + +namespace cv { +struct _ArrayOpsBase { + virtual Mat getMat_(const _InputArray& self, int i = -1) const = 0; + virtual UMat getUMat(const _InputArray& self, int i) const = 0; + virtual std::vector getMatVector(const _InputArray& self) const = 0; + virtual std::vector getUMatVector(const _InputArray& self) const = 0; + virtual int dims(const _InputArray& self, int i) const = 0; + virtual Size size(const _InputArray& self, int i) const = 0; + virtual int sizend(const _InputArray& self, int* arraySize, int i) const = 0; + virtual int type(const _InputArray& self, int i) const = 0; + virtual std::size_t total(const _InputArray& self, int i) const = 0; + virtual int isContinuous(const _InputArray& self, int i) const = 0; + virtual int isSubmatrix(const _InputArray& self, int i) const = 0; + virtual int empty(const _InputArray& self) const = 0; + virtual int empty(const _InputArray& self, int i) const = 0; + virtual std::size_t offset(const _InputArray& self, std::size_t i) const = 0; + virtual std::size_t step(const _InputArray& self, std::size_t i) const = 0; + + virtual void create(const _OutputArray& arr, + int d, + const int* sizes, + int mtype, + int i, + bool allowTransposed, + _OutputArray::DepthMask fixedDepthMask) const = 0; + virtual void release(const _OutputArray& self) const = 0; + virtual Mat& getMatRef(const _OutputArray& self, int i) const = 0; + virtual UMat& getUMatRef(const _OutputArray& self, int i) const = 0; + virtual void assign(const _OutputArray& self, const std::vector& other) const = 0; + virtual void assign(const _OutputArray& self, const std::vector& other) const = 0; +protected: + ~_ArrayOpsBase() = default; +}; + +template +inline constexpr bool is_Mat = std::is_same_v; + +template +inline constexpr bool is_Mat> = true; + +template +inline constexpr bool is_UMat = std::is_same_v; + +template +inline constexpr bool is_cuda_GpuMat = std::is_same_v; + +template +inline constexpr bool is_vector = false; + +template +inline constexpr bool is_vector> = true; + +#ifdef HAVE_CUDA +inline constexpr bool have_cuda = true; +#else +inline constexpr bool have_cuda = false; +#endif // HAVE_CUDA + +template +struct _ArrayOps final : _ArrayOpsBase { + Mat getMat_(const _InputArray& self, const int i) const final + { + T& v = get(self.getObj()); + using value_type = typename T::value_type; + [[maybe_unused]] const auto index = static_cast(i); + + if constexpr (std::is_same_v) { + CV_Assert(i < 0); + constexpr int type = CV_8U; + if (v.empty()) { + return Mat(); + } + + const int n = static_cast(v.size()); + Mat m(1, &n, type); + std::copy(v.begin(), v.end(), m.data); + return m; + } + else if constexpr (is_Mat) { + CV_Assert(0 <= i); + CV_Assert(index < v.size()); + return v[index]; + } + else if constexpr (is_UMat) { + CV_Assert(0 <= i); + CV_Assert(index < v.size()); + return v[index].getMat(self.getFlags() & ACCESS_MASK); + } + else if constexpr (is_vector) { + const int type = self.type(i); + CV_Assert(0 <= i); + CV_Assert(index < v.size()); + auto& sub_v = v[i]; + const int v_size = static_cast(sub_v.size()); + return sub_v.empty() ? Mat() : Mat(1, &v_size, type, sub_v.data()); + } + else { + CV_Assert(i < 0); + const int type = CV_MAT_TYPE(self.getFlags()); + const int width = static_cast(v.size()); + return v.empty() ? Mat() : Mat(1, &width, type, v.data()); + } + } + + UMat getUMat(const _InputArray& self, const int i) const final { + using value_type = typename T::value_type; + + if constexpr (is_UMat) { + T& v = get(self.getObj()); + CV_Assert(0 <= i); + CV_Assert(static_cast(i) < v.size()); + return v[i]; + } + else { + CV_Assert(false && "unreachable"); + } + } + + std::vector getMatVector(const _InputArray& self) const final + { + using value_type = typename T::value_type; + auto& v = get(self.getObj()); + if constexpr (is_Mat) { + return {v.begin(), v.end()}; + } + else if constexpr (!is_cuda_GpuMat) { + const int flags = self.getFlags(); + [[maybe_unused]] const int type = CV_MAT_TYPE(flags); + [[maybe_unused]] const int column_number = CV_MAT_CN(flags); + + std::vector result; + result.reserve(v.size()); + + for (std::size_t i = 0; i < v.size(); ++i) { + if constexpr (is_UMat) { + result.emplace_back(v[i].getMat(flags & ACCESS_MASK)); + } + else if constexpr (is_vector) { + result.emplace_back(size(self, i), type, static_cast(v[i].data())); + } + else if constexpr (!std::is_same_v) { + result.emplace_back(1, column_number, type, static_cast(&v[i])); + } + } + + return result; + } + else { + CV_Assert(false && "unreachable"); + } + } + + std::vector getUMatVector(const _InputArray& self) const final + { + using value_type = typename T::value_type; + auto& v = get(self.getObj()); + [[maybe_unused]] const int flags = self.getFlags(); + + if constexpr (is_UMat) { + return v; + } + else if constexpr (is_Mat) { + std::vector result; + result.reserve(v.size()); + for (std::size_t i = 0; i < v.size(); ++i) { + result.emplace_back(v[i].getUMat(flags & ACCESS_MASK)); + } + + return result; + } + else { + CV_Assert(false && "unreachable"); + } + } + + int dims(const _InputArray& self, const int i) const final + { + using value_type = typename T::value_type; + T& v = get(self.getObj()); + if constexpr (is_vector || is_Mat || is_UMat) { + if (i < 0) { + return 1; + } + + if constexpr (is_vector) { + CV_Assert(static_cast(i) < v.size()); + return 2; + } + else { + return v[i].dims; + } + } + else { + CV_Assert(i < 0); + return 1; + } + } + + Size size(const _InputArray& self, const int i) const final { + using value_type = typename T::value_type; + auto& v = get(self.getObj()); + + if constexpr (is_Mat || is_UMat) { + if (i < 0) { + return v.empty() ? Size() : Size(static_cast(v.size()), 1); + } + + const auto index = static_cast(i); + CV_Assert(index < v.size()); + return v[index].size(); + } + else if constexpr (is_vector) { + if (i < 0) { + return v.empty() ? Size() : Size(static_cast(v.size()), 1); + } + + const auto index = static_cast(i); + CV_Assert(index < v.size()); + return Size(static_cast(v[index].size()), 1); + } + else { + CV_Assert(i < 0); + return Size(static_cast(v.size()), 1); + } + } + + int sizend(const _InputArray& self, int* const arraySize, const int i) const final + { + using value_type = typename T::value_type; + T& v = get(self.getObj()); + if constexpr (is_Mat || is_UMat) { + CV_Assert(i >= 0); + CV_Assert(static_cast(i) < v.size()); + + const auto& m = v[i]; + const int result = m.dims; + if (arraySize != nullptr) { + for (int j = 0; j < result; ++j) { + arraySize[j] = m.size.p[j]; + } + } + + return result; + } + else { + CV_Assert(i < 0); + Size sz2d = Size(v.size(), 1); + if (arraySize != nullptr) { + arraySize[0] = sz2d.width; + } + + return 1; + } + } + + int type(const _InputArray& self, const int i) const final + { + using value_type = typename T::value_type; + if constexpr (is_Mat || is_UMat) { + T& v = get(self.getObj()); + if (v.empty()) { + const int flags = self.getFlags(); + CV_Assert((flags & _InputArray::FIXED_TYPE) != 0); + return CV_MAT_TYPE(flags); + } + + CV_Assert(i < static_cast(v.size())); + return v[i >= 0 ? i : 0].type(); + } + else { + CV_Assert(false && "unreachable"); + } + } + + std::size_t total(const _InputArray& self, const int i) const final { + using value_type = typename T::value_type; + T& v = get(self.getObj()); + if constexpr (is_Mat || is_UMat) { + if (i < 0) { + return v.size(); + } + + CV_Assert(i < static_cast(v.size())); + return v[i].total(); + } else { + CV_Assert(false && "unreachable"); + } + } + + int isContinuous(const _InputArray& self, const int i) const final + { + auto& v = get(self.getObj()); + using value_type = typename T::value_type; + if constexpr (is_Mat || is_UMat) { + CV_Assert(i >= 0); + CV_Assert(i < static_cast(v.size())); + return v[i].isContinuous(); + } + else { + CV_Assert(false && "unreachable"); + } + } + + int isSubmatrix(const _InputArray& self, const int i) const final + { + using value_type = typename T::value_type; + if constexpr (is_Mat || is_UMat) { + T& v = get(self.getObj()); + CV_Assert(i >= 0); + CV_Assert(i < static_cast(v.size())); + return v[i].isSubmatrix(); + } + else { + CV_Assert(false && "unreachable"); + } + } + + int empty(const _InputArray& self) const final + { + return get(self.getObj()).empty(); + } + + int empty(const _InputArray& self, const int i) const final + { + using value_type = typename T::value_type; + const T& v = get(self.getObj()); + if constexpr (is_Mat || is_UMat || is_vector) { + CV_Assert(i >= 0); + CV_Assert(i < static_cast(v.size())); + return v[i].empty(); + } + else { + CV_Assert(false && "unreachable"); + } + } + + std::size_t offset(const _InputArray& self, const std::size_t i) const final + { + using value_type = typename T::value_type; + const T& v = get(self.getObj()); + CV_Assert(i < v.size()); + + if constexpr (is_Mat) { + return static_cast(v[i].ptr() - v[i].datastart); + } + else if constexpr (is_UMat) { + return v[i].offset; + } + else { + CV_Assert(false && "unreachable"); + } + } + + std::size_t step(const _InputArray& self, const std::size_t i) const final + { + using value_type = typename T::value_type; + const auto& v = get(self.getObj()); + CV_Assert(i < v.size()); + + if constexpr (is_Mat || is_UMat) { + return v[i].step; + } + else { + CV_Assert(false && "unreachable"); + } + } + + void create(const _OutputArray& arr, + const int d, + const int* const sizes, + int mtype, + const int i, + const bool allowTransposed, + const _OutputArray::DepthMask fixedDepthMask) const final + { + using value_type = typename T::value_type; + auto& v = get(arr.getObj()); + + if constexpr (is_Mat || is_UMat) { + if (i < 0) { + CV_Assert(d == 2); + CV_Assert(sizes[0] == 1 || sizes[1] == 1 || sizes[0] * sizes[1] == 0); + const std::size_t len = sizes[0] * sizes[1] > 0 ? sizes[0] + sizes[1] - 1 : 0; + const std::size_t len0 = v.size(); + + CV_Assert(!arr.fixedSize() || len == len0); + v.resize(len); + if (arr.fixedType()) { + const int _type = CV_MAT_TYPE(arr.getFlags()); + for (std::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 < static_cast(v.size())); + auto& m = mattify(v[i]); + + if (allowTransposed) { + if (!m.isContinuous()) { + CV_Assert(!arr.fixedType() && !arr.fixedSize()); + m.release(); + } + + const bool same_type = m.type() == mtype; + const bool same_dimensions = d == 2 && m.dims == 2 && m.rows == sizes[1] && m.cols == sizes[0]; + if (get_data(m) != nullptr && same_type && same_dimensions) { + return; + } + } + + if (arr.fixedType()) { + const bool same_channels = CV_MAT_CN(mtype) == m.channels(); + const bool has_depth = ((1 << CV_MAT_TYPE(arr.getFlags())) & fixedDepthMask) != 0; + if (same_channels && has_depth) { + mtype = m.type(); + } + else { + CV_Assert(CV_MAT_TYPE(mtype) == m.type()); + } + } + + if (arr.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; + } + else if constexpr (!std::is_same_v) { + const int size0 = d > 0 ? sizes[0] : 1; + const int size1 = d > 1 ? sizes[1] : 1; + CV_Assert(d <= 2); + CV_Assert(size0 == 1 || size1 == 1 || size0 * size1 == 0); + + const std::size_t len = size0 * size1 > 0 ? size0 + size1 - 1 : 0; + + if constexpr (is_vector) { + if (i < 0) { + CV_Assert(!arr.fixedSize() || len == v.size()); + v.resize(len); + return; + } + + CV_Assert(i < static_cast(v.size())); + v[i].resize(len); + } + else { + CV_Assert(i < 0); + const int type0 = CV_MAT_TYPE(arr.getFlags()); + CV_Assert(mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0)); + v.resize(len); + } + } + else { + CV_Assert(false && "unreachable"); + } + } + + void release(const _OutputArray& self) const override + { + get(self.getObj()).clear(); + } + + Mat& getMatRef(const _OutputArray& self, const int i) const final + { + if constexpr (is_Mat) { + CV_Assert(i >= 0); + T& v = get(self.getObj()); + CV_Assert(i < static_cast(v.size())); + return v[i]; + } + else { + CV_Assert(false && "unreachable"); + } + } + + UMat& getUMatRef(const _OutputArray& self, const int i) const final + { + if constexpr (is_UMat) { + CV_Assert(i >= 0); + T& v = get(self.getObj()); + CV_Assert(i < static_cast(v.size())); + return v[i]; + } + else { + CV_Assert(false && "unreachable"); + } + } + + void assign(const _OutputArray& self, const std::vector& other) const final + { + return assign_impl(self, other); + } + + void assign(const _OutputArray& self, const std::vector& other) const final + { + return assign_impl(self, other); + } + + static const T& get(const void* const data) + { + return *static_cast(data); + } + + static T& get(void* const data) + { + return *static_cast(data); + } + + template + static auto get_data(U& m) + { + if constexpr (is_Mat) { + return m.data; + } + else if constexpr (is_UMat) { + return m.u; + } + else { + CV_Assert(false && "unreachable"); + } + } + + template + static auto& mattify(U& m) + { + if constexpr (is_Mat) { + return static_cast(m); + } + else if constexpr (is_UMat) { + return m; + } + else { + CV_Assert(false && "unreachable"); + } + } + + template + static void assign_impl(const _OutputArray& self, const std::vector& other) + { + using value_type = typename T::value_type; + if constexpr (is_Mat || is_UMat) { + auto& this_v = get(self.getObj()); + CV_Assert(this_v.size() == other.size()); + + for (std::size_t i = 0; i < other.size(); ++i) { + const auto& m = other[i]; + auto& this_m = this_v[i]; + if (this_m.u != nullptr && this_m.u == m.u) { + continue; + } + + m.copyTo(this_m); + } + } + else { + CV_Assert(false && "unreachable"); + } + } +}; + +template<> +Mat _ArrayOps>::getMat_(const _InputArray& self, const int i) const; + +template<> +Size _ArrayOps>::size(const _InputArray& self, const int i) const; + +template<> +int _ArrayOps>::sizend(const _InputArray& self, int* const arraySize, const int i) const; + +template<> +std::size_t _ArrayOps>::offset(const _InputArray& self, const std::size_t i) const; + +template<> +std::size_t _ArrayOps>::step(const _InputArray& self, const std::size_t i) const; + +template<> +void _ArrayOps>::create(const _OutputArray& arr, + int d, + const int* sizes, + int mtype, + int i, + bool allowTransposed, + _OutputArray::DepthMask fixedDepthMask) const; + +template<> +void _ArrayOps>::release(const _OutputArray& self) const; + +template +inline constexpr _ArrayOps array_ops; + +template +_InputArray::_InputArray(const int _flags, T* const _obj) +: _InputArray(_flags, _obj, {}) +{} + +template +_InputArray::_InputArray(const int _flags, T* const _obj, const Size _sz) +: flags(_flags) +, obj(_obj) +, sz(_sz) +{ + if constexpr (is_vector) { + ops = &array_ops; + } +} + +template +_InputArray::_InputArray(const int _flags, const T* const _obj, const Size _sz) +: flags(_flags) +, obj(const_cast(_obj)) +, sz(_sz) +{ + if constexpr (is_vector) { + ops = &array_ops; + } +} +} // namespace cv + +#pragma GCC diagnostic pop + +#endif // OPENCV_CORE_ARRAY_HELPERS_HPP diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index d1cad11f5c5c..e1c0ab556638 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -176,6 +176,7 @@ CV_EXPORTS bool operator != (const MatShape& shape1, const MatShape& shape2); CV__DEBUG_NS_BEGIN +struct CV_EXPORTS _ArrayOpsBase; class CV_EXPORTS _OutputArray; //////////////////////// Input/Output Array Arguments ///////////////////////////////// @@ -289,8 +290,8 @@ class CV_EXPORTS _InputArray STD_ARRAY_MAT =15 << KIND_SHIFT }; - _InputArray(); - _InputArray(int _flags, void* _obj); + _InputArray() = default; + template _InputArray(int flags, T* obj); _InputArray(const Mat& m); _InputArray(const MatExpr& expr); _InputArray(const std::vector& vec); @@ -359,15 +360,18 @@ class CV_EXPORTS _InputArray bool isVector() const; bool isGpuMat() const; bool isGpuMatVector() const; - ~_InputArray(); protected: - int flags; - void* obj; + int flags = static_cast(NONE); + void* obj = nullptr; Size sz; + const _ArrayOpsBase* ops = nullptr; + + template + _InputArray(int flags, T* obj, Size sz); - void init(int _flags, const void* _obj); - void init(int _flags, const void* _obj, Size _sz); + template + _InputArray(int flags, const T* obj, Size sz); }; CV_ENUM_FLAGS(_InputArray::KindFlag) __CV_ENUM_FLAGS_BITWISE_AND(_InputArray::KindFlag, int, _InputArray::KindFlag) @@ -421,8 +425,13 @@ class CV_EXPORTS _OutputArray : public _InputArray DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F }; - _OutputArray(); - _OutputArray(int _flags, void* _obj); + _OutputArray() = default; + + template + _OutputArray(int _flags, T* _obj) + : _InputArray(_flags, _obj) + {} + _OutputArray(Mat& m); _OutputArray(std::vector& vec); _OutputArray(cuda::GpuMat& d_mat); @@ -503,14 +512,23 @@ class CV_EXPORTS _OutputArray : public _InputArray void move(UMat& u) const; void move(Mat& m) const; +protected: + template _OutputArray(int _flags, T* _obj, Size _sz) + : _InputArray(_flags, _obj, _sz) + {} }; class CV_EXPORTS _InputOutputArray : public _OutputArray { public: - _InputOutputArray(); - _InputOutputArray(int _flags, void* _obj); + _InputOutputArray() = default; + + template + _InputOutputArray(int _flags, T* _obj) + : _OutputArray(_flags, _obj) + {} + _InputOutputArray(Mat& m); _InputOutputArray(std::vector& vec); _InputOutputArray(cuda::GpuMat& d_mat); @@ -550,7 +568,11 @@ class CV_EXPORTS _InputOutputArray : public _OutputArray template static _InputOutputArray rawInOut(std::vector<_Tp>& vec); template _InputOutputArray rawInOut(std::array<_Tp, _Nm>& arr); - +private: + template + _InputOutputArray(int _flags, T* _obj, Size _sz) + : _OutputArray(_flags, _obj, _sz) + {} }; /** Helper to wrap custom types. @see InputArray */ @@ -4088,5 +4110,6 @@ CV_EXPORTS MatExpr abs(const MatExpr& e); } // cv #include "opencv2/core/mat.inl.hpp" +#include "opencv2/core/array_helpers.hpp" #endif // OPENCV_CORE_MAT_HPP diff --git a/modules/core/include/opencv2/core/mat.inl.hpp b/modules/core/include/opencv2/core/mat.inl.hpp index 649ebd265726..4bc156abd274 100644 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@ -143,95 +143,104 @@ CV__DEBUG_NS_BEGIN //////////////////////// Input/Output Arrays //////////////////////// -inline void _InputArray::init(int _flags, const void* _obj) -{ flags = _flags; obj = (void*)_obj; } - -inline void _InputArray::init(int _flags, const void* _obj, Size _sz) -{ flags = _flags; obj = (void*)_obj; sz = _sz; } inline void* _InputArray::getObj() const { return obj; } inline int _InputArray::getFlags() const { return flags; } inline Size _InputArray::getSz() const { return sz; } -inline _InputArray::_InputArray() { init(0 + NONE, 0); } -inline _InputArray::_InputArray(int _flags, void* _obj) { init(_flags, _obj); } -inline _InputArray::_InputArray(const Mat& m) { init(+MAT+ACCESS_READ, &m); } -inline _InputArray::_InputArray(const std::vector& vec) { init(+STD_VECTOR_MAT+ACCESS_READ, &vec); } -inline _InputArray::_InputArray(const UMat& m) { init(+UMAT+ACCESS_READ, &m); } -inline _InputArray::_InputArray(const std::vector& vec) { init(+STD_VECTOR_UMAT+ACCESS_READ, &vec); } +inline _InputArray::_InputArray(const Mat& m) +: _InputArray(+MAT+ACCESS_READ, &m) +{} -template inline +inline _InputArray::_InputArray(const std::vector& vec) +: _InputArray(+STD_VECTOR_MAT+ACCESS_READ, &vec) +{} + +inline _InputArray::_InputArray(const UMat& m) +: _InputArray(+UMAT+ACCESS_READ, &m) +{} + +inline _InputArray::_InputArray(const std::vector& vec) +: _InputArray(+STD_VECTOR_UMAT+ACCESS_READ, &vec) +{} + +template _InputArray::_InputArray(const std::vector<_Tp>& vec) -{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec); } +: _InputArray(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec) +{} -template inline +template _InputArray::_InputArray(const std::array<_Tp, _Nm>& arr) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_READ, arr.data(), Size(1, _Nm)); } +: _InputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_READ, arr.data(), Size(1, _Nm)) +{} -template inline +template _InputArray::_InputArray(const std::array& arr) -{ init(+STD_ARRAY_MAT + ACCESS_READ, arr.data(), Size(1, _Nm)); } +: _InputArray(+STD_ARRAY_MAT + ACCESS_READ, arr.data(), Size(1, _Nm)) +{} inline _InputArray::_InputArray(const std::vector& vec) -{ init(FIXED_TYPE + STD_BOOL_VECTOR + traits::Type::value + ACCESS_READ, &vec); } +: _InputArray(FIXED_TYPE + STD_BOOL_VECTOR + traits::Type::value + ACCESS_READ, &vec) +{} -template inline +template _InputArray::_InputArray(const std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec); } +: _InputArray(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec) +{} -template inline +template _InputArray::_InputArray(const std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_READ, &vec); } +: _InputArray(FIXED_TYPE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_READ, &vec) +{} -template inline +template _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_READ, &mtx, Size(n, m)); } +: _InputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_READ, &mtx, Size(n, m)) +{} -template inline +template _InputArray::_InputArray(const _Tp* vec, int n) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_READ, vec, Size(n, 1)); } +: _InputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_READ, vec, Size(n, 1)) +{} -template inline +template _InputArray::_InputArray(const Mat_<_Tp>& m) -{ init(FIXED_TYPE + MAT + traits::Type<_Tp>::value + ACCESS_READ, &m); } +: _InputArray(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)); } +: _InputArray(FIXED_TYPE + FIXED_SIZE + MATX + CV_64F + ACCESS_READ, &val, Size(1,1)) +{} inline _InputArray::_InputArray(const cuda::GpuMat& d_mat) -{ init(+CUDA_GPU_MAT + ACCESS_READ, &d_mat); } +: _InputArray(+CUDA_GPU_MAT + ACCESS_READ, &d_mat) +{} inline _InputArray::_InputArray(const std::vector& d_mat) -{ init(+STD_VECTOR_CUDA_GPU_MAT + ACCESS_READ, &d_mat);} +: _InputArray(+STD_VECTOR_CUDA_GPU_MAT + ACCESS_READ, &d_mat) +{} inline _InputArray::_InputArray(const ogl::Buffer& buf) -{ init(+OPENGL_BUFFER + ACCESS_READ, &buf); } +: _InputArray(+OPENGL_BUFFER + ACCESS_READ, &buf) +{} inline _InputArray::_InputArray(const cuda::HostMem& cuda_mem) -{ init(+CUDA_HOST_MEM + ACCESS_READ, &cuda_mem); } +: _InputArray(+CUDA_HOST_MEM + ACCESS_READ, &cuda_mem) +{} -template inline +template _InputArray _InputArray::rawIn(const std::vector<_Tp>& vec) { - _InputArray v; - v.flags = _InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_READ; - v.obj = (void*)&vec; - return v; + return _InputArray(_InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_READ, &vec); } -template inline +template _InputArray _InputArray::rawIn(const std::array<_Tp, _Nm>& arr) { - _InputArray v; - v.flags = FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_READ; - v.obj = (void*)arr.data(); - v.sz = Size(1, _Nm); - return v; + return _InputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_READ, arr.data(), Size(1, _Nm)); } -inline _InputArray::~_InputArray() {} - inline Mat _InputArray::getMat(int i) const { if( kind() == MAT && i < 0 ) @@ -253,128 +262,154 @@ inline bool _InputArray::isGpuMatVector() const { return kind() == _InputArray:: //////////////////////////////////////////////////////////////////////////////////////// -inline _OutputArray::_OutputArray() { init(+NONE + ACCESS_WRITE, 0); } -inline _OutputArray::_OutputArray(int _flags, void* _obj) { init(_flags + ACCESS_WRITE, _obj); } -inline _OutputArray::_OutputArray(Mat& m) { init(+MAT+ACCESS_WRITE, &m); } -inline _OutputArray::_OutputArray(std::vector& vec) { init(+STD_VECTOR_MAT + ACCESS_WRITE, &vec); } -inline _OutputArray::_OutputArray(UMat& m) { init(+UMAT + ACCESS_WRITE, &m); } -inline _OutputArray::_OutputArray(std::vector& vec) { init(+STD_VECTOR_UMAT + ACCESS_WRITE, &vec); } +inline _OutputArray::_OutputArray(Mat& m) +: _OutputArray(+MAT+ACCESS_WRITE, &m) +{} +inline _OutputArray::_OutputArray(std::vector& vec) +: _OutputArray(+STD_VECTOR_MAT + ACCESS_WRITE, &vec) +{} +inline _OutputArray::_OutputArray(UMat& m) +: _OutputArray(+UMAT + ACCESS_WRITE, &m) +{} +inline _OutputArray::_OutputArray(std::vector& vec) +: _OutputArray(+STD_VECTOR_UMAT + ACCESS_WRITE, &vec) +{} -template inline +template _OutputArray::_OutputArray(std::vector<_Tp>& vec) -{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } +: _OutputArray(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec) +{} -template inline +template _OutputArray::_OutputArray(std::array<_Tp, _Nm>& arr) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, arr.data(), Size(1, _Nm)) +{} -template inline +template _OutputArray::_OutputArray(std::array& arr) -{ init(+STD_ARRAY_MAT + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } +: _OutputArray(+STD_ARRAY_MAT + ACCESS_WRITE, arr.data(), Size(1, _Nm)) +{} -template inline +template _OutputArray::_OutputArray(std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } +: _OutputArray(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec) +{} -template inline +template _OutputArray::_OutputArray(std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } +: _OutputArray(FIXED_TYPE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &vec) +{} -template inline +template _OutputArray::_OutputArray(Mat_<_Tp>& m) -{ init(FIXED_TYPE + MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &m); } +: _OutputArray(FIXED_TYPE + MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &m) +{} -template inline +template _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, &mtx, Size(n, m)); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, &mtx, Size(n, m)) +{} -template inline +template _OutputArray::_OutputArray(_Tp* vec, int n) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, vec, Size(n, 1)); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, vec, Size(n, 1)) +{} -template inline +template _OutputArray::_OutputArray(const std::vector<_Tp>& vec) -{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec) +{} -template inline +template _OutputArray::_OutputArray(const std::array<_Tp, _Nm>& arr) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, arr.data(), Size(1, _Nm)) +{} -template inline +template _OutputArray::_OutputArray(const std::array& arr) -{ init(FIXED_SIZE + STD_ARRAY_MAT + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } +: _OutputArray(FIXED_SIZE + STD_ARRAY_MAT + ACCESS_WRITE, arr.data(), Size(1, _Nm)) +{} -template inline +template _OutputArray::_OutputArray(const std::vector >& vec) -{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_WRITE, &vec) +{} -template inline +template _OutputArray::_OutputArray(const std::vector >& vec) -{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &vec); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &vec) +{} -template inline +template _OutputArray::_OutputArray(const Mat_<_Tp>& m) -{ init(FIXED_TYPE + FIXED_SIZE + MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &m); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + MAT + traits::Type<_Tp>::value + ACCESS_WRITE, &m) +{} -template inline +template _OutputArray::_OutputArray(const Matx<_Tp, m, n>& mtx) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, &mtx, Size(n, m)); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, &mtx, Size(n, m)) +{} -template inline +template _OutputArray::_OutputArray(const _Tp* vec, int n) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, vec, Size(n, 1)); } +: _OutputArray(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); } +: _OutputArray(+CUDA_GPU_MAT + ACCESS_WRITE, &d_mat) +{} inline _OutputArray::_OutputArray(std::vector& d_mat) -{ init(+STD_VECTOR_CUDA_GPU_MAT + ACCESS_WRITE, &d_mat);} +: _OutputArray(+STD_VECTOR_CUDA_GPU_MAT + ACCESS_WRITE, &d_mat) +{} inline _OutputArray::_OutputArray(ogl::Buffer& buf) -{ init(+OPENGL_BUFFER + ACCESS_WRITE, &buf); } +: _OutputArray(+OPENGL_BUFFER + ACCESS_WRITE, &buf) +{} inline _OutputArray::_OutputArray(cuda::HostMem& cuda_mem) -{ init(+CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); } +: _OutputArray(+CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem) +{} inline _OutputArray::_OutputArray(const Mat& m) -{ init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_WRITE, &m); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_WRITE, &m) +{} inline _OutputArray::_OutputArray(const std::vector& vec) -{ init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_WRITE, &vec); } +: _OutputArray(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_WRITE, &vec) +{} inline _OutputArray::_OutputArray(const UMat& m) -{ init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_WRITE, &m); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_WRITE, &m) +{} inline _OutputArray::_OutputArray(const std::vector& vec) -{ init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_WRITE, &vec); } +: _OutputArray(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_WRITE, &vec) +{} inline _OutputArray::_OutputArray(const cuda::GpuMat& d_mat) -{ init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_WRITE, &d_mat); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_WRITE, &d_mat) +{} inline _OutputArray::_OutputArray(const ogl::Buffer& buf) -{ init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_WRITE, &buf); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_WRITE, &buf) +{} inline _OutputArray::_OutputArray(const cuda::HostMem& cuda_mem) -{ init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem); } +: _OutputArray(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_WRITE, &cuda_mem) +{} template inline _OutputArray _OutputArray::rawOut(std::vector<_Tp>& vec) { - _OutputArray v; - v.flags = _InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_WRITE; - v.obj = (void*)&vec; - return v; + return _OutputArray(_InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_WRITE, &vec); } template inline _OutputArray _OutputArray::rawOut(std::array<_Tp, _Nm>& arr) { - _OutputArray v; - v.flags = FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE; - v.obj = (void*)arr.data(); - v.sz = Size(1, _Nm); - return v; + return _OutputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_WRITE, arr.data(), Size(1, _Nm)); } inline @@ -401,130 +436,157 @@ std::vector >& _OutputArray::getVecVecRef() const /////////////////////////////////////////////////////////////////////////////////////////// -inline _InputOutputArray::_InputOutputArray() { init(0+ACCESS_RW, 0); } -inline _InputOutputArray::_InputOutputArray(int _flags, void* _obj) { init(_flags+ACCESS_RW, _obj); } -inline _InputOutputArray::_InputOutputArray(Mat& m) { init(+MAT+ACCESS_RW, &m); } -inline _InputOutputArray::_InputOutputArray(std::vector& vec) { init(+STD_VECTOR_MAT+ACCESS_RW, &vec); } -inline _InputOutputArray::_InputOutputArray(UMat& m) { init(+UMAT+ACCESS_RW, &m); } -inline _InputOutputArray::_InputOutputArray(std::vector& vec) { init(+STD_VECTOR_UMAT+ACCESS_RW, &vec); } +inline _InputOutputArray::_InputOutputArray(Mat& m) +: _InputOutputArray(+MAT+ACCESS_RW, &m) +{} +inline _InputOutputArray::_InputOutputArray(std::vector& vec) +: _InputOutputArray(+STD_VECTOR_MAT+ACCESS_RW, &vec) +{} +inline _InputOutputArray::_InputOutputArray(UMat& m) +: _InputOutputArray(+UMAT+ACCESS_RW, &m) +{} +inline _InputOutputArray::_InputOutputArray(std::vector& vec) +: _InputOutputArray(+STD_VECTOR_UMAT+ACCESS_RW, &vec) +{} -template inline +template _InputOutputArray::_InputOutputArray(std::vector<_Tp>& vec) -{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec); } +: _InputOutputArray(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec) +{} -template inline +template _InputOutputArray::_InputOutputArray(std::array<_Tp, _Nm>& arr) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, arr.data(), Size(1, _Nm)); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, arr.data(), Size(1, _Nm)) +{} -template inline +template _InputOutputArray::_InputOutputArray(std::array& arr) -{ init(+STD_ARRAY_MAT + ACCESS_RW, arr.data(), Size(1, _Nm)); } +: _InputOutputArray(+STD_ARRAY_MAT + ACCESS_RW, arr.data(), Size(1, _Nm)) +{} -template inline +template _InputOutputArray::_InputOutputArray(std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec); } +: _InputOutputArray(FIXED_TYPE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec) +{} -template inline +template _InputOutputArray::_InputOutputArray(std::vector >& vec) -{ init(FIXED_TYPE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_RW, &vec); } +: _InputOutputArray(FIXED_TYPE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_RW, &vec) +{} -template inline +template _InputOutputArray::_InputOutputArray(Mat_<_Tp>& m) -{ init(FIXED_TYPE + MAT + traits::Type<_Tp>::value + ACCESS_RW, &m); } +: _InputOutputArray(FIXED_TYPE + MAT + traits::Type<_Tp>::value + ACCESS_RW, &m) +{} -template inline +template _InputOutputArray::_InputOutputArray(Matx<_Tp, m, n>& mtx) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, &mtx, Size(n, m)); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, &mtx, Size(n, m)) +{} -template inline +template _InputOutputArray::_InputOutputArray(_Tp* vec, int n) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, vec, Size(n, 1)); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, vec, Size(n, 1)) +{} -template inline +template _InputOutputArray::_InputOutputArray(const std::vector<_Tp>& vec) -{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec) +{} -template inline +template _InputOutputArray::_InputOutputArray(const std::array<_Tp, _Nm>& arr) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, arr.data(), Size(1, _Nm)); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, arr.data(), Size(1, _Nm)) +{} -template inline +template _InputOutputArray::_InputOutputArray(const std::array& arr) -{ init(FIXED_SIZE + STD_ARRAY_MAT + ACCESS_RW, arr.data(), Size(1, _Nm)); } +: _InputOutputArray(FIXED_SIZE + STD_ARRAY_MAT + ACCESS_RW, arr.data(), Size(1, _Nm)) +{} -template inline +template _InputOutputArray::_InputOutputArray(const std::vector >& vec) -{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_VECTOR + traits::Type<_Tp>::value + ACCESS_RW, &vec) +{} -template inline +template _InputOutputArray::_InputOutputArray(const std::vector >& vec) -{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_RW, &vec); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_MAT + traits::Type<_Tp>::value + ACCESS_RW, &vec) +{} -template inline +template _InputOutputArray::_InputOutputArray(const Mat_<_Tp>& m) -{ init(FIXED_TYPE + FIXED_SIZE + MAT + traits::Type<_Tp>::value + ACCESS_RW, &m); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + MAT + traits::Type<_Tp>::value + ACCESS_RW, &m) +{} -template inline +template _InputOutputArray::_InputOutputArray(const Matx<_Tp, m, n>& mtx) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, &mtx, Size(n, m)); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, &mtx, Size(n, m)) +{} -template inline +template _InputOutputArray::_InputOutputArray(const _Tp* vec, int n) -{ init(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, vec, Size(n, 1)); } +: _InputOutputArray(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); } +: _InputOutputArray(+CUDA_GPU_MAT + ACCESS_RW, &d_mat) +{} inline _InputOutputArray::_InputOutputArray(ogl::Buffer& buf) -{ init(+OPENGL_BUFFER + ACCESS_RW, &buf); } +: _InputOutputArray(+OPENGL_BUFFER + ACCESS_RW, &buf) +{} inline _InputOutputArray::_InputOutputArray(cuda::HostMem& cuda_mem) -{ init(+CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); } +: _InputOutputArray(+CUDA_HOST_MEM + ACCESS_RW, &cuda_mem) +{} inline _InputOutputArray::_InputOutputArray(const Mat& m) -{ init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_RW, &m); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_RW, &m) +{} inline _InputOutputArray::_InputOutputArray(const std::vector& vec) -{ init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_RW, &vec); } +: _InputOutputArray(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_RW, &vec) +{} inline _InputOutputArray::_InputOutputArray(const UMat& m) -{ init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_RW, &m); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_RW, &m) +{} inline _InputOutputArray::_InputOutputArray(const std::vector& vec) -{ init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_RW, &vec); } +: _InputOutputArray(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_RW, &vec) +{} inline _InputOutputArray::_InputOutputArray(const cuda::GpuMat& d_mat) -{ init(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_RW, &d_mat); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + CUDA_GPU_MAT + ACCESS_RW, &d_mat) +{} inline _InputOutputArray::_InputOutputArray(const std::vector& d_mat) -{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_CUDA_GPU_MAT + ACCESS_RW, &d_mat);} +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_CUDA_GPU_MAT + ACCESS_RW, &d_mat) +{} template<> inline _InputOutputArray::_InputOutputArray(std::vector& d_mat) -{ init(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_CUDA_GPU_MAT + ACCESS_RW, &d_mat);} +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + STD_VECTOR_CUDA_GPU_MAT + ACCESS_RW, &d_mat) +{} inline _InputOutputArray::_InputOutputArray(const ogl::Buffer& buf) -{ init(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_RW, &buf); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + OPENGL_BUFFER + ACCESS_RW, &buf) +{} inline _InputOutputArray::_InputOutputArray(const cuda::HostMem& cuda_mem) -{ init(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem); } +: _InputOutputArray(FIXED_TYPE + FIXED_SIZE + CUDA_HOST_MEM + ACCESS_RW, &cuda_mem) +{} template inline _InputOutputArray _InputOutputArray::rawInOut(std::vector<_Tp>& vec) { - _InputOutputArray v; - v.flags = _InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_RW; - v.obj = (void*)&vec; - return v; + return _InputOutputArray(_InputArray::FIXED_TYPE + _InputArray::STD_VECTOR + rawType<_Tp>() + ACCESS_RW, &vec); } template inline _InputOutputArray _InputOutputArray::rawInOut(std::array<_Tp, _Nm>& arr) { - _InputOutputArray v; - v.flags = FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW; - v.obj = (void*)arr.data(); - v.sz = Size(1, _Nm); - return v; + return _InputOutputArray(FIXED_TYPE + FIXED_SIZE + MATX + traits::Type<_Tp>::value + ACCESS_RW, arr.data(), Size(1, _Nm)); } diff --git a/modules/core/src/matrix_expressions.cpp b/modules/core/src/matrix_expressions.cpp index f42f7bff33c3..05bb76b0a062 100644 --- a/modules/core/src/matrix_expressions.cpp +++ b/modules/core/src/matrix_expressions.cpp @@ -1838,7 +1838,8 @@ _InputArray::_InputArray(const MatExpr& expr) swap(const_cast(expr), result_expr); } CV_Assert(isIdentity(expr)); - init(FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_READ, &expr.a); + flags = FIXED_TYPE + FIXED_SIZE + MAT + ACCESS_READ; + obj = const_cast(&expr.a); } } // cv:: diff --git a/modules/core/src/matrix_wrap.cpp b/modules/core/src/matrix_wrap.cpp index b96dc4077612..123f89d8eaa1 100644 --- a/modules/core/src/matrix_wrap.cpp +++ b/modules/core/src/matrix_wrap.cpp @@ -38,53 +38,15 @@ Mat _InputArray::getMat_(int i) const return Mat(sz, flags, obj); } - if( k == STD_VECTOR ) - { - CV_Assert( i < 0 ); - int t = CV_MAT_TYPE(flags); - const std::vector& v = *(const std::vector*)obj; - int v_size = size().width; - - return !v.empty() ? Mat(1, &v_size, t, (void*)&v[0]) : Mat(); - } - - if( k == STD_BOOL_VECTOR ) - { - CV_Assert( i < 0 ); - int t = CV_8U; - const std::vector& v = *(const std::vector*)obj; - int j, n = (int)v.size(); - if( n == 0 ) - return Mat(); - Mat m(1, &n, t); - uchar* dst = m.data; - for( j = 0; j < n; j++ ) - dst[j] = (uchar)v[j]; - return m; + if (k == STD_VECTOR || k == STD_BOOL_VECTOR || k == STD_VECTOR_VECTOR || + k == STD_VECTOR_MAT || k == STD_VECTOR_UMAT) { + CV_Assert(ops != nullptr); + return ops->getMat_(*this, i); } if( k == NONE ) return Mat(); - if( k == STD_VECTOR_VECTOR ) - { - int t = type(i); - const std::vector >& vv = *(const std::vector >*)obj; - CV_Assert( 0 <= i && i < (int)vv.size() ); - const std::vector& v = vv[i]; - int v_size = size(i).width; - - return !v.empty() ? Mat(1, &v_size, t, (void*)&v[0]) : Mat(); - } - - if( k == STD_VECTOR_MAT ) - { - const std::vector& v = *(const std::vector*)obj; - CV_Assert( 0 <= i && i < (int)v.size() ); - - return v[i]; - } - if( k == STD_ARRAY_MAT ) { const Mat* v = (const Mat*)obj; @@ -92,15 +54,6 @@ Mat _InputArray::getMat_(int i) const return v[i]; } - - if( k == STD_VECTOR_UMAT ) - { - const std::vector& v = *(const std::vector*)obj; - CV_Assert( 0 <= i && i < (int)v.size() ); - - return v[i].getMat(accessFlags); - } - if( k == OPENGL_BUFFER ) { CV_Assert( i < 0 ); @@ -140,10 +93,8 @@ UMat _InputArray::getUMat(int i) const if( k == STD_VECTOR_UMAT ) { - const std::vector& v = *(const std::vector*)obj; - CV_Assert( 0 <= i && i < (int)v.size() ); - - return v[i]; + CV_Assert(ops != nullptr); + return ops->getUMat(*this, i); } if( k == MAT ) @@ -160,7 +111,6 @@ UMat _InputArray::getUMat(int i) const void _InputArray::getMatVector(std::vector& mv) const { _InputArray::KindFlag k = kind(); - AccessFlag accessFlags = flags & ACCESS_MASK; if( k == MAT ) { @@ -185,17 +135,11 @@ void _InputArray::getMatVector(std::vector& mv) const return; } - if( k == STD_VECTOR ) - { - const std::vector& v = *(const std::vector*)obj; - - size_t n = size().width, esz = CV_ELEM_SIZE(flags); - int t = CV_MAT_DEPTH(flags), cn = CV_MAT_CN(flags); - mv.resize(n); - - for( size_t i = 0; i < n; i++ ) - mv[i] = Mat(1, cn, t, (void*)(&v[0] + esz*i)); - return; + if (k == STD_VECTOR || k == STD_VECTOR_VECTOR || k == STD_VECTOR_MAT || + k == STD_VECTOR_UMAT) { + CV_Assert(ops != nullptr); + mv = ops->getMatVector(*this); + return; } if( k == NONE ) @@ -204,32 +148,6 @@ void _InputArray::getMatVector(std::vector& mv) const return; } - if( k == STD_VECTOR_VECTOR ) - { - const std::vector >& vv = *(const std::vector >*)obj; - int n = (int)vv.size(); - int t = CV_MAT_TYPE(flags); - mv.resize(n); - - for( int i = 0; i < n; i++ ) - { - const std::vector& v = vv[i]; - mv[i] = Mat(size(i), t, (void*)&v[0]); - } - return; - } - - if( k == STD_VECTOR_MAT ) - { - const std::vector& v = *(const std::vector*)obj; - size_t n = v.size(); - mv.resize(n); - - for( size_t i = 0; i < n; i++ ) - mv[i] = v[i]; - return; - } - if( k == STD_ARRAY_MAT ) { const Mat* v = (const Mat*)obj; @@ -241,17 +159,6 @@ void _InputArray::getMatVector(std::vector& mv) const return; } - if( k == STD_VECTOR_UMAT ) - { - const std::vector& v = *(const std::vector*)obj; - size_t n = v.size(); - mv.resize(n); - - for( size_t i = 0; i < n; i++ ) - mv[i] = v[i].getMat(accessFlags); - return; - } - CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); } @@ -266,15 +173,10 @@ void _InputArray::getUMatVector(std::vector& umv) const return; } - if( k == STD_VECTOR_MAT ) - { - const std::vector& v = *(const std::vector*)obj; - size_t n = v.size(); - umv.resize(n); - - for( size_t i = 0; i < n; i++ ) - umv[i] = v[i].getUMat(accessFlags); - return; + if (k == STD_VECTOR_MAT || k == STD_VECTOR_UMAT) { + CV_Assert(ops != nullptr); + umv = ops->getUMatVector(*this); + return; } if( k == STD_ARRAY_MAT ) @@ -287,18 +189,6 @@ void _InputArray::getUMatVector(std::vector& umv) const umv[i] = v[i].getUMat(accessFlags); return; } - - if( k == STD_VECTOR_UMAT ) - { - const std::vector& v = *(const std::vector*)obj; - size_t n = v.size(); - umv.resize(n); - - for( size_t i = 0; i < n; i++ ) - umv[i] = v[i]; - return; - } - if( k == UMAT ) { UMat& v = *(UMat*)obj; @@ -397,17 +287,13 @@ Size _InputArray::size(int i) const if( k == MAT ) { CV_Assert( i < 0 ); - const Mat* m = (const Mat*)obj; - CV_Assert(m->dims <= 2); - return Size(m->cols, m->rows); + return ((const Mat*)obj)->size(); } if( k == UMAT ) { CV_Assert( i < 0 ); - const UMat* m = (const UMat*)obj; - CV_Assert(m->dims <= 2); - return Size(m->cols, m->rows); + return ((const UMat*)obj)->size(); } if (k == MATX) @@ -415,48 +301,16 @@ Size _InputArray::size(int i) const CV_Assert( i < 0 ); return sz; } - - if( k == STD_VECTOR ) - { - CV_Assert( i < 0 ); - const std::vector& v = *(const std::vector*)obj; - const std::vector& iv = *(const std::vector*)obj; - size_t szb = v.size(), szi = iv.size(); - return szb == szi ? Size((int)szb, 1) : Size((int)(szb/CV_ELEM_SIZE(flags)), 1); - } - - if( k == STD_BOOL_VECTOR ) - { - CV_Assert( i < 0 ); - const std::vector& v = *(const std::vector*)obj; - return Size((int)v.size(), 1); + if (k == STD_VECTOR || k == STD_BOOL_VECTOR || k == STD_VECTOR_VECTOR || + k == STD_VECTOR_MAT || k == STD_VECTOR_UMAT || + k == STD_VECTOR_CUDA_GPU_MAT) { + CV_Assert(ops != nullptr); + return ops->size(*this, i); } if( k == NONE ) return Size(); - if( k == STD_VECTOR_VECTOR ) - { - const std::vector >& vv = *(const std::vector >*)obj; - if( i < 0 ) - return vv.empty() ? Size() : Size((int)vv.size(), 1); - CV_Assert( i < (int)vv.size() ); - const std::vector >& ivv = *(const std::vector >*)obj; - - size_t szb = vv[i].size(), szi = ivv[i].size(); - return szb == szi ? Size((int)szb, 1) : Size((int)(szb/CV_ELEM_SIZE(flags)), 1); - } - - if( k == STD_VECTOR_MAT ) - { - const std::vector& vv = *(const std::vector*)obj; - if( i < 0 ) - return vv.empty() ? Size() : Size((int)vv.size(), 1); - CV_Assert( i < (int)vv.size() ); - - return vv[i].size(); - } - if( k == STD_ARRAY_MAT ) { const Mat* vv = (const Mat*)obj; @@ -467,29 +321,6 @@ Size _InputArray::size(int i) const return vv[i].size(); } - if (k == STD_VECTOR_CUDA_GPU_MAT) - { -#ifdef HAVE_CUDA - const std::vector& vv = *(const std::vector*)obj; - if (i < 0) - return vv.empty() ? Size() : Size((int)vv.size(), 1); - CV_Assert(i < (int)vv.size()); - return vv[i].size(); -#else - CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)"); -#endif - } - - if( k == STD_VECTOR_UMAT ) - { - const std::vector& vv = *(const std::vector*)obj; - if( i < 0 ) - return vv.empty() ? Size() : Size((int)vv.size(), 1); - CV_Assert( i < (int)vv.size() ); - - return vv[i].size(); - } - if( k == OPENGL_BUFFER ) { CV_Assert( i < 0 ); @@ -519,6 +350,9 @@ int _InputArray::sizend(int* arrsz, int i) const int j, d = 0; _InputArray::KindFlag k = kind(); + const bool is_nd_vector = (k == STD_VECTOR_MAT || k == STD_VECTOR_UMAT) && (i >= 0); + const bool is_1d_vector = k == STD_VECTOR && i < 0; + if( k == NONE ) ; else if( k == MAT ) @@ -539,15 +373,10 @@ int _InputArray::sizend(int* arrsz, int i) const for(j = 0; j < d; j++) arrsz[j] = m.size.p[j]; } - else if( k == STD_VECTOR_MAT && i >= 0 ) + else if( is_nd_vector || is_1d_vector ) { - const std::vector& vv = *(const std::vector*)obj; - CV_Assert( i < (int)vv.size() ); - const Mat& m = vv[i]; - d = m.dims; - if(arrsz) - for(j = 0; j < d; j++) - arrsz[j] = m.size.p[j]; + CV_Assert(ops != nullptr); + return ops->sizend(*this, arrsz, i); } else if( k == STD_ARRAY_MAT && i >= 0 ) { @@ -559,25 +388,6 @@ int _InputArray::sizend(int* arrsz, int i) const for(j = 0; j < d; j++) arrsz[j] = m.size.p[j]; } - else if( k == STD_VECTOR_UMAT && i >= 0 ) - { - const std::vector& vv = *(const std::vector*)obj; - CV_Assert( i < (int)vv.size() ); - const UMat& 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 && i < 0 ) - { - Size sz2d = size(); - d = 1; - if(arrsz) - { - arrsz[0] = sz2d.width; - } - } else { CV_CheckLE(dims(i), 2, "Not supported"); @@ -595,23 +405,14 @@ int _InputArray::sizend(int* arrsz, int i) const bool _InputArray::empty(int i) const { - _InputArray::KindFlag k = kind(); if (i >= 0) { - if (k == STD_VECTOR_MAT) { - auto mv = reinterpret_cast*>(obj); - CV_Assert((size_t)i < mv->size()); - return mv->at(i).empty(); - } - else if (k == STD_VECTOR_MAT) { - auto umv = reinterpret_cast*>(obj); - CV_Assert((size_t)i < umv->size()); - return umv->at(i).empty(); - } - else if (k == STD_VECTOR_VECTOR) { - auto vv = reinterpret_cast >*>(obj); - CV_Assert((size_t)i < vv->size()); - return vv->at(i).empty(); - } else { + switch (_InputArray::KindFlag k = kind(); k) { + case STD_VECTOR_MAT: + case STD_VECTOR_UMAT: + case STD_VECTOR_VECTOR: + CV_Assert(ops != nullptr); + return ops->empty(*this, i); + default: CV_Error(Error::StsNotImplemented, ""); } } @@ -693,23 +494,9 @@ int _InputArray::dims(int i) const if( k == NONE ) return 0; - if( k == STD_VECTOR_VECTOR ) - { - const std::vector >& vv = *(const std::vector >*)obj; - if( i < 0 ) - return 1; - CV_Assert( i < (int)vv.size() ); - return 2; - } - - if( k == STD_VECTOR_MAT ) - { - const std::vector& vv = *(const std::vector*)obj; - if( i < 0 ) - return 1; - CV_Assert( i < (int)vv.size() ); - - return vv[i].dims; + if (k == STD_VECTOR_VECTOR || k == STD_VECTOR_MAT || k == STD_VECTOR_UMAT) { + CV_Assert(ops != nullptr); + return ops->dims(*this, i); } if( k == STD_ARRAY_MAT ) @@ -722,16 +509,6 @@ int _InputArray::dims(int i) const return vv[i].dims; } - if( k == STD_VECTOR_UMAT ) - { - const std::vector& vv = *(const std::vector*)obj; - if( i < 0 ) - return 1; - CV_Assert( i < (int)vv.size() ); - - return vv[i].dims; - } - if( k == OPENGL_BUFFER ) { CV_Assert( i < 0 ); @@ -769,14 +546,10 @@ size_t _InputArray::total(int i) const return ((const UMat*)obj)->total(); } - if( k == STD_VECTOR_MAT ) + if( k == STD_VECTOR_MAT || k == STD_VECTOR_UMAT ) { - const std::vector& vv = *(const std::vector*)obj; - if( i < 0 ) - return vv.size(); - - CV_Assert( i < (int)vv.size() ); - return vv[i].total(); + CV_Assert(ops != nullptr); + return ops->total(*this, i); } if( k == STD_ARRAY_MAT ) @@ -789,16 +562,6 @@ size_t _InputArray::total(int i) const return vv[i].total(); } - if( k == STD_VECTOR_UMAT ) - { - const std::vector& vv = *(const std::vector*)obj; - if( i < 0 ) - return vv.size(); - - CV_Assert( i < (int)vv.size() ); - return vv[i].total(); - } - return size(i).area(); } @@ -818,28 +581,9 @@ int _InputArray::type(int i) const if( k == NONE ) return -1; - if( k == STD_VECTOR_UMAT ) - { - const std::vector& vv = *(const std::vector*)obj; - if( vv.empty() ) - { - CV_Assert((flags & FIXED_TYPE) != 0); - return CV_MAT_TYPE(flags); - } - CV_Assert( i < (int)vv.size() ); - return vv[i >= 0 ? i : 0].type(); - } - - if( k == STD_VECTOR_MAT ) - { - const std::vector& vv = *(const std::vector*)obj; - if( vv.empty() ) - { - CV_Assert((flags & FIXED_TYPE) != 0); - return CV_MAT_TYPE(flags); - } - CV_Assert( i < (int)vv.size() ); - return vv[i >= 0 ? i : 0].type(); + if (k == STD_VECTOR_UMAT || k == STD_VECTOR_MAT || k == STD_VECTOR_CUDA_GPU_MAT) { + CV_Assert(ops != nullptr); + return ops->type(*this, i); } if( k == STD_ARRAY_MAT ) @@ -854,22 +598,6 @@ int _InputArray::type(int i) const return vv[i >= 0 ? i : 0].type(); } - if (k == STD_VECTOR_CUDA_GPU_MAT) - { -#ifdef HAVE_CUDA - const std::vector& vv = *(const std::vector*)obj; - if (vv.empty()) - { - CV_Assert((flags & FIXED_TYPE) != 0); - return CV_MAT_TYPE(flags); - } - CV_Assert(i < (int)vv.size()); - return vv[i >= 0 ? i : 0].type(); -#else - CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)"); -#endif - } - if( k == OPENGL_BUFFER ) return ((const ogl::Buffer*)obj)->type(); @@ -905,56 +633,26 @@ bool _InputArray::empty() const if (k == MATX) return false; - if( k == STD_VECTOR ) - { - const std::vector& v = *(const std::vector*)obj; - return v.empty(); - } - - if( k == STD_BOOL_VECTOR ) - { - const std::vector& v = *(const std::vector*)obj; - return v.empty(); + if (k == STD_VECTOR || k == STD_BOOL_VECTOR || k == STD_VECTOR_VECTOR || k == STD_VECTOR_MAT || + k == STD_VECTOR_UMAT || k == STD_VECTOR_CUDA_GPU_MAT) { + CV_Assert(ops != nullptr); + return ops->empty(*this); } if( k == NONE ) return true; - if( k == STD_VECTOR_VECTOR ) - { - const std::vector >& vv = *(const std::vector >*)obj; - return vv.empty(); - } - - if( k == STD_VECTOR_MAT ) - { - const std::vector& vv = *(const std::vector*)obj; - return vv.empty(); - } - if( k == STD_ARRAY_MAT ) { return sz.height == 0; } - if( k == STD_VECTOR_UMAT ) - { - const std::vector& vv = *(const std::vector*)obj; - return vv.empty(); - } - if( k == OPENGL_BUFFER ) return ((const ogl::Buffer*)obj)->empty(); if( k == CUDA_GPU_MAT ) return ((const cuda::GpuMat*)obj)->empty(); - if (k == STD_VECTOR_CUDA_GPU_MAT) - { - const std::vector& vv = *(const std::vector*)obj; - return vv.empty(); - } - if( k == CUDA_HOST_MEM ) return ((const cuda::HostMem*)obj)->empty(); @@ -975,11 +673,10 @@ bool _InputArray::isContinuous(int i) const k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR ) return true; - if( k == STD_VECTOR_MAT ) + if( k == STD_VECTOR_MAT || k == STD_VECTOR_UMAT ) { - const std::vector& vv = *(const std::vector*)obj; - CV_Assert(i >= 0 && (size_t)i < vv.size()); - return vv[i].isContinuous(); + CV_Assert(ops != nullptr); + return ops->isContinuous(*this, i); } if( k == STD_ARRAY_MAT ) @@ -989,13 +686,6 @@ bool _InputArray::isContinuous(int i) const return vv[i].isContinuous(); } - if( k == STD_VECTOR_UMAT ) - { - const std::vector& vv = *(const std::vector*)obj; - CV_Assert(i >= 0 && (size_t)i < vv.size()); - return vv[i].isContinuous(); - } - if( k == CUDA_GPU_MAT ) return i < 0 ? ((const cuda::GpuMat*)obj)->isContinuous() : true; @@ -1016,11 +706,10 @@ bool _InputArray::isSubmatrix(int i) const k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR ) return false; - if( k == STD_VECTOR_MAT ) + if( k == STD_VECTOR_MAT || k == STD_VECTOR_UMAT ) { - const std::vector& vv = *(const std::vector*)obj; - CV_Assert(i >= 0 && (size_t)i < vv.size()); - return vv[i].isSubmatrix(); + CV_Assert(ops != nullptr); + return ops->isSubmatrix(*this, i); } if( k == STD_ARRAY_MAT ) @@ -1030,13 +719,6 @@ bool _InputArray::isSubmatrix(int i) const return vv[i].isSubmatrix(); } - if( k == STD_VECTOR_UMAT ) - { - const std::vector& vv = *(const std::vector*)obj; - CV_Assert(i >= 0 && (size_t)i < vv.size()); - return vv[i].isSubmatrix(); - } - CV_Error(cv::Error::StsNotImplemented, ""); } @@ -1061,12 +743,10 @@ size_t _InputArray::offset(int i) const k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR ) return 0; - if( k == STD_VECTOR_MAT ) + if( k == STD_VECTOR_MAT || k == STD_VECTOR_UMAT || k == STD_VECTOR_CUDA_GPU_MAT ) { - const std::vector& vv = *(const std::vector*)obj; - CV_Assert( i >= 0 && i < (int)vv.size() ); - - return (size_t)(vv[i].ptr() - vv[i].datastart); + CV_Assert(ops != nullptr); + return ops->offset(*this, i); } if( k == STD_ARRAY_MAT ) @@ -1076,13 +756,6 @@ size_t _InputArray::offset(int i) const return (size_t)(vv[i].ptr() - vv[i].datastart); } - if( k == STD_VECTOR_UMAT ) - { - const std::vector& vv = *(const std::vector*)obj; - CV_Assert(i >= 0 && (size_t)i < vv.size()); - return vv[i].offset; - } - if( k == CUDA_GPU_MAT ) { CV_Assert( i < 0 ); @@ -1090,13 +763,6 @@ size_t _InputArray::offset(int i) const return (size_t)(m->data - m->datastart); } - if (k == STD_VECTOR_CUDA_GPU_MAT) - { - const std::vector& vv = *(const std::vector*)obj; - CV_Assert(i >= 0 && (size_t)i < vv.size()); - return (size_t)(vv[i].data - vv[i].datastart); - } - CV_Error(Error::StsNotImplemented, ""); } @@ -1120,11 +786,10 @@ size_t _InputArray::step(int i) const k == NONE || k == STD_VECTOR_VECTOR || k == STD_BOOL_VECTOR ) return 0; - if( k == STD_VECTOR_MAT ) + if( k == STD_VECTOR_MAT || k == STD_VECTOR_UMAT || k == STD_VECTOR_CUDA_GPU_MAT ) { - const std::vector& vv = *(const std::vector*)obj; - CV_Assert( i >= 0 && i < (int)vv.size() ); - return vv[i].step; + CV_Assert(ops != nullptr); + return ops->step(*this, i); } if( k == STD_ARRAY_MAT ) @@ -1134,24 +799,11 @@ size_t _InputArray::step(int i) const return vv[i].step; } - if( k == STD_VECTOR_UMAT ) - { - const std::vector& vv = *(const std::vector*)obj; - CV_Assert(i >= 0 && (size_t)i < vv.size()); - return vv[i].step; - } - if( k == CUDA_GPU_MAT ) { CV_Assert( i < 0 ); return ((const cuda::GpuMat*)obj)->step; } - if (k == STD_VECTOR_CUDA_GPU_MAT) - { - const std::vector& vv = *(const std::vector*)obj; - CV_Assert(i >= 0 && (size_t)i < vv.size()); - return vv[i].step; - } CV_Error(Error::StsNotImplemented, ""); } @@ -1412,107 +1064,10 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i, return; } - if( k == STD_VECTOR || k == STD_VECTOR_VECTOR ) + if( k == STD_VECTOR || k == STD_VECTOR_VECTOR || k == STD_VECTOR_MAT || k == STD_VECTOR_UMAT ) { - CV_Assert( d <= 2 && (size0 == 1 || size1 == 1 || size0*size1 == 0) ); - size_t len = size0*size1 > 0 ? size0 + size1 - 1 : 0; - std::vector* v = (std::vector*)obj; - - if( k == STD_VECTOR_VECTOR ) - { - std::vector >& vv = *(std::vector >*)obj; - if( i < 0 ) - { - CV_Assert(!fixedSize() || len == vv.size()); - vv.resize(len); - return; - } - CV_Assert( i < (int)vv.size() ); - v = &vv[i]; - } - else - CV_Assert( i < 0 ); - - int type0 = CV_MAT_TYPE(flags); - CV_Assert( mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0) ); - - int esz = CV_ELEM_SIZE(type0); - CV_Assert(!fixedSize() || len == ((std::vector*)v)->size() / esz); - switch( esz ) - { - case 1: - ((std::vector*)v)->resize(len); - break; - case 2: - ((std::vector*)v)->resize(len); - break; - case 3: - ((std::vector*)v)->resize(len); - break; - case 4: - ((std::vector*)v)->resize(len); - break; - case 6: - ((std::vector*)v)->resize(len); - break; - case 8: - ((std::vector*)v)->resize(len); - break; - case 12: - ((std::vector*)v)->resize(len); - break; - case 16: - ((std::vector*)v)->resize(len); - break; - case 20: - ((std::vector >*)v)->resize(len); - break; - case 24: - ((std::vector*)v)->resize(len); - break; - case 28: - ((std::vector >*)v)->resize(len); - break; - case 32: - ((std::vector*)v)->resize(len); - break; - case 36: - ((std::vector >*)v)->resize(len); - break; - case 40: - ((std::vector >*)v)->resize(len); - break; - case 44: - ((std::vector >*)v)->resize(len); - break; - case 48: - ((std::vector >*)v)->resize(len); - break; - case 52: - ((std::vector >*)v)->resize(len); - break; - case 56: - ((std::vector >*)v)->resize(len); - break; - case 60: - ((std::vector >*)v)->resize(len); - break; - case 64: - ((std::vector >*)v)->resize(len); - break; - case 128: - ((std::vector >*)v)->resize(len); - break; - case 256: - ((std::vector >*)v)->resize(len); - break; - case 512: - ((std::vector >*)v)->resize(len); - break; - default: - CV_Error_(cv::Error::StsBadArg, ("Vectors with element size %d are not supported. Please, modify OutputArray::create()\n", esz)); - } - return; + CV_Assert(ops != nullptr); + return ops->create(*this, d, sizes, mtype, i, allowTransposed, fixedDepthMask); } if( k == NONE ) @@ -1520,65 +1075,6 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i, CV_Error(cv::Error::StsNullPtr, "create() called for the missing output array" ); } - if( k == STD_VECTOR_MAT ) - { - std::vector& v = *(std::vector*)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 = v.size(); - - CV_Assert(!fixedSize() || len == len0); - v.resize(len); - 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 < (int)v.size() ); - 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_ARRAY_MAT ) { Mat* v = (Mat*)obj; @@ -1638,73 +1134,6 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i, return; } - if( k == STD_VECTOR_UMAT ) - { - std::vector& v = *(std::vector*)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 = v.size(); - - CV_Assert(!fixedSize() || len == len0); - v.resize(len); - 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 < (int)v.size() ); - UMat& m = v[i]; - - if( allowTransposed ) - { - if( !m.isContinuous() ) - { - CV_Assert(!fixedType() && !fixedSize()); - m.release(); - } - - if( d == 2 && m.dims == 2 && m.u && - 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 == CUDA_GPU_MAT || k == CUDA_HOST_MEM) && d <= 2 && - i < 0 && !allowTransposed && fixedDepthMask == 0) - { - create((d < 2 ? 1 : sizes[0]), (d < 1 ? 1 : sizes[d > 1]), - mtype, i, allowTransposed, fixedDepthMask); - return; - } - CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); } @@ -1857,38 +1286,13 @@ void _OutputArray::release() const if( k == NONE ) return; - if( k == STD_VECTOR ) - { - create(Size(), CV_MAT_TYPE(flags)); - return; - } - - if( k == STD_VECTOR_VECTOR ) - { - ((std::vector >*)obj)->clear(); - return; - } - - if( k == STD_VECTOR_MAT ) + if( k == STD_VECTOR || k == STD_VECTOR_VECTOR || k == STD_VECTOR_MAT || k == STD_VECTOR_UMAT || + k == STD_VECTOR_CUDA_GPU_MAT ) { - ((std::vector*)obj)->clear(); - return; + CV_Assert(ops != nullptr); + return ops->release(*this); } - if( k == STD_VECTOR_UMAT ) - { - ((std::vector*)obj)->clear(); - return; - } - if (k == STD_VECTOR_CUDA_GPU_MAT) - { -#ifdef HAVE_CUDA - ((std::vector*)obj)->clear(); - return; -#else - CV_Error(Error::StsNotImplemented, "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)"); -#endif - } CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); } @@ -1924,9 +1328,8 @@ Mat& _OutputArray::getMatRef(int i) const if( k == STD_VECTOR_MAT ) { - std::vector& v = *(std::vector*)obj; - CV_Assert( i < (int)v.size() ); - return v[i]; + CV_Assert(ops != nullptr); + return ops->getMatRef(*this, i); } else { @@ -1947,9 +1350,8 @@ UMat& _OutputArray::getUMatRef(int i) const else { CV_Assert( k == STD_VECTOR_UMAT ); - std::vector& v = *(std::vector*)obj; - CV_Assert( i < (int)v.size() ); - return v[i]; + CV_Assert(ops != nullptr); + return ops->getUMatRef(*this, i); } } @@ -2131,33 +1533,10 @@ void _OutputArray::move(Mat& m) const void _OutputArray::assign(const std::vector& v) const { _InputArray::KindFlag k = kind(); - if (k == STD_VECTOR_UMAT) + if (k == STD_VECTOR_UMAT || k == STD_VECTOR_MAT) { - std::vector& this_v = *(std::vector*)obj; - CV_Assert(this_v.size() == v.size()); - - for (size_t i = 0; i < v.size(); i++) - { - const UMat& m = v[i]; - UMat& this_m = this_v[i]; - if (this_m.u != NULL && this_m.u == m.u) - continue; // same object (see dnn::Layer::forward_fallback) - m.copyTo(this_m); - } - } - else if (k == STD_VECTOR_MAT) - { - std::vector& this_v = *(std::vector*)obj; - CV_Assert(this_v.size() == v.size()); - - for (size_t i = 0; i < v.size(); i++) - { - const UMat& m = v[i]; - Mat& this_m = this_v[i]; - if (this_m.u != NULL && this_m.u == m.u) - continue; // same object (see dnn::Layer::forward_fallback) - m.copyTo(this_m); - } + CV_Assert(ops != nullptr); + ops->assign(*this, v); } else { @@ -2169,33 +1548,10 @@ void _OutputArray::assign(const std::vector& v) const void _OutputArray::assign(const std::vector& v) const { _InputArray::KindFlag k = kind(); - if (k == STD_VECTOR_UMAT) - { - std::vector& this_v = *(std::vector*)obj; - CV_Assert(this_v.size() == v.size()); - - for (size_t i = 0; i < v.size(); i++) - { - const Mat& m = v[i]; - UMat& this_m = this_v[i]; - if (this_m.u != NULL && this_m.u == m.u) - continue; // same object (see dnn::Layer::forward_fallback) - m.copyTo(this_m); - } - } - else if (k == STD_VECTOR_MAT) + if (k == STD_VECTOR_UMAT || k == STD_VECTOR_MAT) { - std::vector& this_v = *(std::vector*)obj; - CV_Assert(this_v.size() == v.size()); - - for (size_t i = 0; i < v.size(); i++) - { - const Mat& m = v[i]; - Mat& this_m = this_v[i]; - if (this_m.u != NULL && this_m.u == m.u) - continue; // same object (see dnn::Layer::forward_fallback) - m.copyTo(this_m); - } + CV_Assert(ops != nullptr); + ops->assign(*this, v); } else { @@ -2207,4 +1563,119 @@ void _OutputArray::assign(const std::vector& v) const static _InputOutputArray _none; InputOutputArray noArray() { return _none; } +template<> +[[gnu::visibility("default")]] Mat _ArrayOps>::getMat_(const _InputArray& self, const int i) const +{ + std::vector& v = get(self.getObj()); + CV_Assert(i < 0); + const int type = CV_MAT_TYPE(self.getFlags()); + const int width = static_cast(v.size()); + return v.empty() ? Mat() : Mat(1, &width, type, v.data()); +} + +[[noreturn]] static void noCudaError() { + CV_Error( + Error::StsNotImplemented, + "CUDA support is not enabled in this OpenCV build (missing HAVE_CUDA)"); +} + +template<> +[[gnu::visibility("default")]] Size _ArrayOps>::size(const _InputArray& self, const int i) const +{ + if constexpr (!have_cuda) { + noCudaError(); + } else { + const std::vector& v = get(self.getObj()); + if (i < 0) { + return v.empty() ? Size() : Size(static_cast(v.size()), 1); + } + + const auto index = static_cast(i); + CV_Assert(index < v.size()); + return v[index].size(); + } +} + +template<> +[[gnu::visibility("default")]] int _ArrayOps>::sizend(const _InputArray& self, int* const arraySize, const int i) const +{ + std::vector& v = get(self.getObj()); + CV_Assert(i < 0); + Size sz2d = Size(v.size(), 1); + if (arraySize != nullptr) { + arraySize[0] = sz2d.width; + } + + return 1; +} + +template<> +[[gnu::visibility("default")]] int _ArrayOps>::type(const _InputArray& self, const int i) const +{ + if constexpr (!have_cuda) { + noCudaError(); + } else { + std::vector& v = get(self.getObj()); + if (v.empty()) { + const int flags = self.getFlags(); + CV_Assert((flags & _InputArray::FIXED_TYPE) != 0); + return CV_MAT_TYPE(flags); + } + + CV_Assert(i < static_cast(v.size())); + return v[i >= 0 ? i : 0].type(); + } +} + +template<> +[[gnu::visibility("default")]] std::size_t _ArrayOps>::offset(const _InputArray& self, const std::size_t i) const +{ + const std::vector& v = get(self.getObj()); + CV_Assert(i < v.size()); + return static_cast(v[i].data - v[i].datastart); +} + +template<> +[[gnu::visibility("default")]] std::size_t _ArrayOps>::step(const _InputArray& self, const std::size_t i) const +{ + const std::vector& v = get(self.getObj()); + CV_Assert(i < v.size()); + return v[i].step; +} + +template<> +[[gnu::visibility("default")]] +void _ArrayOps>::create(const _OutputArray& arr, + const int d, + const int* const sizes, + int mtype, + const int i, + bool /*allowTransposed*/, + const _OutputArray::DepthMask fixedDepthMask) const +{ + std::vector& v = get(arr.getObj()); + const int size0 = d > 0 ? sizes[0] : 1; + const int size1 = d > 1 ? sizes[1] : 1; + CV_Assert(d <= 2); + CV_Assert(size0 == 1 || size1 == 1 || size0 * size1 == 0); + + const std::size_t len = size0 * size1 > 0 ? size0 + size1 - 1 : 0; + + CV_Assert(i < 0); + const int type0 = CV_MAT_TYPE(arr.getFlags()); + CV_Assert(mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && + ((1 << type0) & fixedDepthMask) != 0)); + v.resize(len); +} + +template<> +[[gnu::visibility("default")]] void _ArrayOps>::release(const _OutputArray& self) const +{ + if constexpr (!have_cuda) { + noCudaError(); + } else { + get(self.getObj()).clear(); + } +} + } // cv::