Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am trying to extract "exactly 1 frame of every 10" frames of a video (i.e. extract 1 , leave 9 then repeat) for scientific purposes. The video is 105 frames, 3.5 seconds, 29.97fps (h.264, .mov, produced by Nikon D3100).

I have uploaded it here.

VLC

Below command should produce 10 frames, but it only produces 6 images. I tried different scene ratios and neither of them produce correct number of frames (not even near to correct).

vlc 1.mov --video-filter=scene --vout=dummy --scene-ratio=10 --scene-prefix=img- --scene-path=. vlc://quit

Would someone please tell me what is the problem?

FFmpeg

FFmpeg does not seem to have a command exactly for my purpose. Below command extracts 3 frames out of every second, but since the FPS is not exactly 30 (rather 2.97), that will not produce correct results for me.

In addition even FFmpeg does not give out correct number of frames with even this command. For 3.5 seconds of video I expect at most 10 frames, but what I get is 12 frames!

ffmpeg -i 1.mov -y -an -sameq  -r 3 -f image2 -vcodec mjpeg %03d.jpg 

How can I achieve what I want?

share|improve this question
    
BTW -sameq doesn't do what you probably think it does, and has been removed from the current version (the real ffmpeg that is, I'm not sure if it's in the Ubuntu fake ffmpeg). Use qscale instead. –  stib Apr 22 at 2:38

3 Answers 3

up vote 4 down vote accepted

You can use the select and setpts video filters in ffmpeg to do this:

ffmpeg -i input -filter:v "select=not(mod(n\,10)),setpts=N/((30000/1001)*TB)" \
-qscale:v 2 output%03d.jpg
  • This should select 1 frame out of every 10 frames.

  • setpts="N/((30000/1001)*TB)" is required or ffmpeg will repeat images. The value multiplied by TB should be equal to the frame rate of your input, which is, in your case, NTSC video being 30000/1001. NTSC film is 24000/1001. PAL video can simply be 25. See video rate for more examples.

  • For JPG output you can vary quality with -qscale:v. Range is 2 (best quality) to 31 (worst quality).

share|improve this answer
    
Looks very interesting, but seems to require some particular version or something extra compiled-in. I get "unrecognized option '-filter:v'" with "FFmpeg version SVN-r0.5.1-4:0.5.1-1ubuntu1.3" (--enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --disable-stripping --disable-vhook --enable-runtime-cpudetect --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --enable-shared --disable-static) –  mivk Feb 19 '12 at 21:54
    
I also cannot run the command and receive the following error on ffmpeg windows N-35709-g7d531e8: [select @ 017EBB00] [Eval @ 0022DC08] Missing ')' or too many args in 'mod(n\,10))' [select @ 017EBB00] Error while parsing expression 'not(mod(n\,10))' Error initializing filter 'select' with args 'not(mod(n\,10))' Error opening filters! –  wmac Feb 20 '12 at 5:22
    
@mivk Your FFmpeg version from the Ubuntu repo does not have filtering capabilities. You will have to compile FFmpeg. –  LordNeckbeard Feb 20 '12 at 19:33
    
@wmac I guess Windows doesn't like the single quotes. Change them to double quotes: ". –  LordNeckbeard Feb 20 '12 at 19:52
1  
@LordNeckbeard, thanks, it runs correct and solved the whole problem. I really really appreciate your help. –  wmac Feb 21 '12 at 1:52

The most important aspect in your question is the fact that the video uses 29.97 frames per second, not 30. Pesky NTSC.

Anyway, I think it would be easiest to just extract every frame, and then remove the ones you don't need:

ffmpeg -i 1.mov -y -f image2 -c:v mjpeg %03d.jpg

Then, remove the ones you don't need. Since every tenth frame will end with a 1.jpg, we can just take all the others …

find . -maxdepth 1 -not -iname "*1.jpg"

… and once you're sure these are the ones you want to remove:

find . -maxdepth 1 -not -iname "*1.jpg" -exec rm '{}' \;

If you can use mencoder, you could try the framestep option, as explained in the documentation, like framestep=10 in your case. I personally couldn't install/try it though.

share|improve this answer
    
Thank you very much for your help and your edit. I tried mencoder and even that one has problem! I guess it has something to do with either codec or container. ffmpeg extracts exactly 105 frames with below command: ffmpeg -i 1.mov -y -an -sameq -f image2 -vcodec mjpeg %03d.jpg but mencoder only extracts 90 frames!!! with below command: mplayer -vo png 1.mov Using framestep=10 also produces wrong number of frames. I am shocked on how all three (ffmpeg, vlc and mencoder) are unable to do such a simple task correctly. I submited a bug report to VLC website. Thanks again. –  wmac Feb 18 '12 at 17:56

If you were to first convert the video to a series of raw rgb24 or rgb32 images possibly then you might be able to get the right number of frames since in original form there seems to include unusual frame types that may not be images at all ??? In the original Laser Discs the entire video was composed of a series of images with individual frame numbers 1 to 100,000 or more and like that is really the correct way to establish a baseline for future conversions or manipulations. The industry has changed to this strange compression idea simply to reduce monies outlaid and to corrupt true scientific forms of handling numbers. You must first extract any audio as a wave file so as not to loose audio entirely. It seems FFMPEG puts identifying info in each extracted image because if you try to string images together from ones just extracted and you mix other images from other sources with same extension ffmpeg will ignore the images you tried to piece into the middle of everything. With the laser disc format the frame rate is simply dictated by whatever rate you present the sequential images and not controlled in any way by the images themselves. FFMPEG might take a lesson from science instead of art for proper handling and display of images of any kind. Or possibly the entire AV industry itself. The industry really needs to improve capabilities of the hardware and use raw data which requires lots of memory/storage. Nothing beats raw data for precision and accuracy.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.