DeniseT
DeniseT

Reputation: 29

Reduce memory consumption

I'm currently using this code to analyze webcam frames:

int main()
{
    VideoCapture cap(0); // open the default camera
    if (!cap.isOpened())  // check if we succeeded
        return -1;
    cap.set(CV_CAP_PROP_FPS, 15);

    std::vector<cv::Mat> images(9000);
    for (framenumb = 0; framenumb < 9000; ++framenumb) 
    {
        images[framenumb].create(480, 640, CV_8UC3);
    }
    for (framenumb = 0; framenumb < 9000; ++framenumb)
    {
        Mat frame;
        cap >> frame;
        if (frame.empty()) break; // end of video stream
        if (waitKey(1) == 27) break; // stop capturing by pressing ESC 
        frame.copyTo(images[framenumb]);
        imshow("webcam", images[framenumb]);
    }
    //We can then process the captured frames

However, it leads to insufficient memory error:

OpenCV Error: Insufficient Memory (failed to allocate xyz bytes) in unknown function, file 
..\..\opecv\modules\core\src\alloc.cpp line 52.

Is there a way for me to avoid this? Thanks a lot in advanced!

Edit: Thanks for the all constructive feedback everyone! I guess all I can do for now is to change my approach to the problem. What I tried to accomplish was to take average of every 15 frames. For example: with 9000 frames, I will have 600 average pictures. Thus, I created a vector of 9000 images and use counter to achieve that.This is the code i used later:

for (int i = 0; i < 600; i++)
            {
                Mat avgImg(480, 640, CV_32FC3, Scalar());
                for (framenumb = 15 * i; framenumb < (15 * i) + 15; ++framenumb)
                {
                    cv::accumulate(images[framenumb], avgImg);
                }
                //stacking every 15 images into a single image
                avgImg = avgImg / 15;
                avgImg.convertTo(avgImg, CV_8UC3);
                char filename[80];
                sprintf(filename, "C:/AvgPics/test_%d.jpeg", framenumb);
                imwrite(filename, avgImg);

So is there a way for me to specify opencv to take average of every 15 images without having to use a 9000-image vector?

Upvotes: 1

Views: 670

Answers (2)

MSalters
MSalters

Reputation: 180303

Compile as 64 bits. 8 GB is not excessive, but 32 bits programs are limited to 4GB at best. (I assume you do have sufficient RAM - at least 12 GB total). OpenCV supports 64 bits.

Upvotes: 7

RaymoAisla
RaymoAisla

Reputation: 161

You probably need to find a way to treat your frames without open them all at the same time.

I don't really know OpenCV syntax, but it seems that 9000 images of 480*640 pixels are opened, which require, assuming 3 bytes per pixel, a memory of 9000*480*640*3 bytes, i.e. 8 GB. That is not easy to treat with a standard computer with "classic quantity" of RAM.

If the treatment is sequential and doesn't require to open all frames simultaneously, the best thing to do is to adapt the treatment to do it sequentially frame by frame.

Upvotes: 2

Related Questions