¿Cómo puedo extraer una imagen JPEG de buena calidad de un archivo de video H264 con ffmpeg?

108

Actualmente estoy usando este comando para extraer las imágenes:

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

Pero, ¿cómo puedo mejorar la calidad de la imagen JPEG?

Daniel Gartmann
fuente
1
¿Qué tiene de malo la calidad actual, aparte de que no es "buena"?
bjoernz

Respuestas:

215

Utilizar -qscale:v

Utilice -qscale:v(o el alias-q:v ) como una opción de salida. El rango efectivo para JPEG es 2-31, siendo 31 la peor calidad. Recomiendo probar valores de 2-5.

Para generar una serie de imágenes:

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

Para generar una sola imagen con una duración de ~ 60 segundos:

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

Esto funcionará con cualquier entrada de video. Vea a continuación si su entrada es MJPEG.


MJPEG

Si su entrada es MJPEG (Motion JPEG), las imágenes se pueden extraer sin pérdida de calidad.

La salida de la consola ffmpego ffprobepuede decirle si su entrada es MJPEG:

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

Luego, puede extraer los marcos usando el mjpeg2jpegfiltro de flujo de bits :

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

Ver también

llogan
fuente
Esto parece no tener ningún efecto para mí: qscale 1 y 2 dan tamaños de archivo idénticos y (a simple vista) parecen iguales que sin qscale.
felwithe
¿Puedes publicar la línea de comandos completa que estás usando? También publique el resultado completo y sin cortar de ffmpeg en la línea de comandos. Tenga en cuenta que la ubicación de las opciones es relevante, por lo que -qscale: v 2 debe colocarse después de la opción -i inputfile, pero antes de la opción de archivo de salida, para que tenga algún efecto.
Ronald S. Bultje
1
Para mí agregando -qmin 1 -qmax 1además de -q:v 1duplicar el tamaño del archivo. Y puedo parecer ver una mejora muy leve también.
complementaria
1
@complistic: -qmin 1 -qmax 1resultó en un archivo más grande, pero me da exactamente la misma imagen. Validé esto a través de photoshop, 2 capas y filtro de diferencia. Los píxeles son los mismos.
Cherouvim
@Kostanos Puedes intentarlo -qmin 1 -q:v 1.
llogan
0

Imprima las imágenes en un formato sin pérdidas como PNG:

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

Luego use otro programa (donde puede especificar con mayor precisión la calidad, el submuestreo y el método DCT, por ejemplo, GIMP) para convertir los PNG que desea a JPEG.

Es posible obtener imágenes ligeramente más nítidas en formato JPEG de esta manera de lo que es posible con una -qmin 1 -q:v 1salida como JPEG directamente desde ffmpeg.

Jake
fuente
ffmpeggenera PNG8archivos que usan solo 256 colores (igual que GIF). por lo que en realidad tiene mucha pérdida.
lapin
@lapin Los PNG que extraje con este método son de 24 bits (incluso para fotogramas con menos de 256 colores, aunque otros tienen muchos más). Esto estaba usando la versión 4.2.1 x64 en Windows. Aquí también está escrito : "Si extraigo png de un mp4, con este ffmpegcomando [ ], obtengo png de alta calidad que son de la misma calidad que el video original". ¿Qué versión de ffmpegestá usando para generar PNG8archivos y cuál es su formato de entrada?
Jake
En realidad, creo que tienes razón, el problema es que identify image.pngda un resultado de "8 bits" cuando en realidad no es un canal único de 8 bits, sino de 8 bits para R, G y B. IDK cómo identifyse supone que el usuario promedio debe entender eso aunque.
lapin