Questão Extraindo “um de cada 10 quadros” em um vídeo usando VLC ou FFmpeg


Eu estou tentando extrair "exatamente 1 quadro de cada 10" quadros de um vídeo (ou seja, extrair 1, deixe 9 e repita) para fins científicos. O vídeo é de 105 quadros, 3,5 segundos, 29,97 fps (h.264, .mov, produzido pela Nikon D3100).

eu tenho carregou aqui.

VLC

O comando abaixo deve produzir 10 quadros, mas produz apenas 6 imagens. Eu tentei diferentes proporções de cena e nenhum deles produz o número correto de quadros (nem perto de corrigir).

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

Alguém poderia me dizer qual é o problema?

FFmpeg

O FFmpeg não parece ter um comando exatamente para o meu propósito. O comando abaixo extrai 3 quadros de cada segundo, mas como o FPS não é exatamente 30 (mais ou menos 2.97), isso não produzirá resultados corretos para mim.

Além disso, mesmo o FFmpeg não fornece números corretos de quadros, mesmo com este comando. Por 3,5 segundos de vídeo eu espero no máximo 10 frames, mas o que eu ganho são 12 frames!

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

Como posso conseguir o que quero?


8


origem


BTW -sameq não faz o que você provavelmente acha que faz, e foi removido da versão atual (o ffmpeg real que é, eu não tenho certeza se ele está no ffmpeg falso do Ubuntu). Use qscale em vez disso. - stib


Respostas:


Selecione 1 quadro de cada 10 quadros

Você pode usar o select filtro de vídeo em ffmpeg para fazer isso:

ffmpeg -i input -vf "select=not(mod(n\,10))" -vsync vfr -q:v 2 img_%03d.jpg
  • Para saída JPG, você pode variar a qualidade com -q:v. O alcance efetivo é 2 (melhor qualidade) a 31 (pior qualidade). Você não precisa desta opção se quiser imprimir em PNG.

  • Isto irá produzir img_001.jpg, img_002.jpg, img_003.jpgetc.


15



Parece muito interessante, mas parece exigir alguma versão particular ou algo extra compilado. Eu recebo "unrecognized option '-filter:v'"com" Versão do FFmpeg 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 --desable-stripping --disable-vhook --enable-runtime-cpudetect --enable- gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --enable-shared --disable-static - mivk
Eu também não posso executar o comando e receber o seguinte erro nas janelas do ffmpeg N-35709-g7d531e8: [selecione @ 017EBB00] [Eval @ 0022DC08] Ausente ')' ou muitos argumentos em 'mod (n \, 10))' [ select @ 017EBB00] Erro ao analisar a expressão 'not (mod (n \, 10))' Erro ao inicializar o filtro 'select' com args 'not (mod (n \, 10))' Erro ao abrir filtros! - wmac
@mivk Sua versão do FFmpeg do repositório do Ubuntu não tem recursos de filtragem. Voce terá que compilar FFmpeg. - LordNeckbeard
@wmac Acho que o Windows não gosta das aspas simples. Altere-as para aspas duplas: ". - LordNeckbeard
@LordNeckbeard, obrigado, corre correto e resolveu todo o problema. Eu realmente aprecio sua ajuda. - wmac


O aspecto mais importante em sua pergunta é o fato de que o vídeo usa 29,97 quadros por segundo, não 30. Pesky NTSC.

Enfim, acho que seria mais fácil apenas extrair cada quadroe remova os que você não precisa:

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

Em seguida, remova os que você não precisa. Como cada décimo quadro terminará com um 1.jpgpodemos apenas pegar todos os outros ...

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

… E assim que tiver certeza de que essas são as que você deseja remover:

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

Se você pode usar mencoder, você poderia tentar o framestep opção, como explicado na documentação, gostar framestep=10 no seu caso. Eu pessoalmente não consegui instalar / experimentar.


4



Muito obrigado pela sua ajuda e sua edição. Eu tentei mencoder e até mesmo aquele tem problema! Eu acho que tem algo a ver com codec ou contêiner. O ffmpeg extrai exatamente 105 quadros com o comando abaixo: ffmpeg -i 1.mov -y -um -sameq -f image2 -vcodec mjpeg% 03d.jpg mas o mencoder apenas extrai 90 quadros !!! com o comando abaixo: mplayer -vo png 1.mov Usar framestep = 10 também produz um número errado de quadros. Estou chocado em como todos os três (ffmpeg, vlc e mencoder) são incapazes de fazer uma tarefa tão simples corretamente. Eu enviei um relatório de bug para o site da VLC. Obrigado novamente. - wmac


Se você fosse primeiro converter o vídeo para uma série de imagens raw rgb24 ou rgb32 possivelmente então você poderia obter o número correto de frames já que na forma original parece haver tipos incomuns de frames que podem não ser imagens? ? Nos discos a laser originais, o vídeo inteiro era composto de uma série de imagens com números de quadros individuais de 1 a 100.000 ou mais e, assim, é realmente a maneira correta de estabelecer uma linha de base para futuras conversões ou manipulações. A indústria mudou para essa estranha ideia de compactação simplesmente para reduzir o dinheiro perdido e para corromper as verdadeiras formas científicas de lidar com números. Você deve primeiro extrair qualquer áudio como um arquivo wave para não perder totalmente o áudio. Parece que o FFMPEG coloca informações de identificação em cada imagem extraída, porque se você tentar juntar imagens das que acabaram de ser extraídas e misturar outras imagens de outras fontes com a mesma extensão, o ffmpeg irá ignorar as imagens que você tentou incluir no meio de tudo. Com o formato de disco laser, a taxa de quadros é simplesmente ditada por qualquer taxa que você apresente as imagens seqüenciais e não seja controlada de forma alguma pelas próprias imagens. O FFMPEG pode aprender com a ciência em vez da arte para o manuseio e exibição de imagens de qualquer tipo. Ou possivelmente toda a indústria de AV. A indústria realmente precisa melhorar os recursos do hardware e usar dados brutos que exigem muita memória / armazenamento. Nada supera dados brutos para precisão e precisão.


0