Выравнивание строк в OpenCV cv :: Mat и CvMat - PullRequest
4 голосов
/ 14 мая 2011

Может кто-нибудь объяснить мне, как работает выравнивание строк в CvMat OpenCV (или его версии 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->data - это [1,2,3,4,5,6]), и я не вижу никакого 4-байтового выравнивания.Является ли это ошибкой в ​​документации, и всегда ли безопасно предполагать непрерывность данных CvMat или cv::Mat (в случае, если матрица не является частью другого ofc)?Или есть какие-то специальные конфигурации, в которых могут быть некоторые пробелы в данных в результате выравнивания памяти?

1 Ответ

3 голосов
/ 16 мая 2011

Не безопасно предполагать преемственность.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) имеет смещение y * step + x.

Есть ряд ситуаций, когда вы получаете не непрерывную память, и они не ограничиваются выравниванием памяти.Например, если вы говорите cv::Mat r = mat.col(0), данные не копируются, но r указывает на ту же область памяти, что и mat, просто с другим «заголовком», поэтому имеющийся у вас «пробел» - это данныеиз матрицы, которой нет в столбце 0.

...