wake-up-neo.com

Python - Extrahieren und Speichern von Videoframes

Also habe ich dieses Tutorial befolgt, aber es scheint nichts zu tun. Einfach nichts. Es wartet einige Sekunden und beendet das Programm. Was ist los mit diesem Code?

import cv2
vidcap = cv2.VideoCapture('Compton.mp4')
success,image = vidcap.read()
count = 0
success = True
while success:
  success,image = vidcap.read()
  cv2.imwrite("frame%d.jpg" % count, image)     # save frame as JPEG file
  if cv2.waitKey(10) == 27:                     # exit if Escape is hit
      break
  count += 1

Außerdem steht in den Kommentaren, dass dies die Frames auf 1000 begrenzt. Warum?

EDIT: Ich habe versucht, success = True erstmal aber das hat nicht geholfen. Es wurde nur ein Bild mit 0 Bytes erstellt.

81
GShocked

Also hier war der endgültige Code, der funktionierte:

import cv2
print(cv2.__version__)
vidcap = cv2.VideoCapture('big_buck_bunny_720p_5mb.mp4')
success,image = vidcap.read()
count = 0
success = True
while success:
  cv2.imwrite("frame%d.jpg" % count, image)     # save frame as JPEG file
  success,image = vidcap.read()
  print 'Read a new frame: ', success
  count += 1

Damit dies funktioniert, müssen Sie ein paar Sachen besorgen. Zuerst OpenCV2 herunterladen . Dann für Python installieren 2.7.x. Gehen Sie zum Ordner ffmpeg im Ordner eines Drittanbieters (etwa C:\OpenCV\3rdparty\ffmpeg, aber ich bin mir nicht sicher). Kopieren opencv_ffmpeg.dll (oder die x64-Version, wenn Ihre python version x64 ist) und fügen Sie es in Ihren Python Ordner ein (wahrscheinlich C:\Python27). Benenne es um opencv_ffmpeg300.dll Wenn Ihre OpenCV-Version 3.0.0 ist (Sie finden es hier ), und ändern Sie entsprechend auf Ihre Version. Übrigens müssen Sie Ihr Python-Ordner in Ihrem Umgebungspfad haben.

36
GShocked

Von hier laden Sie dieses Video herunter, damit wir die gleiche Videodatei für den Test haben. Stellen Sie sicher, dass sich diese mp4-Datei im selben Verzeichnis Ihres python Codes befindet. Stellen Sie dann auch sicher, dass der python= Interpreter im selben Verzeichnis ausgeführt wird.

Ändern Sie dann den Code, ditch waitKey, der auch ohne ein Fenster Zeit verschwendet und die Tastaturereignisse nicht erfassen kann. Außerdem drucken wir den Wert success, um sicherzustellen, dass die Frames erfolgreich gelesen werden.

import cv2
vidcap = cv2.VideoCapture('big_buck_bunny_720p_5mb.mp4')
success,image = vidcap.read()
count = 0
while success:
  cv2.imwrite("frame%d.jpg" % count, image)     # save frame as JPEG file      
  success,image = vidcap.read()
  print('Read a new frame: ', success)
  count += 1

Wie geht das

149
fireant

Um diese Frage (& Antwort von @ user2700065) für einen etwas anderen Fall zu erweitern, wenn jemand nicht jeden Frame extrahieren möchte, sondern alle 1 Sekunde einen Frame extrahieren möchte. Ein einminütiges Video ergibt also 60 Frames (Bilder).

import sys
import argparse

import cv2
print(cv2.__version__)

def extractImages(pathIn, pathOut):
    count = 0
    vidcap = cv2.VideoCapture(pathIn)
    success,image = vidcap.read()
    success = True
    while success:
      vidcap.set(cv2.CAP_PROP_POS_MSEC,(count*1000))    # added this line 
      success,image = vidcap.read()
      print ('Read a new frame: ', success)
      cv2.imwrite( pathOut + "\\frame%d.jpg" % count, image)     # save frame as JPEG file
      count = count + 1

if __name__=="__main__":
    print("aba")
    a = argparse.ArgumentParser()
    a.add_argument("--pathIn", help="path to video")
    a.add_argument("--pathOut", help="path to images")
    args = a.parse_args()
    print(args)
    extractImages(args.pathIn, args.pathOut)
22
Bhushan Babar

Dies ist ein Tweak aus der vorherigen Antwort für python= 3.x aus @GShocked, ich würde es in den Kommentar schreiben, habe aber nicht genug Reputation

import sys
import argparse

import cv2
print(cv2.__version__)

def extractImages(pathIn, pathOut):
    vidcap = cv2.VideoCapture(pathIn)
    success,image = vidcap.read()
    count = 0
    success = True
    while success:
      success,image = vidcap.read()
      print ('Read a new frame: ', success)
      cv2.imwrite( pathOut + "\\frame%d.jpg" % count, image)     # save frame as JPEG file
      count += 1

if __name__=="__main__":
    print("aba")
    a = argparse.ArgumentParser()
    a.add_argument("--pathIn", help="path to video")
    a.add_argument("--pathOut", help="path to images")
    args = a.parse_args()
    print(args)
    extractImages(args.pathIn, args.pathOut)
8
XRarach

Nach vielen Recherchen zum Konvertieren von Frames in Videos habe ich diese Funktion erstellt. Ich hoffe, dies hilft. Dafür benötigen wir opencv:

import cv2
import numpy as np
import os

def frames_to_video(inputpath,outputpath,fps):
   image_array = []
   files = [f for f in os.listdir(inputpath) if isfile(join(inputpath, f))]
   files.sort(key = lambda x: int(x[5:-4]))
   for i in range(len(files)):
       img = cv2.imread(inputpath + files[i])
       size =  (img.shape[1],img.shape[0])
       img = cv2.resize(img,size)
       image_array.append(img)
   fourcc = cv2.VideoWriter_fourcc('D', 'I', 'V', 'X')
   out = cv2.VideoWriter(outputpath,fourcc, fps, size)
   for i in range(len(image_array)):
       out.write(image_array[i])
   out.release()


