Welcome to extractframes’s documentation!

Overview

What does it do?

The extract.py script will take an input video and extract all the frames from it as JPEG files. It can give you just a particular range of the frames, and it can change the frame rate by Linear Frame Sampling. So for instance, if you want half as many frames as there are in the input, it will take every other frame. If you want twice as many frames, it will take every frame twice. It can also select frames by time, not just frame number.

First make it correct, then make it fast

extract.py places an emphasis on correctness rather than speed. It uses the ffmpeg program to extract all of the frames in the input video, at the original frame rate. Only then does it select particular frames to copy, or change frame rates. This is because ffmpeg is not totally reliable when you ask it to change rates. It is used because of its very extensive support for video formats.

When it extracts frames from video, ffmpeg starts numbering them from 1. But for our purposes, it’s more useful to have them numbered from 0. If this is a problem, it wouldn’t be too hard to add an option to change this.

Linear Frame Sampling

extract.py doesn’t ever “make up” image data. All it can do is leave out or duplicate frames. This might lead to problems with e.g. change detection. For example, take a video stream that has been converted from 25 to 30 frames per second:

digraph conversion {
in0->out0
in1->out1
in2->out2
in3->out3
in4->out4
in4->out5
}

The changes between frame out4 and frame out5 will always be zero! So that means that, for example, camN_dyn_objM will have a spurious zero, one time out of every 6 samples.

I’m not sure about the right way to deal with this.

Getting extractframes

This documentation is for extractframes version 0.16.

The latest documentation should always be available at http://tgs.github.com/extractframes/

You can always get the latest released version at https://einstein.psych.indiana.edu/downloads/python/ (if you work in our lab at IU), or from GitHub at https://github.com/tgs/extractframes

Download the latest .zip file for extractframes, and then either run easy_install extractframes-a.b.zip or extract it and run python setup.py install. If either of those don’t work, there’s probably some problem with your Python installation.

extractframes is tested with Python versions 2.5 through 2.7

Using extractframes

Running extract.py

The extract.py script extracts frames from a video in a controllable way. It is called like this:

extract.py [options] input_movie output_format
input_movie
Some movie file in a format that ffmpeg understands. Windows .avi files and Apple .mov files should work fine, among many others.
output_format
A pattern for producing output files. For example, if you want your files to look like img_99.jpg and be in the output directory, then you could say output/img_%5d.jpg. The %05d in the format is what turns the number 99 into the string 99 that becomes part of the filename. Here are some examples when formatting the number 99:
Formatting examples
Format Result Comment
img_%d.jpg img_99.jpg Commonly used in our projects.
img_%05d.jpg img_00099.jpg Adds zeros until exactly 5 digits long—Usually sorts in a better way than above.
img_%5d.jpg img_   99.jpg Adds spaces till 5 characters long—usually not what you want.

Options

--take <BEGIN-END>[,<BEGIN-END>,...]

After extracting all the frames from the input, which are numbered starting with 0, take only the frames from BEGIN to END inclusive. They are renumbered to start with 0 in the output directory, so if you said extract.py --take 10-20 infile.avi out%d.jpg, then you would get out0.jpg through out10.jpg (eleven frames). This is not particularly efficient, see this discussion.

If you specify multiple ranges of frames, separated with commas, then they will all be extracted. If you extract multiple ranges of frames, the first frame of the first range is renumbered to be 0, but the intervals between ranges are preserved. For instance, if you say extract.py --take 10-20,30-40 infile.avi img_%d.jpg, then you would get img_0.jpg through img_10.jpg, then a gap, and then img_20.jpg through img_30.jpg. Why 20? Because 30 (the start of the second range) minus 10 (the start of the first range) is 20.

To specify a range that is only one frame long, use the same number twice. E.g. getting just frame 8, say --take 8-8. But note that, if you use --squish-to, such a short frame range may get entirely left out of the output.

If you use multiple ranges, then they must not overlap, and they must be listed in increasing order.

--take-times <BEGIN-END>[,<BEGIN-END>,...]

After extracting all the frames from the input, take only the frames that fall between BEGIN and END seconds from the start of the video. The video is assumed to be at the American standard of approximately 29.97 frames per second for this calculation. For example, if you said extract.py --take-times 0-15.5 infile.avi out%d.jpg, then you would get out0.jpg through out464.jpg (465 frames). If you’re counting frames, you should know that the American standard frame rate is actually not 29.97 but 30 * \frac{1000}{1001} \approx 29.970029970 frames per second. This is only important if you have many thousands of frames.

--stretch-to <FRAMES>, --squish-to <FRAMES>

Change how many frames there will be in the output, by stretching or squishing time—that is, by changing the frame rate. If your input has 100 frames and you say –stretch-to 200, then the output will have two copies of each frame. This option is applied after --take or --take-times, so extract.py will first take the frames that you select, and then stretch or squish those frames to fill the output requirement.

If you use multiple frame ranges in --take or --take-times, then these options will stretch or squish the outer bounds of the whole range. For example, --take 0-9,20-29 --squish-to 10 will get you frames 0-2 and 6-9.

--keep-numbers

Normally, the output frames are renumbered so that the first frame in the given bounds is frame 0. --keep-numbers overrides this, so that the output frames have the same numbers as the bounds you specified (although this is not any faster than normal: [1]). So if you say extract.py --take 10-20 --keep-numbers infile.avi out%d.jpg, the output files will be out10.jpg through out20.jpg.

If you use this option with --stretch-to, then the first frame number will be the same as the first number you specify with --take, but the last number will be different because there is a different number of frames.

If you use this with multiple frame ranges, it only aligns the start of the first frame range.

[1]Under the hood, there is still renumbering happening, because ffmpeg numbers frames starting with 1 but we start them with 0. So, unfortunately, --keep-numbers is not any faster than the normal mode.