pythonopencvvideo-editing

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


I have a video and I want to obtain specific parts of that video using frame numbers and save them.

For example, if there is a video and it has total 200 frames and I want to extract some specific parts of video say from frame 15 to 30, 50 to 79, etc. and I want to save each of these parts separately.

cap= cv2.VideoCapture('Trademill.mp4')
video_length = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) 
print ("Number of frames: ", video_length)

success,image = cap.read()
count = 0
while success:
cv2.imwrite("frame%d.jpg" % count, image)          
success,image = cap.read()
count += 1

How can I do this using python and OpenCV?


Solution

  • 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()