Ask Your Question

How to free cv::Mat from memory

asked 2019-04-29 09:07:11 -0500

t3rb3d gravatar image

I have a sequence of images (frames) from a camera as an input, what is stored in std::queue<cv::Mat> buffer container. After the processing algorithm is finished for a frame then it is popped. My problem is that somehow the memory usage is constantly rising, however the container size buffer.size() is maximum 1 (so the algorithm is 'eating' up the buffer properly and pops the images).

I would like demonstrate my problem with a minimal reproducible code:

cv::Mat current_frame(500, 500, CV_16UC3);
std::queue<cv::Mat> buffer;

This code results in constantly rising memory usage. (Ubuntu system, opencv 3.4.6 version)

My question is that how can you properly release a cv::Mat from memory.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2019-04-29 11:12:41 -0500

the code below is from an older question maybe it will be a sample for use of std::queue<cv::Mat> ( i have no deep knowledge about the code )

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/calib3d.hpp"

#include <map>
#include <queue>
#include <thread>
#include <mutex>
#include <atomic>
#include <string>
#include <iostream>

/** @brief Example Class that grabs from cv::VideoCapture into a queue.

It can be used as worker thread.

Even if you grab N frames and create N x Mat in the queue
only few blocks will be really allocated thanks to @c std::vector
and @c cv::Mat memory recycling. Look at @c matMemoryCounter to
know how many memory blocks has been allocated
@author PkLab answer to question:
@note It can be done much better but it's better than nothing :)
@note It requires C++11 or later
class GrabberThread {
    int device;
    std::mutex mtx;
    std::queue<cv::Mat > buffer;
    std::atomic<bool> grabOn;
    cv::VideoCapture cap;
    size_t bufSizeMax;
    std::map<unsigned char*, int> matMemoryCounter;
    GrabberThread() : grabOn(false), device(0), bufSizeMax(0) {};
        while (!buffer.empty())

    /* @brief initialize members and open the capture device
    @return true if the device has successfully opened
    bool Init(int dev = 0)
        device = dev;;
        return cap.isOpened();

    /* @brief Disable the grabbing loop control var.
    This will stop the grabbing thread
    void StopGrabing()

    /** @brief This is the thread that grabs into a queue
    @note In real application locks and multiple copyTo can be avoided
    using better queue/circular buffer!
    void GrabThread()
        uchar * frameMemoryAddr;

        if (!cap.isOpened());
        if (!cap.isOpened()) return;

        cv::Mat tmp;;
        while (grabOn.load() == true) //this is lock free
            //read() will wait for cam FPS. 
            //keep grab out of lock so that
            //idle time can be used by other threads
            if (!
            //get lock only when we have a frame
            /** @warning Avoid @c buffer.push_back(tmp) because it stores items by reference.
            We have to create a new cv::Mat for each frame
            STL and cv::Mat will recycle memory
            buffer.push(cv::Mat(tmp.size(), tmp.type()));
            //count how many times this memory block has been used
            frameMemoryAddr = buffer.front().data;
            bufSizeMax = std::max(bufSizeMax, buffer.size());

            /* SHOW THE FRAME if do you want
            string winName = "Live Thread Dev: " + std::to_string(device);
            int font = CV_FONT_HERSHEY_PLAIN;
            cv::putText(tmp, winName, cv::Point(10, 10), font, 1, cv::Scalar(0, 255, 0));
            imshow(winName, tmp);
            cv::waitKey(1);    //just for imshow
        } // while
    } // func

      /** @brief Get the oldest grabbed frame if available

      The frame is copied from the buffer than it can used freely

      @Param [out]frame the the oldest grabbed frame. if not available it will be empty
      @Param [out]pBufSize a pointer where returns current buffer size. If 0 it will be ignored
      @Param [out]pBufSizeMax ...
edit flag offensive delete link more


I tried this from the sample code:

    (*buffer).push(cv::Mat(tmp.size(), tmp.type()));

but unfortunately the issue remains.

t3rb3d gravatar imaget3rb3d ( 2019-04-29 12:30:25 -0500 )edit

Question Tools

1 follower


Asked: 2019-04-29 09:07:11 -0500

Seen: 903 times

Last updated: Apr 29 '19