Как зарезервировать фиксированный размер буфера в OpenCV Mat? - PullRequest
1 голос
/ 14 июня 2019

Я переписываю некоторый унаследованный код, который выполняет матричные операции над двойниками с использованием необработанного массива в стиле C. Поскольку код уже имеет зависимость от 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 Ответ

1 голос
/ 14 июня 2019

Вы можете создать заголовок Submatix для вашего буфера, используя cv::Mat::operator(). Передайте 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 не будет непрерывным , поэтому вам придется обрабатывать его построчно, если вы выполняете какую-либо необработанную обработку буфера.

...