Reputation: 394
Mat a = (Mat_(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
cv::Mat b=a.row(1);
cv::Mat
has a field called data
, that is a pointer which is pointed to the actual memory for the Mat.
I know this is shallow copy, no new memory will be allocated to store the elements in a.row(1)
for b
.
a
and b
will share a same piece of memory.
And the data
field of b
will be the same as a
's data
field.
My question is:
if The data
field of b
is the same as a
's data
field, then what is the difference between a
and b
?
Their data
fields are the same , but other functions know a
and b
are different !!
How do they know this?
Upvotes: 1
Views: 272
Reputation: 394
My assumption was wrong !
Although no new memory is allocated, the data
fields of a
and b
are different!!
Here's a snippet code of the headers in mat.hpp
,where cv::Mat
is defined as this:
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
...
};
when you are doing shallow copy, only the pointer , data
(not the things data
pointed to )would be copied.
no new memory will be allocated.
say , we have a cv::Mat
called a
.
cv::Mat b=a;
b
's data
field will be the same as a
's.
No new memory will be allocated for b
.
But what about the following code:
cv::Mat b=a.col(1);
Here's a snippet code of matrix.cpp
, which including the implementations of cv::Mat functions :
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()
will return a new cv::Mat
, it needs to call a constructor.
The constructor above is for constructing a cv::Mat
with another cv::Mat
reference,and a cv::Range
.
Note that the data
field is not a copy of the data
field of m
's (m
is the parameter passed to the constructor) data
.
so,for my question..
the data
fields of a
and b
are different!
Upvotes: 1