OpenCV's cv::Mat & CvMat row alignment
could someone pls explain to me how the row alignment of OpenCV's CvMat
(or its C++ version cv::Mat
) works? For instance, let's assume I have a matrix
CvMat *cvmat = cvCreateMat(开发者_JS百科2,3,CV_8UC1);
cvSet2D( cvmat, 0, 0, cvScalar(1) );
cvSet2D( cvmat, 0, 1, cvScalar(2) );
cvSet2D( cvmat, 0, 2, cvScalar(3) );
cvSet2D( cvmat, 1, 0, cvScalar(4) );
cvSet2D( cvmat, 1, 1, cvScalar(5) );
cvSet2D( cvmat, 1, 2, cvScalar(6) );
According to the documentation of CvMat
, rows should be aligned by 4 bytes, i.e. first row of the matrix should be padded by one zero and the second should start at the offset +4). However, if I debug this piece of code, the data are continuous (i.e. cvmat->data
is [1,2,3,4,5,6]
) and I don't see any 4-byte alignment. Is this a bug in documentation and is it always safe to assume the continuity of the data of CvMat
or cv::Mat
(in the case that the matrix is not part of another ofc)? Or are there some special configurations in which there could be some gaps in the data as a result of memory alignment?
It's not safe to assume the continuity. cv::Mat
has a member function isContinuous
that you can check for continuity (the C API has a macro for that, as the comment says):
// returns true iff the matrix data is continuous
// (i.e. when there are no gaps between successive rows).
// similar to CV_IS_MAT_CONT(cvmat->type)
bool isContinuous() const;
There's also a member step
that tells you the offset between consecutive rows:
// a distance between successive rows in bytes; includes the gap if any
size_t step;
So, assuming you have an 8-bit single channel image, the pixel at (x, y) is at offset y * step + x
.
There's a number of situations where you end up with non-continuous memory, and they are not restricted to memory alignment. E.g., if you say cv::Mat r = mat.col(0)
, the data is not copied, but r
points to the same memory region as mat
, just with a different "header", so the "gap" that you have there is the data from the matrix that is not in column 0.
精彩评论