Merge pull request #25394 from Gao-HaoYuan:in_place_convertTo

Added reinterpret() method to Mat to convert meta-data without actual data conversion
This commit is contained in:
Alexander Smorkalov 2025-04-04 10:40:33 +03:00 committed by GitHub
commit 0b3155980a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 62 additions and 0 deletions

View File

@ -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<int>& 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

View File

@ -1259,6 +1259,16 @@ Mat Mat::reshape(int _cn, const std::vector<int>& _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 );

View File

@ -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);

View File

@ -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_<float>(1,2) << 3.4884074f, 1.4159607f);