Вы можете установить step
(шаг байтов) и построить срез без копирования данных:
Предположим, data
непрерывно в памяти:
- Строка начинается со смещения
row*N
double
элементов от data.data
(data.data
данные матрицы точек). - Срез
step
(шаг байтов между рядами) равен M * N *sizeof(double)
.
[В случае, если data
не является непрерывным в памяти, решение является более сложным].
Вот пример кода (строит срез 5-й строки):
const int M = 20;
const int N = 40;
const int img_dim[3] = { 10, M, N };
Mat data = cv::Mat::zeros(3, img_dim, CV_64FC1);
int row = 5;
data.at<double>(0, row, 0) = 0;
data.at<double>(1, row, 0) = 1;
data.at<double>(2, row, 0) = 2;
data.at<double>(3, row, 0) = 3;
data.at<double>(0, row, 1) = 100;
data.at<double>(1, row, 1) = 101;
data.at<double>(2, row, 1) = 102;
data.at<double>(3, row, 1) = 103;
//Byte stride between M of slice equals M*N*8 bytes
size_t step = M * N *sizeof(double);
//slice begins at data.data + row*N
Mat slice(10, N, CV_64FC1, (uchar*)data.data + row*N*sizeof(double), step);
std::cout << slice.at<double>(0, 0) << std::endl << slice.at<double>(1, 0) << std::endl << slice.at<double>(2, 0) << std::endl << slice.at<double>(3, 0) << std::endl << std::endl;
std::cout << slice.at<double>(0, 1) << std::endl << slice.at<double>(1, 1) << std::endl << slice.at<double>(2, 1) << std::endl << slice.at<double>(3, 1) << std::endl << std::endl;
Примечание. Обработка данных с большими шагами может быть неэффективной из-за пропусков кэша - может быть более эффективно копировать данные (проверьте, замедляется ли обработка данных).
Выход:
0
1
2
3
100
101
102
103