Linux: Wie extrahiert man Frames aus einem Video? (verlustfrei)

Linux: Wie extrahiert man Frames aus einem Video? (verlustfrei)

Ich habe einige Antworten und Artikel zur Verwendung von Programmen wie VLC, MPlayer, ffmpegusw. gelesen, aber keine der Methoden, die ich gesehen habe, ist „verlustfrei“. Sie erfassen nicht jedes einzelne Bild. Ich möchte jedes Bild aus einem Video als Bild extrahieren (100 % Qualität, ich möchte keine Details verlieren), also könnte man theoretisch diese Bilder nehmen und die Videodatei neu erstellen, ohne den Unterschied zum Original erkennen zu können (abgesehen vom fehlenden Ton natürlich).

Bonuspunkte gibt es, wenn ich eine Start- und Endzeit zum Aufnehmen von Frames angeben kann, sodass ich die Videodatei nicht vorher zuschneiden muss.

Antwort1

Sie können die Frames als PNG extrahieren, ein verlustfreies Bildkomprimierungsformat. So extrahieren Sie beispielsweise Frames von der 5-Minuten-Marke bis zur 10-Minuten-Marke:

ffmpeg -ss 05:00 -i <input> -t 05:00 filename%05d.png

Antwort2

Es gibt mehrere Tools, mit denen alle Frames aus einer Filmdatei extrahiert werden können:

avconv
avconv -i file.avi -f image2 Out%00d.jpg

ffmpeg
ffmpeg -i input.file thumb%04d.png -hide_banner

Dadurch kann auch BMP exportiert werden, was eine viel weniger Verarbeitungszeit als PNG oder JPG benötigt.

Es gibt auch ein Bash-Skript namensmov2frame.shdas versucht, den FFMPEG-Extraktionsprozess zu automatisieren.

Mspieler
mplayer -ao null -vo png input.file

oder eine andere Option:

mplayer -nosound -vo png:z=9 my_file.mp4

VLC Dieser Mediaplayer kann mithilfe seiner Filter offenbar Bildsätze exportieren, aber das bereitet Probleme, es sei denn, Sie verwenden dies ausschließlich oder verfügen über eine portable Version.

  1. Erstellen Sie einen Ordner zum Speichern Ihrer Frames und kopieren Sie den Pfad dorthin. Für Mac OSX/Linux-Benutzer muss dies der vollständige Pfad sein (kein ~).

  2. Klicken Sie in VLC auf „Extras/Einstellungen“.

  3. Klicken Sie unter „Einstellungen anzeigen“ auf „Alle“.

  4. Wählen Sie unter „Video“ die Option „Filter“. Aktivieren Sie „Szenenvideofilter“.

  5. Erweitern Sie „Filter“ und wählen Sie „Szenenfilter“,

  6. Fügen Sie den Pfad von vorhin in „Verzeichnispfadpräfix“ ein.

  7. Wählen Sie im Feld „Aufnahmeverhältnis“ den zu kodierenden Bruchteil der Frames aus. 1/12 gibt alle 12 Frames aus, 1/1 exportiert alle Frames

  8. Klicken Sie auf „Speichern“.

  9. Klicken Sie auf „Medien/Video öffnen“ und suchen Sie Ihr Video. Lassen Sie das Ganze geduldig abspielen.

  10. Klicken Sie auf Extras / Einstellungen. Klicken Sie unter „Einstellungen anzeigen“ auf „Alle“. Wählen Sie unter „Video“ „Filter“ aus. Deaktivieren Sie „Szenenvideofilter“. Klicken Sie auf „Speichern“. So wird VLC beim nächsten Abspielen eines Videos keine Miniaturansichten generieren. Link

Es scheint auch potenzielle Probleme mit den Administratorberechtigungen beim ersten Programmstart zu geben:

sudo vlc [sudo] password for mint16: VLC is not supposed to be run as root. Sorry. If you need to use real-time priorities and/or privileged TCP ports you can use vlc-wrapper (make sure it is Set-UID root and cannot be run by non-trusted users first).

VLC bietet auch eine viel bessere Leistung beim Extrahieren in BMP statt in PNG

Antwort3

Wenn ich dies mit ffmpeg mache, habe ich festgestellt, dass ich die Option oft verwenden muss -vsync 0(beispielsweise beim Arbeiten mit einigen VOB-Dateien von DVDs):

ffmpeg -i video.VOB -vsync 0 %06d.bmp

Wenn Sie auch eine Start- und Stoppzeit festlegen möchten, sähe dies ungefähr so ​​aus:

ffmpeg -i video.VOB -vsync 0 -ss 01:30 -to 01:40 %06d.bmp

Antwort4

Unten ist der Code in OpenCV, mit dem ich Frames aus Videos extrahieren konnte.

import cv2
import os

# Replace 'your_video_file.mp4' with the path to your video file
video_path = 'your_video_file.mp4'

# Create a VideoCapture object
cap = cv2.VideoCapture(video_path)

# Check if the video file is opened successfully
if not cap.isOpened():
    print("Error: Could not open video file.")
    exit()

# Create a directory to store the frames
output_directory = 'frames'
os.makedirs(output_directory, exist_ok=True)

# Loop to read frames from the video
frame_count = 0
while True:
    # Read a frame from the video
    ret, frame = cap.read()

    # Check if the frame is read successfully
    if not ret:
        print("End of video.")
        break

    # Save the frame as an image file
    frame_filename = os.path.join(output_directory, f'frame_{frame_count:04d}.png')
    cv2.imwrite(frame_filename, frame)

    frame_count += 1

# Release the VideoCapture object
cap.release()

print(f"{frame_count} frames saved in '{output_directory}'.")

verwandte Informationen