4

有人可以向我解释一下 OpenCV CvMat(或其 C++ 版本cv::Mat)的行对齐是如何工作的吗?例如,假设我有一个矩阵

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) );

根据 的文档CvMat,行应对齐 4 个字节,即矩阵的第一行应填充一个零,第二行应从偏移量 +4 开始)。但是,如果我调试这段代码,数据是连续的(即cvmat->datais [1,2,3,4,5,6]),我看不到任何 4 字节对齐。这是文档中的错误吗?假设CvMator的数据的连续性总是安全的cv::Mat(如果矩阵不是另一个 ofc 的一部分)?或者是否有一些特殊的配置,由于内存对齐,数据中可能会出现一些间隙?

4

1 回答 1

3

假设连续性是不安全的。cv::Mat有一个成员函数isContinuous,你可以检查连续性(C API 有一个宏,正如评论所说):

// 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;

还有一个成员step告诉您连续行之间的偏移量:

// a distance between successive rows in bytes; includes the gap if any
size_t step;

因此,假设您有一个 8 位单通道图像,则 (x, y) 处的像素位于 offset 处y * step + x

在许多情况下,您最终会得到不连续的内存,并且它们不仅限于内存对齐。例如,如果您说cv::Mat r = mat.col(0),则数据不会被复制,而是r指向与 相同的内存区域mat,只是具有不同的“标题”,因此您所拥有的“间隙”是来自矩阵的数据,该数据不在第 0 列.

于 2011-05-16T10:01:32.830 回答