OpenCV: VideoCapture::get(CV_CAP_PROP_POS_MSEC ) returns 0
I'm trying to timestamp the frames when recording video using OpenCV 3.1.0. However, when using VideoCapture::get(CV_CAP_PROP_POS_MSEC) to get the millisecond timestamp of the last frame grabbed the value returned is always 0.
The code I'm using:
int fps = 10;
VideoCapture cap(0); // open the default camera
cap.set(CV_CAP_PROP_FPS, fps);
cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 1024);
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat testFrame;
cap >> testFrame;
cap >> testFrame;
cap >> testFrame;
Size outSize = Size(testFrame.cols, testFrame.rows);
VideoWriter writer("video.avi", CV_FOURCC('M','J','P','G'), fps, outSize, true);
for(; ;)
{
Mat frame;
cap >> frame; // get a new frame from camera
long stamp = cap.get( CV_CAP_PROP_POS_MSEC ); // THIS DOESN'T SEEM TO WORK
std::cout << "Timestamp: " << stamp << std::endl;
writer.write(frame);
}
As output I always get many lines like the following:
Timestamp: 0
Could you help me understand what I'm doing wrong?
Thanks :)
A s is missing ?
Sorry, that was a typo. The property name was correctly spelled in my code. It compiled and I was able to run it. Let me edit my question to fix that.
You should check return value cap.set(CV_CAP_PROP_FPS, fps); If it is false it means camera driver isn't supported. You have to use a timer or a thread to grab images and write video file
After executing the code I get a video file and when playing it, it looks good. I think there's no problem with the video capture itself. The problem I have is that I need to know the timestamp of each frame in that video file that is written to disk. I've tried with getting the system time, but that wasn't very accurate. Then, I got across this CV_CAP_PROP_POS_MSEC property, but I get 0 with it. Is there any reason why cap.get( CV_CAP_PROP_POS_MSEC ); might not work?
I think video parameter will be good after video file is closed.You can check it after reopen it. You don't need timestamp when you write to video file because you know timestamp when you grab file.
That's not quite right. I need to know the exact time when the frame was capture. If I just get the system time after cap >> frame it can grab a frame from the buffer and that frame might have been capture earlier in time. I need to get as close as real time as possible. Moreover, when using that VideoCapture property from reading a video file instead of from the camera, the value return isn't the timestamp of the frame capture. Sorry, but what you suggested doesn't my problem.
@Yasmina, this property simply is not supported for webcams, only for video files.
you'll have to find another way to get a timestamp.
@berak, is that so? I thought so when I tested it and it didn't work, but then looking at OpenCV's source code I found this "Added v4l2 support for getting capture property CV_CAP_PROP_POS_MSEC. Returns the millisecond timestamp of the last frame grabbed or 0 if no frames have been grabbed Used to successfully synchonize 2 Logitech C310 USB webcams to within 16 ms of one another". Lines 160-162 of file https://github.com/opencv/opencv/blob/master/modules/videoio/src/cap_v4l.cpp
From that I understand that if that property is used to synchronize two webcams, it must work with webcams somehow.
well, you're right, i'm wrong. there is a timestamp taken. just no idea, why it isn't delivered properly.
also note, that there's cap_v4l.cpp and also cap_libv4l.cpp, and it's unclear, which one is used.
i have the same problem. using OpenCV 3.2. self compiled from git. @berak: its not clear which one is used but the functionality is available in both: cap_v4l.cpp https://github.com/opencv/opencv/blob/master/modules/videoio/src/cap_v4l.cpp#L159 (L159) https://github.com/opencv/opencv/blob/master/modules/videoio/src/cap_v4l.cpp#L1651 (L1651) and cap_libv4l.cpp https://github.com/opencv/opencv/blob/master/modules/videoio/src/cap_libv4l.cpp#L194 (L194) https://github.com/opencv/opencv/blob/master/modules/videoio/src/cap_libv4l.cpp#L1414 (L1414).
so this should not make a difference. it seems internally
capture->FirstCapture
evaluates to true all the time.. from a quick poking around in the code i could not find a cause for this... :-( edit: see my 'answer' for more research..