Python - Extracting and Saving Video Frames

How can I extract and save image frames from a large number of videos all at once using OpenCV Python?

Assuming that you code is correct, you can create a function with your code, list files in directory and pass then to your function.

import cv2
import os
# your function
def video2frames( video_file, output_path )
if not os.path.exists(output_path):
os.makedirs(output_path)
cap = cv2.VideoCapture(video_path)
index = 0
while cap.isOpened():
Ret, Mat = cap.read()
if Ret:
index += 1
if index % 29 != 0:
continue
cv2.imwrite(output_path + '/' + str(index) + '.png', Mat)
else:
break
cap.release()
return

def multiple_video2frames( video_path, output_path )
list_videos = os.listdir(video_path)
for video in list_videos:
video_base = os.path.basename(video)
input_file = video_path + '/' + video
out_path = output_path + '/' + video_base
video2frames(input_file, out_path)
return

# run all
video_path = 'C:/Users/user/Videos/' # all videos
output_path = 'C:/Users/user/Pictures/' # location on ur pc
multiple_video2frames( video_path, output_path )

Extract video frames in python using OpenCV

if you want a proper framerate you can do

framerate = vid.get(5)

instead of

cap.set(cv2.CAP_PROP_FPS, 5)

this will give you the exact framerate

How can i save a frame in a live video using opencv in python?

You can use imwrite function from your opencv to extract the current frame.

You can also add time and convert it to string for naming purpose for the output file.

import time as t
LiveVideo = VideoStream(src=0).start()
while True:
frame = LiveVideo.read()
timestr = t.strftime("%Y%m%d-%H%M%S")
cv2.imwrite("frame%s.jpg" % timestr, frame )

How to extract clear frames from video file?

I am posting complete solution to extract one frame from one sec clip. The solution is based on @Kuldeep Singh's Solution.

cap = cv2.VideoCapture("input.mp4")
fps = int(cap.get(cv2.CAP_PROP_FPS))
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))

for i in range(int(frame_count/fps)):
arr_frame=[]
arr_lap=[]
for j in range(fps):
success, frame = cap.read()
laplacian = cv2.Laplacian(frame, cv2.CV_64F).var()
arr_lap.append(laplacian)
arr_frame.append(frame)
selected_frame = arr_frame[arr_lap.index(max(arr_lap))]
cv2.imwrite(f"{i}.jpg", selected_frame)

The above code reads frame for every sec video clip. i.e., let's say the input video has 30 fps then the code reads 30 frames and calculates laplacian variance value. Once the 30 frames are read, it writes frame into image for the maximum variance value. Because, the higher the number, the sharper the edge is. The above process will be continued until the last second.

so, the final output would be, if you pass 10 secs video, you will get 10 clear frames/images.

How to save specific parts of video into separate videos using opencv in python?

Here is how I would do it:

import cv2

file = "video.avi"
parts = [(15, 30), (50, 79)]

cap = cv2.VideoCapture(file)
ret, frame = cap.read()
h, w, _ = frame.shape

fourcc = cv2.VideoWriter_fourcc(*"XVID")
writers = [cv2.VideoWriter(f"part{start}-{end}.avi", fourcc, 20.0, (w, h)) for start, end in parts]

f = 0
while ret:
f += 1
for i, part in enumerate(parts):
start, end = part
if start <= f <= end:
writers[i].write(frame)
ret, frame = cap.read()

for writer in writers:
writer.release()

cap.release()

Explanation:

  1. Import the cv2 module, define the name of the video file and the parts of the file you want to save into different video files:
import cv2

file = "video.avi"
parts = [(15, 30), (50, 79)]

  1. Define a video capture device to read frames from the video file and read from it once to get the shape of the frames of the video:
cap = cv2.VideoCapture(file)
ret, frame = cap.read()
h, w, _ = frame.shape

  1. Define a fourcc (four-character code), and define a list of video writers; one for every video you want to generate:
fourcc = cv2.VideoWriter_fourcc(*"XVID")
writers = [cv2.VideoWriter(f"part{start}-{end}.avi", fourcc, 20.0, (w, h)) for start, end in parts]

  1. Define a while loop, but before that, define a variable to keep track of which frame the while loop is at in the capture device:
f = 0
while ret:
f += 1

  1. Using a for loop inside the while loop, loop through the start and end frames of the parts, using the enumerate method to allow the program to access the index of the parts each iteration is at when needed. If the variable defined before the while loop is between (inclusive) the start and end of the part, write that frame to the corresponding video writer (using the index provided by the enumerate method):
    for i, (start, end) in enumerate(parts):
if start <= f <= end:
writers[i].write(frame)
ret, frame = cap.read()

  1. Finally, release all the video writers and the capture device:
for writer in writers:
writer.release()

cap.release()

How to edit video frames without extracting each frame first ? OpenCV

That assumption isn't correct. You can use OpenCV's VideoCapture to load a video, get a frame, do some processing on it and save it using a VideoWriter object - one frame at a time. There is no need to load all frames into memory and then store them all at once.



Related Topics



Leave a reply



Submit