I've been trying to find/implement a seek and rewind function (for video (.avi)) using OpenCV in C++, but I cant find a way of doing it, other than going through the entire file once and saving each image. Is there any other way?
Any help would be much appreciated; Thanks ahead of time!
The VideoCapture class returns a video capture object which we can use to display the video. The class has several methods, for example, there is the get() method which takes a property identifier from cv2.
Capture Video from Camera OpenCV allows a straightforward interface to capture live stream with the camera (webcam). It converts video into grayscale and display it. We need to create a VideoCapture object to capture a video. It accepts either the device index or the name of a video file.
CAP_PROP_POS_FRAMES refers to the current frame position which we set to our variable frame_id. The read function returns the frame itself (that we name frame) and another value 'ret'. If the frame is found this will be True otherwise it will be False.
Read, Write and Display a video using OpenCVCode in C++ and Python is shared for study and practice.
Using cvSetCaptureProperty() you can cycle through frames, either in miliseconds or by ordinal frame number.
int cvSetCaptureProperty( CvCapture* capture, int property_id, double value );
property_id is a property you would need to use. It can be one of the following:
The first two is of your interest.
EDIT: more info :)
You can cycle through frames just by repeatedly calling the mentioned function with various frame indices.
cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, frameIndex);
Example:
IplImage* frame;
CvCapture* capture = cvCreateFileCapture("test.avi");
/* iterate through first 10 frames */
for (int i = 0; i < 10; i++)
{
/* set pointer to frame index i */
cvSetCaptureProperty(capture, CV_CAP_POS_FRAMES, i);
/* capture the frame and do sth with it */
frame = cvQueryFrame(capture);
}
You could put similar code to execute each time user clicks a button to forward/rewind the video.
The C++ method (OpenCV 2 and higher) would be to use this method instead with the same property_id and value.
bool VideoCapture::set(int property_id, double value)
I think you'd have to read in the entire file into an array of IplImages, then work through that. The reason is, cvQueryFrame is a one-way process, it reads one frame at a time in order. I can't think of any other way. Depending on the length of the video the initialisation time may not be too bad.
The cvTrackbars are as you say, mainly used for altering parameters. They alter the value of a variable (given as a parameter in pointer form) and throw a callback function. Unfortunately they are the only button-style elements in HighGUI as far as I know
for C++ and opencv3.4,frame_index is the position you want to seek to.
Mat frame;
VideoCapture capture("test.avi");
capture.set(CAP_PROP_POS_FRAMES, frame_index);
capture>>frame;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With