#c #image #opencv #vector #release
#c #изображение #opencv #вектор #выпуск
Вопрос:
Используя OpenCV 2.2, я пытаюсь освободить память, вызывая release для Mat-изображения внутри std:: vector, такого как:
std::vector < Mat > matVec;
Однако, похоже, что
for (int k = 0; k < matVec.size(); k )
{
matVec[k].release();
}
не освобождает память (хотя она все еще компилируется).
Я знаю, что в OpenCV 2.2 есть новое управление памятью, но я не смог определить проблему.
Аналогичный пример с IplImage*
типом вместо Mat (используя cvReleaseImage()
вместо функции-члена Mat .release()
) работает просто отлично.
Есть какие-нибудь подсказки?
Ответ №1:
.release()
следует вызывать только в исключительных обстоятельствах, это не для повседневного использования. Просто очистите вектор:
std::vector<cv::Mat>().swap(matVec);
Это вызывает деструктор каждого из Mat
файлов, освобождающий память (если на это не cv::Mat
указывает ни один другой — помните, что cv::Mat
в отличие IplImage
от типа данных с подсчетом ссылок). Если на него есть ссылка где-то еще, вы также должны очистить эту ссылку). Если вы хотите сохранить вектор, но избавиться от содержимого, замените .release()
строку в вашем коде на:
matVec[k] = cv::Mat();
Комментарии:
1. Спасибо, Джейкоб, этарион! Я ценю вашу помощь. И как бы вы поступили следующим образом: предположим, вы хотите отправить обратные изображения в matVec. Однако эти изображения изначально являются IplImage *. Как бы вы преобразовали из IplImage * в Mat таким образом, чтобы вектор все еще можно было правильно очистить, используя предложенный вами метод? Спасибо!
Ответ №2:
Лучшим способом было бы активировать деструктор каждого matVec[k]
объекта. Вы можете сделать это, matVec
выпустив из области видимости или определив matVec
как vector
of Mat*
и вручную выделяя и освобождая каждый объект.
Это всегда безопаснее, поскольку OpenCV использует механизм подсчета ссылок для Mat
объектов, и поэтому вы не хотите освобождать данные в Mat
напрямую.