1
votes

I use the below piece of code to read each frame from the camera and pushing it to a vector. Am doing this to process all the collected frames in the vector at later point.

I used the below code to collect the frames from camera. But after 2005 frames the codes throws the below error.

OpenCV Error: Insufficient memory (Failed to allocate 921604 bytes) in OutOfMemoryError, file D:\Opencv\modules\core\src\alloc.cpp, line 52

The below is the code I used to collect the frames and push it into a vector.

#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/contrib/contrib.hpp"

#include <stdio.h>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <stdlib.h>

 using namespace std;
 using namespace cv; 


 int main()
 {     

     VideoCapture capture(0); 
     if(!capture.isOpened()) 
         return -1; 
     vector <Mat>  frame;       
     int delay = 10;  
         int count = 0;

                Mat src;     

                while(true) { 
                    capture >> src;                                     
                    frame.push_back(src.clone());                                                            

                    imshow("VIDEO", src);
                    if( waitKey( delay ) >= 0) break; 
                    count = count+1;
                    cout << count << endl;
                } 


                /* I need to process each frame stored inside the vector*/

      destroyWindow("VIDEO");
      capture.release();

   return 0;
 }
3
Extract the frames to the disk and push_back the filenames inside the vector.LovaBill

3 Answers

5
votes

You probably are running out of memory like the error suggests. If each frame is 640*480 (ie quite low res) then 2005 * 640 * 480 * 3 (bytes per pixel) = 1,847,808,000 (ie 1.8GB of RAM being allocated in a contiguous block).

Equally every time the vector has to resize itself it will need to make an allocation large enough to hold the new data, then copy the old data to the new vector then deallocate the old allocation, effectively doubling the amount of memory you need.

2
votes

As the error stated, your program has reached the limit of RAM that's reserved for your process by the operational system. You can do some things to reduce this problem:

1 - Encode the image to a more compact format, like .jpg. This will reduce the memory used by your frames.

2 - Save your buffer on disk. As this is probably slow, and you don't want to lose frame rate, probably you will need to use a new thread in a producer/consumer scheme.

3 - Reduce the resolution of the image. I don't know your specific use case, but a reduced image can be suitable for a lot of computer vision algorithms. No need to store all the color information.

4 - Store just the interesting points of the image: It's a very common approach in the computer vision community. Again, I don't know what you are trying to accomplish, but maybe you can do some pre-processing on the image for each frame and store just the relevant points? Maybe you will need some GPU implementation of the pre-processing algorithm to keep the frame rate at real time.

Keep in mind that even if you reduce significantly the amount of memory that you store per frame, you still will eventually run out of memory. Without saving the information on disk, this is pretty much guaranteed.

2
votes

raw frame sizes are huge. You should typically preallocate atleast 2 frames and less than say 4, depending on how much jitter there is with camera source. Multimedia systems always pre-allocate memory.

so you should typically do..

for(int i=0; i<NUM_FRAMES; i++
    frames.push_back(new Mat()); //handle exceptions from new.

and then recycle using the frames

int i=0;
int curr_frame=i;

while(true) { 
   capture >> *(frames[i]); 

   //show frame

   i = (i+1)%NUM_FRAMES;

   //process frames[curr_frame]..
}

You should actually do processing on the fly, preferably on a separate thread. Consequently, your processing time must be roughly match camera capture rate. That is, it shouldn't happen that you yet to process a certain frame, but is overwritten by the camera. If the processing time of the algorithm is variable, such as in video encoder, jitter buffer helps.There will be sufficient number of buffers (NUM_FRAMES), so that encoder can catch up.