9
votes

I'm capturing frames from a Webcam using OpenCV in a C++ app both on my Windows machine as well as on a RaspberryPi (ARM, Debian Wheezy). The problem is the CPU usage. I only need to process frames like every 2 seconds - so no real time live view. But how to achieve that? Which one would you suggest?

  1. Grab each frame, but process only some: This helps a bit. I get the most recent frames but this option has no significant impact on the CPU usage (less than 25%)
  2. Grab/Process each frame but sleep: Good impact on CPU usage, but the frames that I get are old (5-10sec)
  3. Create/Destroy VideoCapture in each cycle: After some cycles the application crashes - even though VideoCapture is cleaned up correctly.
  4. Any other idea?

Thanks in advance

#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <vector>
#include <unistd.h>
#include <stdio.h>

using namespace std;

int main(int argc, char *argv[])
{
    cv::VideoCapture cap(0); //0=default, -1=any camera, 1..99=your camera

    if(!cap.isOpened()) 
    {
        cout << "No camera detected" << endl;
        return 0;
    }

    // set resolution & frame rate (FPS)
    cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT,240);
    cap.set(CV_CAP_PROP_FPS, 5);

    int i = 0;
    cv::Mat frame;

    for(;;)
    {
        if (!cap.grab())
            continue;

        // Version 1: dismiss frames
        i++;
        if (i % 50 != 0)
            continue;

        if( !cap.retrieve(frame) || frame.empty() )
            continue;

        // ToDo: manipulate your frame (image processing)

        if(cv::waitKey(255) ==27) 
            break;  // stop on ESC key

        // Version 2: sleep
        //sleep(1);
    }

    return 0;
}
1

1 Answers

5
votes
  1. Create/Destroy VideoCapture in each cycle: not yet tested

It may be a bit troublesome on Windows (and maybe on other operating systems too) - First frame grabbed after creating VideoCapture is usually black or gray. Second frame should be fine :)

Other ideas:
- modified idea nr 2 - after sleep grab 2 frames. First frame may be old, but second should be new. It's not tested and generally i'm not sure about that, but it's easy to check it.
- Eventually after sleep you may grab frames in while loop (without sleep) waiting till you grab the same frame twice (but it may be hard to achieve especially on RasberryPi).