inputpath = 'folder path'
outpath =  'video file path/video.mp4'
fps = 29
frames_to_video(inputpath,outpath,fps)

ändern Sie den Wert für fps (Bilder pro Sekunde), den Eingabeordnerpfad und den Ausgabeordnerpfad entsprechend Ihrer lokalen Position

7
Puja Sharma

Diese Funktion konvertiert die meisten Videoformate in die Anzahl der Bilder im Video. Es funktioniert auf Python3 mit OpenCV 3+

import cv2
import time
import os

def video_to_frames(input_loc, output_loc):
    """Function to extract frames from input video file
    and save them as separate frames in an output directory.
    Args:
        input_loc: Input video file.
        output_loc: Output directory to save the frames.
    Returns:
        None
    """
    try:
        os.mkdir(output_loc)
    except OSError:
        pass
    # Log the time
    time_start = time.time()
    # Start capturing the feed
    cap = cv2.VideoCapture(input_loc)
    # Find the number of frames
    video_length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) - 1
    print ("Number of frames: ", video_length)
    count = 0
    print ("Converting video..\n")
    # Start converting the video
    while cap.isOpened():
        # Extract the frame
        ret, frame = cap.read()
        # Write the results back to output location.
        cv2.imwrite(output_loc + "/%#05d.jpg" % (count+1), frame)
        count = count + 1
        # If there are no more frames left
        if (count > (video_length-1)):
            # Log the time again
            time_end = time.time()
            # Release the feed
            cap.release()
            # Print stats
            print ("Done extracting frames.\n%d frames extracted" % count)
            print ("It took %d seconds forconversion." % (time_end-time_start))
            break

if __name__=="__main__":

    input_loc = '/path/to/video/00009.MTS'
    output_loc = '/path/to/output/frames/'
    video_to_frames(input_loc, output_loc)

Es unterstützt .mts und normale Dateien wie .mp4 und .avi. Bewährt am .mts Dateien. Klappt wunderbar.

7
Harsh Patel

Dieser Code extrahiert Frames aus dem Video und speichert die Frames im JPG-Format

import cv2
import numpy as np
import os

# set video file path of input video with name and extension
vid = cv2.VideoCapture('VideoPath')


if not os.path.exists('images'):
    os.makedirs('images')

#for frame identity
index = 0
while(True):
    # Extract images
    ret, frame = vid.read()
    # end of frames
    if not ret: 
        break
    # Saves images
    name = './images/frame' + str(index) + '.jpg'
    print ('Creating...' + name)
    cv2.imwrite(name, frame)

    # next frame
    index += 1
5
Rejoice T J

Die vorherigen Antworten haben den ersten Frame verloren. Und es wird schön sein, die Bilder in einem Ordner zu speichern.

# create a folder to store extracted images
import os
folder = 'test'  
os.mkdir(folder)
# use opencv to do the job
import cv2
print(cv2.__version__)  # my version is 3.1.0
vidcap = cv2.VideoCapture('test_video.mp4')
count = 0
while True:
    success,image = vidcap.read()
    if not success:
        break
    cv2.imwrite(os.path.join(folder,"frame{:d}.jpg".format(count)), image)     # save frame as JPEG file
    count += 1
print("{} images are extacted in {}.".format(count,folder))

Übrigens können Sie die Frame Rat e von VLC überprüfen. Gehen Sie zu Windows -> Medieninformationen -> Codec-Details

5
Yuchao Jiang

Ich verwende Python über Anacondas Spyder-Software. Mit dem in der Frage dieses Threads von @Gshocked aufgeführten Originalcode funktioniert der Code nicht (python= Ich habe OpenCV 3.2 heruntergeladen und "opencv_ffmpeg320.dll" und "opencv_ffmpeg320_64.dll" aus dem Ordner "bin" kopiert. Beide DLL-Dateien wurden in den Ordner "Dlls" von Anaconda eingefügt.

Anaconda hat auch einen "pckgs" -Ordner ... Ich habe den gesamten "OpenCV 3.2" -Ordner, den ich heruntergeladen habe, in den "pckgs" -Ordner von Anaconda kopiert und eingefügt.

Schließlich hat Anaconda einen "Library" -Ordner mit einem "bin" -Unterordner. Ich habe die Dateien "opencv_ffmpeg320.dll" und "opencv_ffmpeg320_64.dll" in diesen Ordner eingefügt.

Nach dem Schließen und Neustarten von Spyder funktionierte der Code. Ich bin mir nicht sicher, welche der drei Methoden funktioniert hat, und ich bin zu faul, um zurückzugehen und es herauszufinden. Aber es funktioniert so, Prost!

3
SpaceFarmer2020

Diese Funktion extrahiert Bilder aus dem Video mit 1 fps. ZUSÄTZLICH identifiziert sie das letzte Bild und hört auf zu lesen:

import cv2
import numpy as np

def extract_image_one_fps(video_source_path):

    vidcap = cv2.VideoCapture(video_source_path)
    count = 0
    success = True
    while success:
      vidcap.set(cv2.CAP_PROP_POS_MSEC,(count*1000))      
      success,image = vidcap.read()

      ## Stop when last frame is identified
      image_last = cv2.imread("frame{}.png".format(count-1))
      if np.array_equal(image,image_last):
          break

      cv2.imwrite("frame%d.png" % count, image)     # save frame as PNG file
      print '{}.sec reading a new frame: {} '.format(count,success)
      count += 1
3
Bence Kővári