我正在重写一些旧代码,这些代码使用原始C样式数组对double进行矩阵运算。由于代码已经在其他地方依赖于OpenCV,因此我想改用cv::Mat
类。
困扰我的特定代码适用于大小从1 * 1到N N的方阵。它通过分配一个N N缓冲区来实现,并将其子集用于较小的矩阵。
double* buf = new double[NxN];
for (int i = 1; i < N; ++i) {
// Reuse buf to create a i*i matrix and perform matrix operations
...
}
delete[] buf;
基本上,我想替换该代码以在循环中使用cv::Mat
对象。问题是,代码需要大量的循环迭代(存在嵌套循环等),并且如果我仅使用朴素和简洁的方法,那么分配/取消分配将太多。因此,我想预先保留矩阵对象的大小,并为每次迭代调整大小。理想情况下,看起来像这样:
cv::Mat m;
m.reserveBuffer(N * N * sizeof(double));
for (int i = 1; i < N; ++i) {
m = cv::Mat(i, i, CV_64F);
// Perform matrix operations on m
...
}
但是据我了解,这只会删除m
的先前实例,然后分配一个i * i矩阵。正确的方法是什么?
答案 0 :(得分:1)
您可以使用cv::Mat::operator()
为缓冲区创建submatix头。传递一个cv::Rect
以获得您要在当前循环迭代中处理的ROI(在您的情况下为{0, 0, i, i}
),它将返回缓冲区区域的视图作为另一个cv::Mat
实例。它不会分配新的缓冲区,但会引用原始缓冲区数据。
cv::Mat m(N, N, CV_64FC1);
for (int i = 1; i < N; ++i) {
cv::Mat subM = m({0, 0, i*i});
// Perform matrix operations on "subM"
// Modifying "subM" will modify "m" buffer region that "subM" represents
}
请注意,subM
不会be continious,因此,如果执行任何原始缓冲区处理,则需要逐行处理它。