Extraindo "um de cada 10 quadros" em um vídeo usando VLC ou FFmpeg

12

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

Fiz upload aqui .

VLC

O comando abaixo deve produzir 10 quadros, mas produz apenas 6 imagens. Tentei proporções de cenas diferentes e nenhuma delas produziu o número correto de quadros (nem mesmo 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 por segundo, mas como o FPS não é exatamente 30 (em vez de 2,97), isso não produzirá resultados corretos para mim.

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

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

Como posso conseguir o que quero?

wmac
fonte
1
BTW -sameqnão faz o que você provavelmente pensa que faz e foi removido da versão atual (o ffmpeg real, ou seja, não tenho certeza se está no ffmpeg falso do Ubuntu). Use qscale.
Stib #

Respostas:

21

Selecione 1 quadro em cada 10 quadros

Você pode usar o selectfiltro de vídeo ffmpegpara fazer isso:

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

  • Esta saída vontade img_001.jpg, img_002.jpg, img_003.jpg, etc.

llogan
fonte
Parece muito interessante, mas parece exigir uma versão específica ou algo extra compilado. Eu recebo " unrecognized option '-filter:v'" com "a versão SVN-r0.5.1-4 do FFmpeg: 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
Também não consigo executar o comando e recebo o seguinte erro no ffmpeg windows N-35709-g7d531e8: [selecione @ 017EBB00] [Eval @ 0022DC08] Faltando ')' ou muitos argumentos em 'mod (n \, 10))' [ select @ 017EBB00] Erro ao analisar a expressão 'not (mod (n \, 10))' Erro ao inicializar o filtro 'selecione' com args 'not (mod (n \, 10))' Erro ao abrir filtros!
wmac
@mivk Sua versão do FFmpeg do repositório Ubuntu não possui recursos de filtragem. Você precisará compilar o FFmpeg .
Llogan
1
@ wmac Acho que o Windows não gosta de aspas simples. Mudá-los para aspas: ".
Llogan
1
@ LordNeckbeard, obrigado, ele roda correto e resolveu todo o problema. Eu realmente aprecio sua ajuda.
Wmac
4

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

Enfim, acho que seria mais fácil extrair todos os quadros e remover 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 todo décimo quadro termina com um 1.jpg, podemos pegar todos os outros…

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

… E quando tiver certeza de que estes são os que você deseja remover:

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

Se você pode usar mencoder, você pode tentar a framestepopção, conforme explicado na documentação , como framestep=10no seu caso. Pessoalmente, não consegui instalar / experimentar.

slhck
fonte
1
Muito obrigado por sua ajuda e sua edição. Eu tentei o mencoder e até esse 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 -an -sameq -f image2 -vcodec mjpeg% 03d.jpg mas o mencoder extrai apenas 90 quadros !!! com o comando abaixo: mplayer -vo png 1.mov O uso de framestep = 10 também produz um número incorreto de quadros. Estou chocado com a forma como os três (ffmpeg, vlc e mencoder) não conseguem executar corretamente uma tarefa tão simples. Enviei um relatório de bug ao site do VLC. Obrigado novamente.
wmac
0

Se você primeiro converter o vídeo em uma série de imagens rgb24 ou rgb32, possivelmente poderá obter o número certo de quadros, pois, na forma original, parece incluir tipos de quadros incomuns que podem não ser imagens? ?

Nos discos a laser originais, o vídeo inteiro era composto por 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 idéia de compressão, simplesmente para reduzir o dinheiro gasto e corromper as verdadeiras formas científicas de manipulação de 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 agrupar imagens das que foram extraídas e misturar outras imagens de outras fontes com a mesma extensão, o ffmpeg ignorará as imagens que você tentou colocar no meio de tudo .

Com o formato de disco a laser, a taxa de quadros é simplesmente ditada pela taxa que você apresentar nas imagens sequenciais e não é controlada de forma alguma pelas próprias imagens.

O FFMPEG pode tirar uma lição da ciência, em vez da arte, para manuseio e exibição adequados de imagens de qualquer tipo. Ou possivelmente toda a indústria de AV. O setor realmente precisa melhorar os recursos do hardware e usar dados brutos que requerem muita memória / armazenamento. Nada supera os dados brutos para precisão e exatidão.

Aluetta
fonte