Comment puis-je extraire une image JPEG de bonne qualité d'un fichier vidéo H264 avec ffmpeg?

108

Actuellement, j'utilise cette commande pour extraire les images:

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

Mais comment puis-je améliorer la qualité d'image JPEG?

Daniel Gartmann
la source
1
Qu'est-ce qui ne va pas avec la qualité actuelle, à part que ce n'est pas «bon»?
bjoernz

Réponses:

215

Utilisation -qscale:v

Utilisez -qscale:v(ou l'alias -q:v) comme option de sortie. La plage effective pour JPEG est de 2 à 31, 31 étant la plus mauvaise qualité. Je recommande d'essayer des valeurs de 2 à 5.

Pour produire une série d'images:

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

Pour produire une seule image à une durée d'environ 60 secondes:

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

Cela fonctionnera avec n'importe quelle entrée vidéo. Voyez ci-dessous si votre entrée est MJPEG.


MJPEG

Si votre entrée est MJPEG (Motion JPEG), les images peuvent être extraites sans aucune perte de qualité.

La sortie de la console ffmpegou ffprobepeut vous dire si votre entrée est MJPEG:

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

Ensuite, vous pouvez extraire les trames à l'aide du mjpeg2jpegfiltre de flux binaire :

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

Regarde aussi

llogan
la source
Cela semble n'avoir aucun effet pour moi - qscale 1 et 2 donnent tous les deux des tailles de fichier identiques et (à mon œil nu) semblent identiques à sans qscale du tout.
felwithe
Pouvez-vous publier la ligne de commande complète que vous utilisez? Veuillez également publier la sortie complète et non coupée de ffmpeg sur la ligne de commande. Notez que le placement des options est pertinent, donc -qscale: v 2 doit être placé après l'option -i inputfile, mais avant l'option du fichier de sortie, pour avoir un effet.
Ronald S. Bultje
1
Pour moi, l'ajout -qmin 1 -qmax 1en plus a -q:v 1doublé la taille du fichier. Et je peux sembler voir une très légère amélioration également.
compliste le
1
@complistic: produit -qmin 1 -qmax 1un fichier plus volumineux, mais me donne exactement la même image. J'ai validé cela via photoshop, 2 couches et filtre de différence. Les pixels sont les mêmes.
cherouvim
@Kostanos Vous pouvez essayer -qmin 1 -q:v 1.
llogan
0

Sortez les images dans un format sans perte tel que PNG:

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

Ensuite, utilisez un autre programme (où vous pouvez spécifier plus précisément la qualité, le sous-échantillonnage et la méthode DCT - par exemple GIMP) pour convertir les PNG que vous voulez en JPEG.

Il est possible d'obtenir des images légèrement plus nettes au format JPEG de cette manière que ce qui est possible avec -qmin 1 -q:v 1et de sortir directement au format JPEG à partir de ffmpeg.

Jake
la source
ffmpeggénère des PNG8fichiers qui n'utilisent que 256 couleurs (comme GIF). donc c'est en fait très perdant.
lapin le
@lapin Les PNG que j'ai extraits en utilisant cette méthode sont de 24 bits (même pour les cadres avec moins de 256 couleurs, bien que d'autres en aient beaucoup plus). Cela utilisait la version 4.2.1 x64 sur Windows. Également écrit ici : "Si je tire des png d'un mp4, avec cette ffmpegcommande [ ], j'obtiens des png de haute qualité qui sont de qualité identique à la vidéo originale." Quelle version de ffmpegutilisez-vous pour générer des PNG8fichiers et quel est votre format d'entrée?
Jake
En fait, je pense que vous avez raison, le problème était que cela identify image.pngdonne un résultat "8 bits" alors qu'en fait ce n'est pas vraiment un canal unique de 8 bits, mais 8 bits pour R, G et B. IDK comment l' identifyutilisateur moyen est censé comprendre que tho.
lapin le