Доступ к элементам cv :: Mat с at <float>(i, j). Это (x, y) или (row, col)? - PullRequest
22 голосов
/ 18 ноября 2011

Когда мы получаем доступ к определенным элементам структуры cv :: Mat, мы можем использовать mat.at (i, j) для доступа к элементу в позиции i, j.Однако не сразу ясно, относится ли (i, j) к координате x, y в матрице или к i-й строке и j-му столбцу.

Ответы [ 5 ]

38 голосов
/ 19 февраля 2017

OpenCV, как и многие другие библиотеки, обрабатывает матрицу access в порядке следования строк.Это означает, что каждый доступ определяется как (row, column).Обратите внимание, что если вы работаете с координатами x и y изображения, это становится (y, x), если y является вашей вертикальной осью.

Большинство библиотек матриц одинаковы в этом отношении, доступ(row, col) также, например, в Matlab или Eigen (матричная библиотека C ++).

Однако, где эти приложения и библиотеки различаются, это то, как данные на самом деле хранятся в памяти.OpenCV хранит данные в главном порядке строк в памяти (то есть строки идут первыми), в то время как, например, Matlab сохраняет данные в главном порядке столбцов в памяти.Но если вы просто пользователь этих библиотек и обращаетесь к данным через аксессор (row, col), вы никогда не увидите разницу в порядке хранения в памяти .

25 голосов
/ 19 мая 2013

Так что OpenCV обрабатывает это немного странно.OpenCV сохраняет Mat в мажорном порядке строк, но адресация его по методу Mat :: at () ложно предполагает мажорный порядок столбцов.Я думаю, что документация Opencv вводит в заблуждение в этом случае.Я должен был написать этот тестовый пример, чтобы убедиться в этом сам.

cv::Mat m(3,3,CV_32FC1,0.0f);
m.at<float>(1,0) = 2;
cout << m << endl;

Так что адресация выполняется с Mat :: at (y, x):

[0, 0,0;
2, 0, 0;
0, 0, 0]

Но необработанный доступ к указателю показывает, что это фактически сохраненная мажорная строка, например, «2» находится на 4-й позиции.Если бы он хранился в главном порядке столбцов, он был бы на 2-й позиции.

float* mp = &m.at<float>(0);
for(int i=0;i<9;i++)
    cout << mp[i] << " ";

0 0 0 2 0 0 0 0 0

В качестве дополнительного замечания: Matlab хранит и обращается к матрице в главном порядке столбцов.Это может раздражать, но, по крайней мере, это соответствует.

19 голосов
/ 18 ноября 2011

OpenCV, как и другие библиотеки, обрабатывает матрицы (и изображения) в порядке расположения строк. Это означает, что каждый доступ определяется как (row, column).

Заметными исключениями из этого общего правила являются библиотеки Matlab и Eigen.

12 голосов
/ 18 ноября 2011

Из того, что я прочитал в документации, это at(y, x) (то есть row, col).

8 голосов
/ 18 ноября 2011

Поскольку cv::Mat на самом деле является общей матрицей, а изображения - просто особым случаем, она следует за индексированием матрицы, и поэтому строка (y) предшествует столбцу (x):

mat.at(i, j) = mat.at(row, col) = mat.at(y, x)
...