Home > Enterprise >  Combining two .AVI movies with OpenCV unsuccessful
Combining two .AVI movies with OpenCV unsuccessful

Time:02-02

I am trying to use OpenCV to combine two .AVI videos, but having little success. I want a combined final video that plays the two videos sequentially.

The two input videos were created with Fiji's TrackMate algorithm. They are 6.6 and 6.2 MB, each only 10 seconds, but the output file is only 14 KB and does not play at all in VLC Media Player, so I am surely doing something wrong. Any input would be greatly appreciated: How do I combine two .AVI videos into a single one?

My code is below; it is adapted from this answer with what I think is the correct FourCC:

import cv2

path = '/Volumes/GQA HD/GQA Experiments/2023_01_27/'
file1 = 'TrackMate capture of 1.avi'
file2 = 'TrackMate capture of 2.avi'

file_combined = 'TrackMate Combined captures of IMG_0240.avi'

# Paths of videos
videos = [path file1, path file2]

# Create new video
fourcc = cv2.VideoWriter_fourcc('M','J','P','G')
frameSize=(720,1280)
fps=30
video = cv2.VideoWriter(path file_combined, fourcc, fps, frameSize)

# Write all frames sequentially to new video
for v in videos:
    curr_v = cv2.VideoCapture(v)
    while curr_v.isOpened():
        r, frame = curr_v.read()    # Get return value and curr frame of curr video
        if not r:
            break
        video.write(frame)          # Write the frame

video.release()                     # Save the video

CodePudding user response:

frameSize should probably be (1280, 720) instead of (720, 1280).
OpenCV size conventions is (width, height), when width is the number of columns in the horizontal dimension, and height is the number of row in the vertical dimension.

We may resize frame to (width, height), before writing it, just in case:

if frame.shape[0] != height or frame.shape[1] != width:
    frame = cv2.resize(frame, (width, height))

video.write(frame)

Complete code sample:

import cv2

do_create_sample_video_files = False

if do_create_sample_video_files:
    # Create sample video files for testing (use FFmpeg CLI for creating synthetic video files).
    import subprocess as sp
    import shlex
    sp.run(shlex.split('ffmpeg -y -f lavfi -i testsrc=1280x720:rate=1:duration=300 -vcodec libx264 sample1.avi'))
    sp.run(shlex.split('ffmpeg -y -f lavfi -i testsrc=640x360:rate=1:duration=300 -vcodec libx264 sample2.avi'))  # Use other resolution for testing

path = './'
file1 = 'sample1.avi'
file2 = 'sample2.avi'

file_combined = 'CombinedSample1Sample2.avi'

# Paths of videos
videos = [path file1, path file2]

# Create new video
width, height = 1280, 720
fourcc = cv2.VideoWriter_fourcc('M','J','P','G')
frameSize = (width, height) #(720,1280)  <-- Probably supposed to be (1280, 720).
fps=30
video = cv2.VideoWriter(path file_combined, fourcc, fps, frameSize)

# Write all frames sequentially to new video
for v in videos:
    curr_v = cv2.VideoCapture(v)

    while curr_v.isOpened():
        r, frame = curr_v.read()    # Get return value and curr frame of curr video
        if not r:
            break

        if frame.shape[0] != height or frame.shape[1] != width:
            # Resize frame to the resolution of the destination video if required.
            frame = cv2.resize(frame, (width, height))

        video.write(frame)          # Write the frame

video.release()
  • Related