Выпустить Mat внутри std::vector

#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 напрямую.