Python/Pycharm OPEN-CV 서로 다른 동영상 2개 연결해보기

2023. 9. 29. 17:27파이썬/OpenCV

import sys
import numpy as np
import cv2

# 두 개의 동영상
cap1 = cv2.VideoCapture('snow.mp4')
cap2 = cv2.VideoCapture('storm.mp4')

if not cap1.isOpened() or not cap2.isOpened():
    print('동영상 연결 실패')
    sys.exit()


frame_cnt1 = round(cap1.get(cv2.CAP_PROP_FRAME_COUNT))
frame_cnt2 = round(cap2.get(cv2.CAP_PROP_FRAME_COUNT))
fps = cap1.get(cv2.CAP_PROP_FPS)
effect_frames = int(fps * 2)  # 전환 속도를 결정

print('frame_cnt1:', frame_cnt1)
print('frame_cnt2:', frame_cnt2)
print('FPS:', fps)

delay = int(1000 / fps)

w = round(cap1.get(cv2.CAP_PROP_FRAME_WIDTH))
h = round(cap1.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'DIVX')

# 출력 동영상 객체 생성
out = cv2.VideoWriter('output.avi', fourcc, fps, (w, h))

# 1번 동영상
for i in range(frame_cnt1 - effect_frames):
    ret1, frame1 = cap1.read()

    if not ret1:
        break

    out.write(frame1)
    cv2.imshow('frame', frame1)
    cv2.waitKey(delay)

# 합성 과정
for i in range(effect_frames):
    ret1, frame1 = cap1.read()
    ret2, frame2 = cap2.read()

    if not ret1 or not ret2:
        print('frame read error!')
        sys.exit()

    dx = int(w / effect_frames * i)
    frame_new = np.zeros((h, w, 3), dtype=np.uint8)

    frame_new[:, 0:dx, :] = frame2[:, 0:dx, :]
    frame_new[:, dx:w, :] = frame1[:, dx:w, :]

    out.write(frame_new)
    cv2.imshow('frame', frame_new)
    cv2.waitKey(delay)

# 2번 동영상
for i in range(effect_frames, frame_cnt2):
    ret2, frame2 = cap2.read()

    if not ret2:
        break

    out.write(frame2)
    cv2.imshow('frame', frame2)
    cv2.waitKey(delay)

cap1.release()
cap2.release()
✔️설명

1. cap1과 cap2 변수에 각각의 동영상을 지정한다.
2. if문을 사용하여 2개의 동영상 중 1개라도 연결되지 않았으면 console창에 '동영상 연결 실패'를 출력시킨다.
3. frame_cnt는 동영상의 총 프레임 개수를 가지고 반올림한다.(혹시 소수점일수도 있으니)
4. fps는 동영상의 속도를 얻어온다
5. effect_frames는 동영상 전환 속도를 결정한다

🟡 가로로 이어 붙이는 법
frame_new 변수에 0으로 가득찬 같은 크기의 numpy를 만든다.
effect_frame수만큼 반복문을 돌리면서
frame_new의 두번째 동영상의 가로를 연결
frame_new으 첫번재 동영상 연결

 

snow.mp4
4.18MB
storm.mp4
3.01MB
728x90