Pre-loading video images in std::vector

Have you ever thought to load all images of a video file into a std::vector just to see if your program gets faster than to iteratively read the images from the file?

Well, I did. The hypothesis is that accessing the video info from the file all together at the beginning might at the end be faster that doing it iteratively interlaced with the processing of the images.

Normally I use the following code:

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
void main()
{
  VideoCapture video;
  if( !video.open("myFile.avi") )
    return 1;
  Mat image;
  for(;;)
  {
    video >> image;
    if( image.empty() )
      break;
    // Do some process
    ...
  }
}

While, you can as well do this:

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
void main()
{
  VideoCapture video;
  if( !video.open("myFile.avi") )
    return 1;
  int numFrames = static_cast<int>(video.get(CV_CAP_PROP_FRAME_COUNT));
  vector<Mat> videoFrames;
  videoFrames.reserve( numFrames );
  for( ; ; )
  {
    video >> inputImg;			
    if( inputImg.empty() )
      break;
    Mat aux;
    inputImg.copyTo( aux );
    videoFrames.push_back( aux );
  }
  Mat image;
  for(size_t i=0; i<videoFrames.size(); ++i)
  {
    image = videoFrames[i];
    // Do some process
    ...
  }
}

Of course, the comparison depends on your machine, if it does have enough RAM memory to host the entire video. I believe also in some other variables like your HD type, and so on, but I am not entering in such details.
For a short video of 2792, 376×240 pixels, fourcc = 1145656920, I tried both options with the following result:
-Using VideoCapture: 4451 (ms) = 1.59 (ms/frame)
-Using std::vector: 5568 (ms) (load time = 1666 (ms) + 3902 (ms) processing) = 0.59 (ms/frame) + 1.39 (ms/frame) = 1.99 (ms/frame)

So, there are two reads here. On the one hand, the sum of time make me think that using VideoCapture for one loop processes is still a good option, since the total time is 1.59 (ms/frame), while using vector increases the total time to 1.99 (ms/frame) mainly because of the overhead of loading the images.
On the other hand, if you are about to run several different algorithms on the same video in a separate manner, you gain a little bit because you only have to do the loading once (and it is done very quickly), and accessing the (already decoded) images from memory is better than from file (1.39 ms vs 1.59 ms).

That’s all!
Kind regards

Marcos

This entry was posted in OpenCV and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s