Estou trabalhando em um experimento de rastreamento de vídeo e fiquei preso a vídeos bastante compactados com o codec MPEG4 DivX 5x / 6x. Sou bastante novo em formatos de imagem, codecs e compactação, mas acho que descobri que estou preso a essa qualidade, a menos que viole a segunda lei da termodinâmica.
Agora, para rastrear meus insetos (sim, é isso que estou fazendo), estou interessado apenas nos quadros I (a taxa de quadros é alta o suficiente) e não estou interessado nos canais de cores U e V, pois eles só têm um valor para cada bloco e, portanto, não me dê a resolução que eu quero. É o canal Y que tem todas as informações que me interessam. Escrevi meu rastreador e ele não pode analisar o vídeo, por isso precisa de uma pasta com fotos.
Agora, minha pergunta é: como posso extrair todos os quadros I para imagens em escala de cinza (apenas canal Y) SEM QUALQUER OUTRA QUALIDADE DE QUALIDADE? Estou trabalhando no ubuntu 14.04 e preferencialmente usaria o ffmpeg ou o imageJ, pois eles já estão presentes no meu pipeline. Onde estou agora é:
Acho que descobri que cada segundo quadro é um quadro I, mas não tenho certeza disso. Eu usei:
ffprobe -show_frames movie.avi | grep -A2 "video" | grep "key_frame"
output:
key_frame=1
key_frame=0
key_frame=1
key_frame=0
key_frame=1
key_frame=0
key_frame=1
key_frame=0
key_frame=1
key_frame=0
--
this goes on for exactly the number of frames, as this bit of code tells me:
ffprobe -show_frames movie.avi | grep -A2 "video" | grep -c "key")
13369
Agora, pensei em descobrir como extrair todos os quadros que eu:
ffmpeg -i movie.avi -vf '[in]select=eq(pict_type\,I)[out]' /picture%d.jpg
Mas parece me devolver todos os quadros.
ls *jpg | wc -l
133370
O que estou fazendo errado? Esta é a saída que o ffmpeg me fornece:
ffmpeg version N-77455-g4707497 Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 4.8 (Ubuntu 4.8.4-2ubuntu1~14.04)
configuration: --extra-libs=-ldl --prefix=/opt/ffmpeg --mandir=/usr/share/man --enable-avresample --disable-debug --enable-nonfree --enable-gpl --enable-version3 --enable-libopencore-amrnb --enable-libopencore-amrwb --disable-decoder=amrnb --disable-decoder=amrwb --enable-libpulse --enable-libdcadec --enable-libfreetype --enable-libx264 --enable-libx265 --enable-libfdk-aac --enable-libvorbis --enable-libmp3lame --enable-libopus --enable-libvpx --enable-libspeex --enable-libass --enable-avisynth --enable-libsoxr --enable-libxvid --enable-libvo-aacenc --enable-libvidstab
libavutil 55. 11.100 / 55. 11.100
libavcodec 57. 20.100 / 57. 20.100
libavformat 57. 20.100 / 57. 20.100
libavdevice 57. 0.100 / 57. 0.100
libavfilter 6. 21.101 / 6. 21.101
libavresample 3. 0. 0 / 3. 0. 0
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
libpostproc 54. 0.100 / 54. 0.100
Guessed Channel Layout for Input Stream #0.1 : stereo
Input #0, avi, from 'movie.avi':
Duration: 00:08:54.76, start: 0.000000, bitrate: 3006 kb/s
Stream #0:0: Video: mpeg4 (Simple Profile) (DX50 / 0x30355844), yuv420p, 720x576 [SAR 16:15 DAR 4:3], 1462 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc
Stream #0:1: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 2 channels, s16, 1536 kb/s
[swscaler @ 0x3c2e920] deprecated pixel format used, make sure you did set range correctly
Output #0, image2, to './picture%d.jpg':
Metadata:
encoder : Lavf57.20.100
Stream #0:0: Video: mjpeg, yuvj420p(pc), 720x576 [SAR 16:15 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
Metadata:
encoder : Lavc57.20.100 mjpeg
Side data:
unknown side data type 10 (24 bytes)
Stream mapping:
Stream #0:0 -> #0:0 (mpeg4 (native) -> mjpeg (native))
Press [q] to stop, [?] for help
frame=13370 fps=506 q=24.8 Lsize=N/A time=00:08:54.80 bitrate=N/A dup=6685 drop=0 speed=20.2x
video:157591kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Então, algumas perguntas:
- O que estou fazendo errado? Por que isso me devolve todos os quadros?
- O jpeg causará mais perdas? Ou é a mesma compactação usada no intra-frame no mpeg4? Talvez eu devesse usar tiff?
- Como extraio apenas o canal y?
- É normal que eu receba um quadro I a cada segundo quadro? Eu tenho lido um pouco sobre a codificação MPEG4 e parece que não quadros inteiros, mas blocos são usados como referência? Estou então extraindo todos os quadros que contêm esses blocos? Existe um nível superior com quadros de referência inteiros "reais"?
- Eu acho que não há como recuperar mais qualidade?
Muito, muito obrigado pela sua ajuda!
Muitas felicidades,
Rik Verdonck
-pix_fmt gray
corresponde diretamente ao componente Y da entrada?