Mengekstraksi "satu dari setiap 10 frame" dalam video menggunakan VLC atau FFmpeg

12

Saya mencoba mengekstraksi "persis 1 frame dari setiap 10" frame video (yaitu ekstrak 1, tinggalkan 9 lalu ulangi) untuk tujuan ilmiah. Video ini 105 bingkai, 3,5 detik, 29,97fps (h.264, .mov, diproduksi oleh Nikon D3100).

Saya sudah mengunggahnya di sini .

VLC

Perintah di bawah ini harus menghasilkan 10 frame, tetapi hanya menghasilkan 6 gambar. Saya mencoba rasio adegan yang berbeda dan tak satu pun dari mereka menghasilkan jumlah bingkai yang benar (bahkan tidak dekat dengan benar).

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

Apakah seseorang tolong beri tahu saya apa masalahnya?

FFmpeg

FFmpeg tampaknya tidak memiliki perintah persis untuk tujuan saya. Perintah di bawah ini mengekstrak 3 frame dari setiap detik, tetapi karena FPS tidak tepat 30 (bukan 2,97), itu tidak akan menghasilkan hasil yang benar untuk saya.

Selain itu bahkan FFmpeg tidak memberikan jumlah frame yang benar dengan perintah ini. Untuk 3,5 detik video, saya berharap paling banyak 10 frame, tapi yang saya dapatkan adalah 12 frame!

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

Bagaimana saya bisa mencapai apa yang saya inginkan?

wmac
sumber
1
BTW -sameqtidak melakukan apa yang Anda pikirkan, dan telah dihapus dari versi saat ini (ffmpeg yang sebenarnya, saya tidak yakin apakah itu ada di ffmpeg palsu Ubuntu). Gunakan qscale sebagai gantinya.
stib

Jawaban:

21

Pilih 1 frame dari setiap 10 frame

Anda dapat menggunakan selectfilter video ffmpeguntuk melakukan ini:

ffmpeg -i input.mov -vf "select=not(mod(n\,10))" -vsync vfr -q:v 2 img_%03d.jpg
  • Untuk output JPG Anda dapat memvariasikan kualitas -q:v. Kisaran efektif adalah 2 (kualitas terbaik) hingga 31 (kualitas terburuk). Anda tidak memerlukan opsi ini jika Anda ingin output ke PNG saja.

  • Ini akan menampilkan img_001.jpg, img_002.jpg, img_003.jpg, dll

llogan
sumber
Terlihat sangat menarik, tetapi tampaknya memerlukan beberapa versi tertentu atau sesuatu yang dikompilasi tambahan. Saya mendapatkan " unrecognized option '-filter:v'" dengan "FFmpeg versi 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 --able-zlib --disable-stripping --disable-vhook --enable-runtime-cpudetect - -enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --enable-shared --disable-static)
mivk
Saya juga tidak dapat menjalankan perintah dan menerima kesalahan berikut pada windows ffmpeg N-35709-g7d531e8: [pilih @ 017EBB00] [Eval @ 0022DC08] Hilang ')' atau terlalu banyak argumen dalam 'mod (n \, 10))' [ select @ 017EBB00] Kesalahan saat mem-parsing ekspresi 'not (mod (n \, 10))' Kesalahan inisialisasi filter 'select' with args 'not (mod (n \, 10))' Kesalahan membuka filter!
wmac
@mivk Versi FFmpeg Anda dari repo Ubuntu tidak memiliki kemampuan penyaringan. Anda harus mengkompilasi FFmpeg .
llogan
1
@ wmac Saya kira Windows tidak suka tanda kutip tunggal. Mengubahnya ke tanda kutip ganda: ".
Logan
1
@ LordNeckbeard, terima kasih, ini berjalan dengan benar dan menyelesaikan seluruh masalah. Saya sangat menghargai bantuan Anda.
wmac
4

Aspek yang paling penting dalam pertanyaan Anda adalah kenyataan bahwa video menggunakan 29,97 frame per detik, bukan 30. Pesky NTSC.

Bagaimanapun, saya pikir akan lebih mudah untuk mengekstrak setiap frame , dan kemudian menghapus yang tidak Anda butuhkan:

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

Kemudian, hapus yang tidak Anda butuhkan. Karena setiap frame kesepuluh akan berakhir dengan 1.jpg, kita bisa mengambil yang lainnya ...

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

... dan sekali Anda yakin ini yang ingin Anda hapus:

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

Jika Anda dapat menggunakan mencoder, Anda bisa mencoba framestepopsi, seperti yang dijelaskan dalam dokumentasi , seperti framestep=10dalam kasus Anda. Saya pribadi tidak dapat menginstal / mencobanya.

slhck
sumber
1
Terima kasih banyak atas bantuan dan hasil edit Anda. Saya mencoba mencoder dan bahkan yang satu itu bermasalah! Saya kira itu ada hubungannya dengan codec atau wadah. ffmpeg mengekstrak persis 105 frame dengan perintah di bawah ini: ffmpeg -i 1.mov -y -an -sameq -f image2 -vcodec mjpeg% 03d.jpg tetapi mencoder hanya mengekstrak 90 frame !!! dengan perintah di bawah ini: mplayer -vo png 1.mov Menggunakan framestep = 10 juga menghasilkan jumlah frame yang salah. Saya kaget pada bagaimana ketiganya (ffmpeg, vlc dan mencoder) tidak dapat melakukan tugas sederhana seperti itu dengan benar. Saya mengirimkan laporan bug ke situs web VLC. Terima kasih lagi.
wmac
0

Jika Anda pertama kali mengkonversi video ke serangkaian gambar rgb24 atau rgb32 mentah mungkin, maka Anda mungkin bisa mendapatkan jumlah bingkai yang tepat karena dalam bentuk aslinya tampaknya termasuk jenis bingkai yang tidak biasa yang mungkin bukan gambar sama sekali ?? ?

Dalam Laser Disc asli, seluruh video terdiri dari serangkaian gambar dengan nomor bingkai individual 1 hingga 100.000 atau lebih, dan seperti itulah cara yang benar-benar tepat untuk menetapkan garis dasar untuk konversi atau manipulasi di masa mendatang.

Industri telah mengubah ide kompresi yang aneh ini hanya untuk mengurangi jumlah uang yang dikeluarkan dan untuk merusak bentuk-bentuk ilmiah yang benar dalam menangani angka.

Pertama-tama Anda harus mengekstrak audio apa pun sebagai file gelombang agar tidak kehilangan audio sama sekali. Tampaknya FFMPEG menempatkan informasi pengenal di setiap gambar yang diekstraksi, karena jika Anda mencoba merangkai gambar dari yang baru saja diekstraksi, dan Anda mencampur gambar lain dari sumber lain dengan ekstensi yang sama, ffmpeg akan mengabaikan gambar yang Anda coba potong menjadi bagian dari segalanya .

Dengan format cakram laser, laju bingkai ditentukan dengan laju berapa pun Anda menampilkan gambar berurutan dan tidak dikontrol dengan cara apa pun oleh gambar itu sendiri.

FFMPEG mungkin mengambil pelajaran dari sains alih-alih seni untuk penanganan yang tepat dan tampilan gambar dalam bentuk apa pun. Atau mungkin seluruh industri AV itu sendiri. Industri ini benar-benar perlu meningkatkan kemampuan perangkat keras dan menggunakan data mentah yang membutuhkan banyak memori / penyimpanan. Tidak ada yang mengalahkan data mentah untuk presisi dan akurasi.

Aluetta
sumber