반응형
황선규 박사님의 OpenCV 강의를 공부하면서 정리하였습니다.
동영상 전환 이펙트
두 동영상 클립 사이에 추가되는 애니메이션 효과를 적용시켜보겠습니다.
구현할 기능은 두 개의 동영상 동시 열기, 첫 번째 동영상의 마지막 N개 프레임과 두 번째 동영상의 처음 N개 프레임을 합성하겠습니다. 또한 합성된 영상을 동영상으로 저장하겠습니다.
# 두 개의 동영상을 열어서 cap1, cap2로 지정
cap1 = cv2.VideoCapture('video1.mp4')
cap2 = cv2.VideoCapture('video2.mp4')
if not cap1.isOpened() or not cap2.isOpened()
print('video open failed!')
sys.exit
# 두 동영상의 크기, FPS는 같다고 가정하겠습니다.
# 크기 : 1280 X 720, FPS : 24
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
# 48프레임. 첫 번째 영상의 2초, 두 번째 영상의 2초를 겹쳐서 효과 줌
effect_frame = int(fps * 2)
print('frame_cnt1 :', frame_cnt1)
print('frame_cnt2 :', frame_cnt2)
print('FPS :', fps)
# 프레임 간 시간 간격
delay = int(1000 / fps)
# 저장을 위해 w,h,fourcc 속성 값 추출
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_frame): # 뒤에 2초 남겨두고 앞부분만 저장
ret1, frame1 = cap1.read()
if not ret1:
print('frame read error!')
sys.exit()
out.write(frame1)
print('.', end='')
cv2.imshow('output', frame1) # 프레임1 출력
cv2.waitKey(delay)
# 1번 동영상 뒷부분과 2번 동영상 앞부분을 합성
for i in range(effect_frames): # 48번
ret1, frame1 = cap1.read()
ret2, frame2 = cap2.read()
if not ret1 or not ret2:
print('frame read error!')
sys.exit()
# 합성, 짤라내기 위한 변수, w 넓이를 48로 나눔
dx = int((w / effect_frame) * i)
# 프레임을 하나 생성
frame = np.zeros((h, w, 3), dtype=np.unit8)
frame[:, 0:dx, :] = frame2[:, 0:dx, :] # 0부터 dx까지는 영상2
frame[:, dx:w, :] = frame1[:, dx:w, :] # dx부터 끝까지는 영상1
# 프레임 저장
out.write(frame)
print('.', end='')
cv2.imshow('output', frame) # 영상 출력
cv2.waitKey(delay)
# 2번 동영상 저장
for i in range(effect_frame, frame_cnt2)
ret2, frame2 = cap2.read()
if not ret2:
print('video read error!')
sys.exit()
out.write(frame2)
print('.', end='')
cv2.imshow('output', frame2)
cv2.waitKey(delay)
print('\noutput.avi file is successfully generated!')
# 프레임을 받아온 후 꼭 release를 써야 한다. 사용한 자원 해제
cap1.release()
cap2.release()
out.release()
cv2.destroyAllWindows()
이처럼 동영상 전환 이펙트를 줄 수 있습니다.
디졸브(dissolve) 이펙트 사용방법
이번에는 동영상 전환 이펙트로 디졸브 효과를 주겠습니다.
위에 작성하였던 코드에서 약간 수정을 해보겠습니다.
# 프레임을 하나 만듬
frame = np.zeros((h, w, 3), dtype=np.uint8)
frame[:, 0:dx, :] = frame2[:, 0:dx, :] # 0부터 dx까지는 영상2
frame[:, dx:w, :] = frame1[:, dx:w, :] # dx 부터 끝까지는 영상1
여기 코드를 아래의 코드로 변경하면 됩니다.
#디졸브 효과
#과중치를 이용. cv2.addWeighted 함수 이용하면 된다.
alpha = i / effect_frames
frame = cv2.addWeighted(frame1, 1 - alpha, frame2, alpha, 0)
이처럼 영상이 겹쳐지면서 화면이 전환됩니다.
반응형
'Python > 파이썬 OpenCV 공부' 카테고리의 다른 글
[파이썬 OpenCV] 영상의 산술 연산 - cv2.add, cv2.addWeighted, cv2.subtract, cv2.absdiff (0) | 2020.09.27 |
---|---|
[파이썬 OpenCV] 영상의 밝기 조절 - cv2.add, np.clip (0) | 2020.09.27 |
[파이썬 OpenCV] 연산 시간 측정 방법 - cv2.TickMeter (0) | 2020.09.27 |
[파이썬 OpenCV] 트랙바를 이용한 그레이스케일 레벨 표현하기 - cv2.createTrackbar (0) | 2020.09.27 |
[파이썬 OpenCV] 마우스를 이용해 그리기 - cv2.setMouseCallback (0) | 2020.09.27 |