diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index 679b89aaa1..c6cfb78f77 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -372,6 +372,7 @@ public: void release() const; void clear() const; void setTo(const _InputArray& value, const _InputArray & mask = _InputArray()) const; + Mat reinterpret( int type ) const; void assign(const UMat& u) const; void assign(const Mat& m) const; @@ -1339,6 +1340,15 @@ public: */ Mat reshape(int cn, const std::vector& newshape) const; + /** @brief Reset the type of matrix. + + The methods reset the data type of matrix. If the new type and the old type of the matrix + have the same element size, the current buffer can be reused. The method needs to consider whether the + current mat is a submatrix or has any references. + @param type New data type. + */ + Mat reinterpret( int type ) const; + /** @brief Transposes a matrix. The method performs matrix transposition by means of matrix expressions. It does not perform the diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index f05711bba8..5f67814639 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -1259,6 +1259,16 @@ Mat Mat::reshape(int _cn, const std::vector& _newshape) const return reshape(_cn, (int)_newshape.size(), &_newshape[0]); } +Mat Mat::reinterpret(int type) const +{ + type = CV_MAT_TYPE(type); + CV_Assert(CV_ELEM_SIZE(this->type()) == CV_ELEM_SIZE(type)); + Mat m = *this; + m.flags = (m.flags & ~CV_MAT_TYPE_MASK) | type; + m.updateContinuityFlag(); + return m; +} + Mat Mat::diag(const Mat& d) { CV_Assert( d.cols == 1 || d.rows == 1 ); diff --git a/modules/core/src/matrix_wrap.cpp b/modules/core/src/matrix_wrap.cpp index b72fdbe784..4ddb89f638 100644 --- a/modules/core/src/matrix_wrap.cpp +++ b/modules/core/src/matrix_wrap.cpp @@ -1656,6 +1656,12 @@ void _OutputArray::create(int d, const int* sizes, int mtype, int i, CV_Error(Error::StsNotImplemented, "Unknown/unsupported array type"); } +Mat _OutputArray::reinterpret(int mtype) const +{ + mtype = CV_MAT_TYPE(mtype); + return getMat().reinterpret(mtype); +} + void _OutputArray::createSameSize(const _InputArray& arr, int mtype) const { int arrsz[CV_MAX_DIM], d = arr.sizend(arrsz); diff --git a/modules/core/test/test_mat.cpp b/modules/core/test/test_mat.cpp index d77aca06cb..aae15af463 100644 --- a/modules/core/test/test_mat.cpp +++ b/modules/core/test/test_mat.cpp @@ -1303,6 +1303,42 @@ TEST(Core_Mat, reshape_ndims_4) } } +TEST(Core_Mat, reinterpret_Mat_8UC3_8SC3) +{ + cv::Mat A(8, 16, CV_8UC3, cv::Scalar(1, 2, 3)); + cv::Mat B = A.reinterpret(CV_8SC3); + + EXPECT_EQ(A.data, B.data); + EXPECT_EQ(B.type(), CV_8SC3); +} + +TEST(Core_Mat, reinterpret_Mat_8UC4_32FC1) +{ + cv::Mat A(8, 16, CV_8UC4, cv::Scalar(1, 2, 3, 4)); + cv::Mat B = A.reinterpret(CV_32FC1); + + EXPECT_EQ(A.data, B.data); + EXPECT_EQ(B.type(), CV_32FC1); +} + +TEST(Core_Mat, reinterpret_OutputArray_8UC3_8SC3) { + cv::Mat A(8, 16, CV_8UC3, cv::Scalar(1, 2, 3)); + cv::OutputArray C(A); + cv::Mat B = C.reinterpret(CV_8SC3); + + EXPECT_EQ(A.data, B.data); + EXPECT_EQ(B.type(), CV_8SC3); +} + +TEST(Core_Mat, reinterpret_OutputArray_8UC4_32FC1) { + cv::Mat A(8, 16, CV_8UC4, cv::Scalar(1, 2, 3, 4)); + cv::OutputArray C(A); + cv::Mat B = C.reinterpret(CV_32FC1); + + EXPECT_EQ(A.data, B.data); + EXPECT_EQ(B.type(), CV_32FC1); +} + TEST(Core_Mat, push_back) { Mat a = (Mat_(1,2) << 3.4884074f, 1.4159607f);