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

标签 c++ opencv

Mat a = (Mat_(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
cv::Mat b=a.row(1);

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

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

最佳答案

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

这是 mat.hpp 中 header 的片段代码,其中 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 字段不一样!

关于c++ - 如果 a 是 cv::Mat 和 cv::Mat b=a.row(1),那么这两个 cv::Mat 实例有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25990849/

相关文章:

python - 如何在给定相对 bbox 坐标的情况下在此图片上裁剪车号?

c++ - 如何从 C++ 源代码中提取所有类型定义、结构和 union

c++ - Qt - 如何粘合两个窗口并将它们移动到一起?

c++ - 有什么方法可以避免 systemctl 在停止时杀死我的一个子进程?

python - 使用 solvePnPRansac 函数时出错

python - Python:如果JSON响应为空,则无法使用

c++ - 是否可以将整数指针转换为位于该内存位置的实际整数?

c++ - 如何在C++中独立生成多个随机数序列?

forms - 通过字段识别和光学字符识别 (OCR) 在预定义表格上进行手写数据输入自动化

c++ - 使用 ycbcr 格式捕获相机图像