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(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::Mathas a member functionisContinuousthat you can check for continuity (the C API has a macro for that, as the comment says):There’s also a member
stepthat tells you the offset between consecutive rows: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, butrpoints to the same memory region asmat, just with a different “header”, so the “gap” that you have there is the data from the matrix that is not in column 0.