如果 a 是 cv::Mat 和 cv::Mat b=a.row(1),那么两个 cv::Mat 实例有什么区别

if a is a cv::Mat and cv::Mat b=a.row(1),then What is the difference between the two cv::Mat instances?

本文关键字:Mat cv 两个 什么 区别 实例 row 如果      更新时间:2023-10-16
垫 a = (Mat_(3,3( <<1, 0, 0, 0, 1, 0,

0, 0, 1(;
cv::Mat b=a.row(1(;

cv::Mat有一个名为data的字段,这是一个指向垫子实际内存的指针。
我知道这是浅拷贝,不会分配新的内存来存储a.row(1)中的元素以供b.
ab将共享同一块内存。
bdata领域将与adata领域相同。

我的问题是:
如果bdata域与adata域相同,那么ab有什么区别?
它们的data字段是相同的,但其他函数知道ab是不同的!
他们怎么知道的?

我的假设是错误的!
虽然没有分配新的内存,但abdata字段是不同的!!

这是 mat.hpp 中标头的代码片段代码,其中 cv::Mat 定义如下:

class CV_EXPORTS Mat
{
public:
    // ... a lot of methods ...
    ...
        /*! includes several bit-fields:
        - the magic signature
        - continuity flag
        - depth
        - number of channels
        */
        int flags;
    //! the array dimensionality, >= 2
    int dims;
    //! the number of rows and columns or (-1, -1) when the array has more than 2 dimensions
    int rows, cols;
    uchar* data;
    //! pointer to the reference counter;
    // when array points to user-allocated data, the pointer is NULL 
    int* refcount;
    // other members
    ...
};

当你做浅拷贝时,只会复制指针 、data(而不是data指向的东西(。
不会分配新的内存。
比如说,我们有一个名为acv::Mat

cv::Mat b=a;

bdata字段将与a的字段相同。不会为 b 分配新的内存。

但是下面的代码呢:

cv::Mat b=a.col(1(;

这是 matrix.cpp 的代码片段,其中包括 cv::Mat 函数的实现:

Mat::Mat(const Mat& m, const Range* ranges)
    : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
      datalimit(0), allocator(0), u(0), size(&rows)
 {
int i, d = m.dims;
CV_Assert(ranges);
for( i = 0; i < d; i++ )
{
    Range r = ranges[i];
    CV_Assert( r == Range::all() || (0 <= r.start && r.start < r.end && r.end <= m.size[i]) );
}
*this = m;
for( i = 0; i < d; i++ )
{
    Range r = ranges[i];
    if( r != Range::all() && r != Range(0, size.p[i]))
    {
        size.p[i] = r.end - r.start;
        data += r.start*step.p[i];
        flags |= SUBMATRIX_FLAG;
    }
}
updateContinuityFlag(*this);
}

cv::Mat::col()将返回一个新的cv::Mat,它需要调用一个构造函数。
上面的构造函数用于构造具有另一个cv::Mat引用的cv::Mat,以及一个cv::Range
请注意,data 字段不是 mdata 字段的副本(m 是传递给构造函数的参数(data

所以,对于我的问题..
abdata领域是不同的!