如果 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?
垫 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
.
a
和b
将共享同一块内存。
而b
的data
领域将与a
的data
领域相同。
我的问题是:
如果b
的data
域与a
的data
域相同,那么a
和b
有什么区别?
它们的data
字段是相同的,但其他函数知道a
和b
是不同的!
他们怎么知道的?
我的假设是错误的!
虽然没有分配新的内存,但a
和b
的data
字段是不同的!!
这是 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
指向的东西(。
不会分配新的内存。
比如说,我们有一个名为a
的cv::Mat
。
cv::Mat b=a;
b
的data
字段将与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
字段不是 m
的 data
字段的副本(m
是传递给构造函数的参数(data
。
所以,对于我的问题..
a
和b
的data
领域是不同的!
相关文章:
- 将CHW格式的浮点向量转换为cv::Mat
- C++:从GPU内存(cudaMemcpy2D)获取BGR图像(cv::Mat)
- 选择基于另一个垫子的非零像素的cv::Mat的一部分?
- 将 cv::mat 转换为 QImage
- 将 cv::Mat 转换为 std::vector 的通用函数
- 在 QML VideoOutput 中将 cv::mat 显示为 QVideoFrame
- 如何将 cv::Mat & Img 复制到未签名的 char* img?opencv
- 如何将 cv::Mat 转换为 vtkImageData?
- 如何将 vtkImageData 转换为 cv::Mat?
- 如何总结所有cv::Mat元素
- Qt-工作线程崩溃时将cv::Mat转换为QImage
- 在 cv::Mat 中生成 2D 坐标网格
- 将 cv::Mat 转换为无符号的 int 像素
- OpenCV 分段错误(核心转储)在使用 cv::Mat::at 时
- 如何将多个 cv::Mat 从 c++ dll 传递到 opencvsharp Mat c#?
- OpenCV(3.4.1) 错误:断言失败(变暗 <= 2 && step[0] > 0) in cv::Mat::locateROI
- 如何在不复制数据的情况下将 cv::Mat 转换为 2d 标准::矢量
- 如何使用 (*mpORBextractorLeft)(im,cv::Mat(),mvKeys,mDescriptors)
- 从数组创建 Mat 时,'cv::Mat' 和 'int' 类型不兼容
- 如何将 cv::mat 对象从 python 模块传递到 c++ 函数并返回返回的 cv::mat 类型为对象?