如何在OpenCV Mat中保留固定的缓冲区大小?

时间:2019-06-13 22:47:54

标签: c++ opencv memory-management mat

我正在重写一些旧代码,这些代码使用原始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矩阵。正确的方法是什么?

1 个答案:

答案 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,因此,如果执行任何原始缓冲区处理,则需要逐行处理它。