Ermitteln der Gesamtzahl der Frames in einer Datei (.avi) über Python mithilfe des Open-CV-Moduls.
Wenn möglich, welche Informationen (Auflösung, fps, Dauer usw.) wir von einer Videodatei dadurch erhalten können.
Antworten:
Mit einer neueren OpenCV-Version (ich verwende 3.1.0) funktioniert es folgendermaßen:
import cv2
cap = cv2.VideoCapture("video.mp4")
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print( length )
Ähnliches gilt für andere Videoeigenschaften cv2.CAP_PROP_*
import cv2
cap = cv2.VideoCapture(fn)
if not cap.isOpened():
print "could not open :",fn
return
length = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))
width = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.cv.CV_CAP_PROP_FPS)
siehe hier für weitere Informationen.
Auch alles mit einem Körnchen Salz, nicht alle diese Requisiten sind obligatorisch, einige sind möglicherweise nicht mit Ihrem Capture / Video-Codec verfügbar
So funktioniert es mit Python 3.6.5 (unter Anaconda) und OpenCV 3.4.2. [Hinweis]: Sie müssen das "CV_" aus dem "CV_CAP_PROP_xx" für jede Eigenschaft löschen, die auf der offiziellen OpenCV- Website angegeben ist .
import cv2
cap = cv2.VideoCapture("video.mp4")
property_id = int(cv2.CAP_PROP_FRAME_COUNT)
length = int(cv2.VideoCapture.get(cap, property_id))
print( length )
length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
Es gibt zwei Methoden, um die Anzahl der Frames in einer Videodatei zu bestimmen
Methode 1 ist schnell und relys auf OpenCV der Video Eigenschaft Funktionalität , die fast augenblicklich die Anzahl der Frames in einer Videodatei bestimmt. Es gibt jedoch einen Kompromiss bei der Genauigkeit, da dieser von Ihren OpenCV- und Video-Codec-Versionen abhängt. Andererseits ist das manuelle Zählen jedes Frames 100% genau, obwohl es erheblich langsamer ist. Hier ist eine Funktion, die standardmäßig versucht, Methode 1 auszuführen. Wenn dies fehlschlägt, wird automatisch Methode 2 verwendet
def frame_count(video_path, manual=False):
def manual_count(handler):
frames = 0
while True:
status, frame = handler.read()
if not status:
break
frames += 1
return frames
cap = cv2.VideoCapture(video_path)
# Slow, inefficient but 100% accurate method
if manual:
frames = manual_count(cap)
# Fast, efficient but inaccurate method
else:
try:
frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
except:
frames = manual_count(cap)
cap.release()
return frames
Benchmarks
if __name__ == '__main__':
import timeit
import cv2
start = timeit.default_timer()
print('frames:', frame_count('fedex.mp4', manual=False))
print(timeit.default_timer() - start, '(s)')
start = timeit.default_timer()
print('frames:', frame_count('fedex.mp4', manual=True))
print(timeit.default_timer() - start, '(s)')
Ergebnisse von Methode 1
frames: 3671
0.018054921 (s)
Ergebnisse von Methode 2
frames: 3521
9.447095287 (s)
Beachten Sie, dass sich die beiden Methoden um 150 Frames unterscheiden und Methode 2 erheblich langsamer ist als Methode 1 . Verwenden Sie daher Methode 1, wenn Sie Geschwindigkeit benötigen, aber bereit sind, auf Genauigkeit zu verzichten. Verwenden Sie in Situationen, in denen Sie eine Verzögerung haben, aber die genaue Anzahl der Frames benötigen, Methode 2
Eine andere Lösung, die nicht von den manchmal fehlerhaften CV_CAP_PROP
Gettern abhängt, besteht darin, Ihre gesamte Videodatei in einer Schleife zu durchlaufen
Das Sammeln von Informationen über die Auflösung ist schwieriger, da einige Codecs eine variable Auflösung unterstützen (ähnlich wie bei VBR in Audiodateien, bei denen die Bitrate keine Konstante ist, sondern einen vordefinierten Bereich abdeckt).
FPS kann berechnet werden, aber hier haben Sie das gleiche Problem wie bei der Auflösung - Konstante (CFR) vs Variable (VFR). Dies ist eher ein Multithreading-Problem omho. Persönlich würde ich einen Frame-Zähler verwenden, der nach jedem gültigen Frame erhöht wird, während in einem Intervall von 1 Sekunde ein Timer (der in einem Hintergrund-Thread ausgeführt wird) das Speichern des aktuellen Zählerwerts und das anschließende Zurücksetzen auslöst. Sie können die Werte in einer Liste speichern, um die durchschnittliche / konstante Bildrate am Ende zu berechnen, wenn Sie auch die Gesamtzahl der Bilder im Video kennen.
Der Nachteil dieser eher simplen Vorgehensweise besteht darin, dass Sie die gesamte Datei durchlaufen müssen, was - falls sie mehrere Stunden lang ist - vom Benutzer definitiv bemerkt wird. In diesem Fall können Sie klug sein und dies in einem Hintergrundprozess tun, während der Benutzer etwas anderes tun kann, während Ihre Anwendung diese Informationen über die geladene Videodatei sammelt.
Der Vorteil ist, dass Sie unabhängig davon, welche Videodatei Sie haben, solange OpenCV daraus lesen kann, ziemlich genaue Ergebnisse erhalten, im Gegensatz zu CV_CAP_PROP
denen, die möglicherweise so funktionieren oder nicht, wie Sie es erwarten.