Come posso estrarre un'immagine JPEG di buona qualità da un file video H264 con ffmpeg?


108

Attualmente sto usando questo comando per estrarre le immagini:

ffmpeg.exe -i 10fps.h264 -r 10 -f immagine2 10fps.h264_% 03d.jpeg

Ma come posso migliorare la qualità dell'immagine JPEG?


1
Cosa c'è che non va nella qualità attuale, a parte che non è "buona"?
bjoernz

Risposte:


215

Uso -qscale:v

Usa -qscale:v(o l'alias-q:v ) come opzione di output. La gamma effettiva per JPEG è 2-31 con 31 è la qualità peggiore. Consiglio di provare valori di 2-5.

Per produrre una serie di immagini:

ffmpeg -i input.mp4 -qscale:v 2 output_%03d.jpg

Per produrre una singola immagine della durata di ~ 60 secondi:

ffmpeg -ss 60 -i input.mp4 -qscale:v 4 -frames:v 1 output.jpg

Funzionerà con qualsiasi ingresso video. Vedi sotto se il tuo input è MJPEG.


MJPEG

Se il tuo input è MJPEG (Motion JPEG), le immagini possono essere estratte senza alcuna perdita di qualità.

L' output della console ffmpego ffprobepuò dirti se il tuo input è MJPEG:

$ ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=nw=1 input.avi
codec_name=mjpeg

Quindi puoi estrarre i frame usando il mjpeg2jpegfiltro bitstream :

$ ffmpeg -i input.avi -codec:v copy -bsf:v mjpeg2jpeg output_%03d.jpg

Vedi anche


Questo sembra non avere alcun effetto per me: qscale 1 e 2 danno entrambi dimensioni di file identiche e (a occhio nudo) appaiono uguali senza qscale.
felwithe

Puoi pubblicare la riga di comando completa che stai utilizzando? Inoltre, invia l'output completo e non tagliato da ffmpeg sulla riga di comando. Notare che il posizionamento delle opzioni è rilevante, quindi -qscale: v 2 deve essere posizionato dopo l'opzione -i inputfile, ma prima dell'opzione del file di output, per avere effetto.
Ronald S. Bultje

1
Per me l'aggiunta -qmin 1 -qmax 1oltre al -q:v 1raddoppio della dimensione del file. E mi sembra di vedere anche un leggerissimo miglioramento.
complistic

1
@complistic: ha -qmin 1 -qmax 1prodotto un file più grande, ma mi dà esattamente la stessa immagine. L'ho convalidato tramite Photoshop, 2 livelli e filtro di differenza. I pixel sono gli stessi.
cherouvim

@Kostanos Puoi provare -qmin 1 -q:v 1.
llogan

0

Produci le immagini in un formato senza perdita di dati come PNG:

ffmpeg.exe -i 10fps.h264 -r 10 -f image2 10fps.h264_%03d.png

Quindi usa un altro programma (dove puoi specificare più precisamente la qualità, il sottocampionamento e il metodo DCT, ad esempio GIMP) per convertire i PNG che desideri in JPEG.

In questo modo è possibile ottenere immagini leggermente più nitide in formato JPEG rispetto a quanto è possibile con l' -qmin 1 -q:v 1output come JPEG direttamente da ffmpeg.


ffmpegproduce PNG8file che utilizzano solo 256 colori (come GIF). quindi è in realtà molto lossy.
lapin

@lapin I PNG che ho estratto usando questo metodo sono a 24 bit (anche per i frame con meno di 256 colori, sebbene altri ne abbiano molti di più). Questo utilizzava la versione 4.2.1 x64 su Windows. Anche scritto qui è: "Se estraggo png da un mp4, con questo [ffmpeg comando ], ottengo png di alta qualità che sono della stessa qualità del video originale." Quale versione di ffmpegstai utilizzando per l'output di PNG8file e qual è il tuo formato di input?
Jake

In realtà penso che tu abbia ragione, il problema era che identify image.pngdà il risultato "8 bit" quando in realtà non è realmente un singolo canale a 8 bit, ma 8 bit per R, G e B. IDK come identifydovrebbe capire l' utente medio quel tho.
lapin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.