我有一个3维cv :: Mat,尺寸为(10,行= M,列数= N)。这是MxN像素堆叠在一个立方体中的10张图像。我想在整个图像的维度上按行对多维数据集进行切片,以便最后获得M个(10,N)的切片,并将对其应用其他一些opencv算法。我发现我可以使用cv :: Ranges();但是,我必须使用重塑使其变为2D,因此必须使用clone()使切片连续。下面是我用来执行此操作的代码段,但是执行时间很慢(我认为对每个行切片执行的克隆/复制都执行此操作)。有一个更好的方法吗?我还发现this,这并不令人鼓舞。
const int img_dim[3] = {10, 20, 40};
Mat data = Mat::zeros(3, img_dim, CV_64FC1);
for (int row = 0; row < data.size[1]; row++ {
std::vector<Range> range;
range.push_back(Range(0, data.size[0]));
range.push_back(Range(row, row+1));
range.push_back(Range(0, data.size[2]));
// Below slice is still 3D with (10, 1, 40) so I use reshape to make it (10, 40)
// which requires the clone()
Mat slice = data(&range[0]).clone();
const int sz[] {data.size[0], data.size[2]};
slice = slice.reshape(1, 2, sz);
// Processing of slice
// e.g cv::GaussianBlur(slice, dst, Size(0,0), r, r);
}
答案 0 :(得分:1)
您可以设置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