27

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!

Cenoc
  • 11,172
  • 21
  • 58
  • 92
  • 1
    By the way just as tip, the OpenCV seek doesnot work properly on flv's if you get stuck anytime figuring out seeking didn't work. Took me a day to figure it out!!! –  Jun 10 '10 at 09:11

4 Answers4

50

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:

  1. CV_CAP_PROP_POS_MSEC - position in milliseconds from the file beginning
  2. CV_CAP_PROP_POS_FRAMES - position in frames
  3. CV_CAP_PROP_POS_AVI_RATIO - position in relative units (0 - start of the file, 1 - end of the file)
  4. CV_CAP_PROP_FRAME_WIDTH - width of frames in the video stream (only for cameras)
  5. CV_CAP_PROP_FRAME_HEIGHT - height of frames in the video stream (only for cameras)
  6. CV_CAP_PROP_FPS - frame rate (only for cameras)
  7. CV_CAP_PROP_FOURCC - 4-character code of codec (only for cameras).

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)
Jean-Philippe Jodoin
  • 4,536
  • 1
  • 25
  • 28
Adi
  • 1,296
  • 10
  • 13
  • Any examples? Say if I have a .avi file, how would I use this to cycle through the frames? – Cenoc Jun 06 '10 at 22:33
  • Wow, never knew about this! Funny what gaps get left in your knowledge when your too focussed on one thing! – n00dle Jun 10 '10 at 10:32
  • 1
    Can I query a frame in constant time? Or will it take a linear time (or some other polynomial time) to seek to a random position. – siddhant3s Nov 23 '11 at 14:44
  • 1
    This doesn't work with video-codecs that use key frames, in which opencv will just navigate you to a key frame instead. – rumpel Mar 07 '13 at 16:11
  • I'm using CV_CAP_POS_FRAMES, and it's incredible slow. It's little faster than grabbing every frame up to that point. Is OpenCV doing that under the hood? Is there any way to jump into the video in constant time, like you would with a standard video viewer? – Fractaly Nov 12 '17 at 01:20
1

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

n00dle
  • 5,949
  • 2
  • 35
  • 48
1

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;
Xin Yang
  • 413
  • 4
  • 9
0

In the highgui library you'll find functions for a seek bar (cvCreateTrackbar and friends).

Matt Stephenson
  • 8,442
  • 1
  • 19
  • 19
  • the way it's described it doesnt sound like a seekbar; it sounds liek a regular trackbar. Also, every example I found for it online, utilized it for other random shiz, like changing picture hue. – Cenoc Jun 04 '10 at 13:59
  • You can hook the trackbar to any variable/event you want - including the file position. You need to do a littl emore work than a builtin seek bar but it's there – Martin Beckett Mar 08 '11 at 17:41