Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version
  • I don't understand why you do if (fps==0)... and how do you measure your fps as 6.8 ?
  • Despite of you can cap.set(CV_CAP_PROP_FPS,25), this is ignored by VideoCapture because you will get a new frame each time you will call cap.read ... you ask for a frame and the cam will give you back a frame immediately

On the output side, FPS for output video will be exactly as requested at VideoWriter opening/construction time.

Than:

  • With VideoCapture the grab loop is controlled by user and not by cam, so you grab frames at FPS given by your grab loop timing
  • With VideoWriter you write video at requested FPS, the codec will do the hard work like frame mapping, compression, decimation etc...

Anyway, because your grab loop is just grab frame, save frame (timing should be at minimum), than you should reach highest FPS but for sure higher than 6.8.

Try showing the grabbed frame with imshow("frame", frame); to have a visual feedback of grabbing fps, in case try without video creation or different codec.

At the end, VideoCapture depends from drivers, OS and additional libs and above statement might be unconfirmed on different on environment

  • I don't understand why you do if (fps==0)... and how do you measure your fps as 6.8 ?
  • Despite of you can cap.set(CV_CAP_PROP_FPS,25), this is ignored by VideoCapture because you will get a new frame each time you will call cap.read ... you ask for a frame and the cam will give you back a frame immediately

On the output side, FPS for output video will be exactly as requested at VideoWriter opening/construction time.

Than:

  • With VideoCapture the grab loop is controlled by user and not by cam, so you grab frames at FPS given by your grab loop timing
  • With VideoWriter you write video at requested FPS, the codec will do the hard work like frame mapping, compression, decimation etc...

Anyway, because your grab loop is just grab frame, save frame (timing should be at minimum), than you should reach highest FPS but for sure higher than 6.8.

Try showing the grabbed frame with imshow("frame", frame); to have a visual feedback of grabbing fps, in case try without video creation or different codec.

At the end, VideoCapture depends from drivers, OS and additional libs and above statement might be unconfirmed on different on environment

EDIT: Above infos aren't completely true because if you open the camera using DirectShow instead of default driver (may be Video For Windows) you can set CV_CAP_PROP_FPS effectively (see here for more info)

// VideoCapture cap(0);              // open the default camera using default driver
// VideoCapture cap(0 + CV_CAP_VFW); // open the default camera using VFW
VideoCapture cap(0 + CV_CAP_DSHOW);  // open the default camera using DirectShow

cap.set(CV_CAP_PROP_FPS,25);         // this seems effective with DSHOW
  • I don't understand why you do if (fps==0)... and how do you measure your fps as 6.8 ?
  • Despite of you can cap.set(CV_CAP_PROP_FPS,25), this is ignored by VideoCapture because you will get a new frame each time you will call cap.read ... you ask for a frame and the cam will give you back a frame immediately

On the output side, FPS for output video will be exactly as requested at VideoWriter opening/construction time.

Than:

  • With VideoCapture the grab loop is controlled by user and not by cam, so you grab frames at FPS given by your grab loop timing
  • With VideoWriter you write video at requested FPS, the codec will do the hard work like frame mapping, compression, decimation etc...

Anyway, because your grab loop is just grab frame, save frame (timing should be at minimum), than you should reach highest FPS but for sure higher than 6.8.

Try showing the grabbed frame with imshow("frame", frame); to have a visual feedback of grabbing fps, in case try without video creation or different codec.

At the end, VideoCapture depends from drivers, OS and additional libs and above statement might be unconfirmed on different on environment

EDIT: Above infos aren't completely true because if you open the camera using DirectShow instead of default driver (may be Video For Windows) you can set CV_CAP_PROP_FPS effectively (see here for more info)

// VideoCapture cap(0);              // open the default camera using default driver
// VideoCapture cap(0 + CV_CAP_VFW); // open the default camera using VFW
VideoCapture cap(0 + CV_CAP_DSHOW);  // open the default camera using DirectShow

cap.set(CV_CAP_PROP_FPS,25);         // this seems effective with DSHOW

EDIT2 VideoCapture is a bit oscure and depends from drivers :( anyway, try declaring the frame once out of for loop than grab one to open the channel and reserve the memory.

On my laptop I can control fps up to 30 using DSHOW. With VFW, I can get only 15 fps regardless of CV_CAP_PROP_FPS. Try this to estimate fps:

#include <time.h>
int EstimateFps()
{
    //VideoCapture cap(0 + CV_CAP_VFW); // open the default camera using VFW driver
    VideoCapture cap(0 + CV_CAP_DSHOW); // open the default camera using DirectShow driver

    if (!cap.isOpened()) // check if we succeeded
        return -1;

    bool bSuccess = false;
    double fpsWanted = 30;
    bSuccess = cap.set(CV_CAP_PROP_FRAME_WIDTH, 640);
    bSuccess = cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
    bSuccess = cap.set(CV_CAP_PROP_FPS, fpsWanted);
    if (!bSuccess)
        cout << endl << fpsWanted << "is not supported";

    Mat frame; //create frame once
    bSuccess = cap.read(frame); // grab a frame to reserve memory
    imshow("frame", frame);

    clock_t start, stop;
    int cc;
    start = clock();
    for (cc = 0; cc<100; cc++) {
        cap.read(frame); // grab a new frame
    }
    stop = clock();
    double timeLoop = (stop - start) / (double)CLOCKS_PER_SEC;
    double fpsLoop = cc / timeLoop;
    cout << endl << "Average FPS:" << fpsLoop << endl;
    cout << endl << "Press Enter to terminate "; cin.get();
    return 0;
}