Jak mogę wyodrębnić dobrej jakości obraz JPEG z pliku wideo H264 za pomocą ffmpeg?

110

Obecnie używam tego polecenia, aby wyodrębnić obrazy:

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

Ale jak mogę poprawić jakość obrazu JPEG?

Daniel Gartmann
źródło
1
Co jest złego w obecnej jakości poza tym, że nie jest „dobra”?
bjoernz

Odpowiedzi:

218

Posługiwać się -qscale:v

Użyj -qscale:v(lub aliasu -q:v) jako opcji wyjściowej. Efektywny zakres dla JPEG to 2-31, przy czym 31 to najgorsza jakość. Zalecam wypróbowanie wartości 2-5.

Aby wydrukować serię obrazów:

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

Aby wyświetlić pojedynczy obraz o czasie trwania ~ 60 sekund:

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

Działa to z każdym wejściem wideo. Zobacz poniżej, czy dane wejściowe to MJPEG.


MJPEG

Jeśli wejście to MJPEG (Motion JPEG), obrazy można wyodrębnić bez utraty jakości.

Wynik konsoli ffmpeglub ffprobemoże powiedzieć, czy dane wejściowe to MJPEG:

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

Następnie możesz wyodrębnić ramki za pomocą mjpeg2jpegfiltru strumienia bitów :

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

Zobacz także

llogan
źródło
Wydaje się, że nie ma to dla mnie żadnego efektu - qscale 1 i 2 dają identyczne rozmiary plików i (gołym okiem) wyglądają tak samo jak bez qscale.
felwithe
Czy możesz opublikować całą linię poleceń, której używasz? Prosimy również o umieszczenie w wierszu poleceń pełnego, nieociętego wyniku ffmpeg. Zwróć uwagę, że umieszczanie opcji jest istotne, więc -qscale: v 2 musi zostać umieszczone po opcji -i plik_wejściowy, ale przed opcją pliku wyjściowego, aby miało jakikolwiek efekt.
Ronald S. Bultje
1
Dla mnie dodanie -qmin 1 -qmax 1oprócz -q:v 1podwoił rozmiar pliku. Wydaje się, że widzę również niewielką poprawę.
skomplikowany
1
@complistic: -qmin 1 -qmax 1zaowocowało większym plikiem, ale daje mi dokładnie ten sam obraz. Sprawdziłem to za pomocą Photoshopa, 2 warstw i filtra różnicowego. Piksele są takie same.
cherouvim
@Kostanos Możesz spróbować -qmin 1 -q:v 1.
llogan
0

Wysyłaj obrazy w bezstratnym formacie, takim jak PNG:

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

Następnie użyj innego programu (w którym możesz dokładniej określić jakość, podpróbkowanie i metodę DCT - np. GIMP), aby przekonwertować pliki PNG, które chcesz, na JPEG.

W ten sposób można uzyskać nieco ostrzejsze obrazy w formacie JPEG, niż jest to możliwe w przypadku -qmin 1 -q:v 1bezpośredniego przesyłania w formacie JPEG ffmpeg.

Jake
źródło
ffmpegwyświetla PNG8pliki, które używają tylko 256 kolorów (tak samo jak GIF). więc w rzeczywistości jest bardzo stratna.
Lapin
@lapin Pliki PNG wyodrębnione tą metodą są 24-bitowe (nawet dla ramek z mniej niż 256 kolorami, chociaż inne mają znacznie więcej). Użyto wersji 4.2.1 x64 w systemie Windows. Napisano tu również : „Jeśli pobiorę pliki png z pliku mp4, za pomocą tego ffmpegpolecenia [ ] otrzymam pliki PNG o wysokiej jakości, które są identycznej jakości z oryginalnym wideo”. Jakiej wersji ffmpegużywasz, która generuje PNG8pliki i jaki jest twój format wejściowy?
Jake
Właściwie myślę, że masz rację, problem polegał na tym, że identify image.pngwynik był „8-bitowy”, podczas gdy w rzeczywistości nie jest to tak naprawdę pojedynczy kanał 8-bitowy, ale 8-bitowy dla R, G i B. IDK, jak przeciętny identifyużytkownik powinien zrozumieć że mimo.
okrążenie