I want to read from a specific frame to a specific frame in a video. For example , my video consists of 150 frames, but I want to read the video from frame 5 to from frame 134 in that video. Is it possible?
CodePudding user response:
First you have to read your video and store it into a multi-dimensional numpy array. Afterwards you can slice the numpy array according to your requirements
See https://stackoverflow.com/a/42166299/4141279 on how to read a video into a numpy array.
Slicing is then done by:
buf[4:134] # assuming buf is your numpy array from the previous step
You could also drop all the unnecessary frames during initial creation of the numpy array if you have memory limitations.
idx = 0
while (fc < frameCount and ret):
ret, tmp = cap.read()
if fc in range(4, 135):
buf[idx] = tmp
idx = 1
fc = 1
CodePudding user response:
I would do something like this :
This probably uses less opencv than you want, but I personally believe that ffmpeg is more adapted to this kind of operation
import cv2
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
def get_framerate(video)->float:
""" this function was made to extract the framerate from a video"""
# Find OpenCV version
(major_ver, minor_ver, subminor_ver) = (cv2.__version__).split('.')
if int(major_ver) < 3 :
return video.get(cv2.cv.CV_CAP_PROP_FPS)
else :
return = video.get(cv2.CAP_PROP_FPS)
if __name__ == "__main__":
# get start frame
videoName = input("Path of the video file ?")
video = cv2.VideoCapture(videoName);
fps = get_framerate(video)
frame_start = int(input("Starting frame ?\n"))
ts_start = frame_start / fps
frame_end = int(input("Ending frame ?\n"))
ts_end = frame_end / fps
ffmpeg_extract_subclip(frameName, ts_start, ts_end, targetname="output.mp4")
source 1 : an openCV guide
source 2 : another question on stack overflow