Erratic fps from VideoCapture opencv - c++

I get the fps from video files using opencv.
It works well for all videos that I have, except those videos recorded by my phone (samsung note). I am getting fps=90000 by calling VideoCapture::get(CV_CAP_PROP_FPS) for. I verified the properties of video files taken by phone, they seem that no problem with recorded files (fps = 30), but when I get fps by opencv its erratic value!
Does any get this problem? any suggestion?
EDIT:
VideoCapture input_video("20.mp4"); // here I read a file, recorded by cameraphone
double fps=input_video.get(CV_CAP_PROP_FPS);
cout<<fps<<endl; // prints 90000 !!!!!
// continue without problem

Related

Error on Video Indexing process with .mp4 videos

I'm trying without any success to index a .mp4 video. I get an error arount the 70% of the indexing process.
I've received an email saying that the file format it's not supported and it seems strange to me.
This is the ID:
Trial---7a3be47a47---e9dfcb48-8e35-4e04-b682-73cbc20310ee---job-7a3be47a47-input-251f3-SingleBitrate720pEncode-EncodingJob-251f3-r1
Can you please help me on this issue?
it seems that your video has avg_frame_rate of 1000 fps and r_frame_rate of 1000 fps which causes it to fail. We don't support such high fps.
Can you encode the video to a lower frame rate, for example 30 fps, and try again?

using OpenCV to capture images, not video

I'm using OpenCV4 to read from a camera. Similar to a webcam. Works great, code is somewhat like this:
cv::VideoCapture cap(0);
cap.set(cv::CAP_PROP_FRAME_WIDTH , 1600);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 1200);
while (true)
{
cv::Mat mat;
// wait for some external event here so I know it is time to take a picture...
cap >> mat;
process_image(mat);
}
Problem is, this gives many video frames, not a single image. This is important because in my case I don't want nor need to be processing 30 FPS. I actually have specific physical events that trigger reading the image from the camera at certain times. Because OpenCV is expecting the caller to want video -- not surprising considering the class is called cv::VideoCapture -- it has buffered many seconds of frames.
What I see in the image is always from several seconds ago.
So my questions:
Is there a way to flush the OpenCV buffer?
Or to tell OpenCV to discard the input until I tell it to take another image?
Or to get the most recent image instead of the oldest one?
The other option I'm thinking of investigating is using V4L2 directly instead of OpenCV. Will that let me take individual pictures or only stream video like OpenCV?

How do we skip frame, calculate number of frames and get current frame with video reader

I am using Opencv for video decoding now. I can play the video with no problem. However, I could not find a way to skip frame, get total number of frames and current frame number. Is there a way to use VideoReader like VideoCapture? I have gone through their api and could not get anything.
OpenCV is Open Source library. If you use VideoCapture then the object of this class has any methods:
To skip a frame you should read 2 times a frame.
To get total number of frames as follows:
cv::VideoCapture m_capture;
....
int totalFrames = m_capture.get(cv::CAP_PROP_FRAME_COUNT)
To get a current frame number:
int currentFrame = m_capture.get(cv::CAP_PROP_POS_FRAMES)
For detailed information visit the OpenCV documentation https://docs.opencv.org/3.1.0/d8/dfe/classcv_1_1VideoCapture.html.

OpenCV VideoCapture Partial Frame Corruption

I recently started using OpenCV for a project involving reading videos. I followed tutorials online for video's reading and the video seems to be read with no problems. However, when I display any frame from the video, the far right column appears to be corrupted. Here is the code I used for reading and displaying the first frame.
VideoCapture cap("6.avi");
Mat frame;
cap>>frame;
imshow("test",frame);
waitKey(0);
This resulted in a frame that looks good for the most part except the far right column. See here.
I am making no modifications to the video or frames before displaying it. Can anyone help figure out why this is happening?
Note: I'm running Ubuntu 14.04, OpenCV version 2.4.8
Full video can be found here.
Your code looks fine to me. Are you certain the frame is corrupted? Resize, maximize, minimize the "test" GUI window to see if the right edge is still corrupted. Sometimes while displaying really small images, I've seen the right edge of the GUI window display incorrectly even though the frame is correct. You could also try imwrite("test.png",frame) to see if the saved image is still corrupted.
If this doesn't help, it would seem like a codec problem. Ensure you have the latest version of opencv, ffmpeg.
If this still doesn't help, the video itself may be corrupted. You could try converting it into another format using ffmpeg

OpenCV: cant get framerate from video

I want to get framerate for video but I always get -nan on linux.
VideoCapture video(input);
if (!video.isOpened()) // zakoncz program w przypadku, problemu z otwarciem
{
exit(0);
}
double fps = video.get(CV_CAP_PROP_FPS);
My openCv version is 2.4.7. The same code works fine on windows.
My guess is that it's camera dependent. Some (API) functions are sometimes not implemented in OpenCV and/or supported by your camera. Best would be if you check the code on github.
Concerning your problem: I am able to get the frame rates with a normal webcam and a XIMEA camera with your code.
Tested on:
Ubuntu 15.04 64bit
OpenCV 3.0.0 compiled with Qt and XIMEA camera support
You could measure your frame rate yourself:
double t1 = (double)cv::getTickCount();
// do something
t1 = ((double)cv::getTickCount() - t1)/cv::getTickFrequency();
Gives you the time that //do something spent.
It is from a file, you can try to estimate it yourself.
VideoCapture video("name_of_video.format");
int frameCount = (int)video.get(CV_CAP_PROP_FRAME_COUNT) ;
//some times frame count is wrong, so you can verify
video.set(CV_CAP_PROP_POS_FRAMES , frameCount-1);
//try to read the last frame, if not decrement frame count
while(!(video.read(nextFrame))){
frameCount--;
video.set(CV_CAP_PROP_POS_FRAMES , frameCount-1);
}
//it is already set above, but just for clarity
video.set(CV_CAP_PROP_POS_FRAMES , frameCount-1);
double fps = (double)(1000*frameCount)/( video.get(CV_CAP_PROP_POS_MSEC));
cout << "fps: " << fps << endl;
This is how I get framerate when using CV_CAP_PROP_FPS fails
The question doesn't clarify if this refers to video from a live source (webcam) or from a video file.
If the latter, the capabilities of OpenCV will depend on the format and codecs used in the file. For some file formats, expect to get a 0 or NaN.
If the former, the real fps of the source may not be returned, especially if the requested framerate is not supported by the hardware, and a different one is used instead. For this case I would suggest an approach similar to #holzkohlengrill's, but only do that calculation after an initial delay of say 300ms (YMMV), as grabbing of the first frames and some initialisations happening can mess with that calculation.