Avoiding memory leaks while using vector<Mat>

二次信任 提交于 2019-12-11 11:55:28

问题


I am trying to write a code that uses opencv Mat objects it goes something like this

Mat img;
vector<Mat> images;
for (i = 1; i < 5; i++)
{
  img.create(h,w,type) // h,w and type are given correctly
  // input an image from somewhere to img correctly. 
  images.push_back(img);
  img.release()
}
for (i = 1; i < 5; i++)
  images[i].release();

I however still seem to have memory leakage can anyone tell me why it is so? I thought that if the refcount of a mat object = 0 then the memory should be automatically deallocated


回答1:


You rarely need to call release explicitly, since OpenCV Mat objects take automatically care of internal memory.

Also take care that Mat copy just copies creates a new header pointing to the same data. If the original Mat goes out of scope you are left with an invalid matrix. So when you push the image into the vector, use a deep copy (clone()) to avoid that it the image into the vector becomes invalid.

Since you mentioned:

I have a large 3D image stored in a Mat object. I am running over it using for loops. creating a 2D mat called "image" putting the slices into image, pushing back image to vector images. releasing the image. And later doing a for loop on the images vector releasing all the matrices one by one.

You can store all slices into the vector with the following code. To release the images in the vector, just clear the vector.

#include <opencv2/opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;

int main() 
{
    // Init the multidimensional image
    int sizes[] = { 10, 7, 5 };
    Mat data(3, sizes, CV_32F);
    randu(data, Scalar(0, 0, 0), Scalar(1,1,1));

    // Put slices into images
    vector<Mat> images;
    for (int z = 0; z < data.size[2]; ++z)
    {
        // Create the slice
        Range ranges[] = { Range::all(), Range::all(), Range(z, z + 1) };
        Mat slice(data(ranges).clone()); // with clone slice is continuous, but still 3d
        Mat slice2d(2, &data.size[0], data.type(), slice.data); // make the slice a 2d image

        // Clone the slice into the vector, or it becomes invalid when slice goes of of scope.
        images.push_back(slice2d.clone());
    }

    // You can deallocate the multidimensional matrix now, if needed
    data.release();

    // Work with slices....

    // Release the vector of slices
    images.clear();

    return 0;
}



回答2:


Please try this code, which is basically what you do:

void testFunction()
{
    // image width/height => 80MB images
    int size = 5000;

    cv::Mat img = cv::Mat(size, size, CV_8UC3);

    std::vector<cv::Mat> images;
    for (int i = 0; i < 5; i++)
    {
      // since image size is the same for i==0 as the initial image, no new data will be allocated in the first iteration.
      img.create(size+i,size+i,img.type()); // h,w and type are given correctly

      // input an image from somewhere to img correctly. 
      images.push_back(img);
      // release the created image.
      img.release();
    }

    // instead of manual releasing, a images.clear() would have been enough here.
    for(int i = 0; i < images.size(); i++)
      images[i].release();

    images.clear();
}

int main()
{
    cv::namedWindow("bla");
    cv::waitKey(0);

    for(unsigned int i=0; i<100; ++i)
    {
        testFunction();
        std::cout << "another iteration finished" << std::endl;
        cv::waitKey(0);
    }

    std::cout << "end of main" << std::endl;
    cv::waitKey(0);
    return 0;
}

After the first call of testFunction, memory will be "leaked" so that the application consumes 4 KB more memory on my device. But not more "leaks" after additional calls for me...

So this looks like your code is ok and the "memory leak" isn't related to that matrix creation and releasing, but maybe to some "global" things happening within the openCV library or C++ to optimize future function calls or memory allocations.




回答3:


I encountered same problems when iterate openCV mat. The memory consumption can be 1.1G, then it stopped by warning that no memory. In my program, there are macro #define new new(FILE, LINE), crashed with some std lib. So I deleted all Overloading Operator about new/delete. When debugging, it has no error. But when it runs, I got "Debug Assertion Failed! Expression: _pFirstBlock == pHead". Following the instruction Debug Assertion Error in OpenCV I changed setting from MT (Release)/MTd (Debug)to

Project Properties >> Configuration Properties >> C/C++ >> Code Generation and changing the Runtime Library to:

Multi-threaded Debug DLL (/MDd), if you are building the Debug version of your code. Multi-threaded DLL(/MD), if you are building the Release version of your code.

The memory leak is gone. The memory consumption is 38M.



来源:https://stackoverflow.com/questions/34434401/avoiding-memory-leaks-while-using-vectormat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!