I'm playing with OpenCV and two webcams (Logitech C525, max 720p@30fps and TedGem 1080, max 1080p@30fps). I would like to write to disk those 30 fps, but I'm only getting ~28 for the Logitech and ~24 for the TedGem.
My approach is: launch a thread that reads frames and writes them to disk, wait for 5 seconds using usleep, and raise a stop flag. Theoretically, I should have recorded ~150 frames (30fps, 5 seconds), but I only get 140 for the Logitech and 117 for the TedGem. Is this a hardware limitation, or is there something wrong with the code? Is is possible to save raw images, and not jpg compressed ones so I can maybe save some time?
I've tried also with separate threads for writing and reading, and even different resolutions, with the same results.
#include "opencv2/opencv.hpp"
#include "iostream"
#include "thread"
#include <unistd.h>
using namespace cv;
VideoCapture camera(0);
bool stop = false;
int fc = 0;
void saveFrames()
{
while(!stop)
{
Mat frame;
camera >> frame;
// camera.read(frame); // same results with this one
cv::imwrite("frames/frame" + std::to_string(fc) + ".jpg", frame);
fc++;
}
}
int main()
{
if(!camera.isOpened())
return -1;
camera.set(CV_CAP_PROP_FRAME_WIDTH,1280);
camera.set(CV_CAP_PROP_FRAME_HEIGHT,720);
camera.set(CV_CAP_PROP_FPS,30);
double fps = camera.get(CV_CAP_PROP_FPS);
std::thread tr(saveFrames);
usleep(5e6);
stop = true;
tr.join();
std::cout << "Written " << fc << " frames of " << fps * 5 << std::endl;
return 0;
}
If, instead of using threading, I just call the read routine 300 times to get 300 frames, even without calling imwrite, and use std::chrono to count the time, I get 10.35 seconds for the 300 frames (~28.91fps).
More data after more testing: I've switched to std::chrono in order to measure the time since the polling start until the end. It does not seem to be a noticeable difference between a threaded and non-threaded version, or between a read-image-only and read-and-write versions. According chrono, I almost reach 29 fps with the Logitech but still 26.5 fps with the TedGem.