Program/OPEN_CV

[Open CV] 기본적인 영상처리 기법 _ 실전코딩 ( 크로마키 합성 )

사막여유 2022. 5. 14. 20:32
728x90

 

크로마키 합성이란?

 - 녹색 또는 파란색 배경에서 촬영한 영상에 다른 배경 영상을 합성하는 기술이다.

 

크로마키 합성을 위해서는

 - 녹색 스크린 영역 추출하기

 - 녹색 영역에 다른 배경 영상을 합성하여 저장하기

 - 스페이스바를 이요하여 크로마키 합성 동착 제어하기 

등의 기능이 필요하다.

 

일단 cv2.inRange() 함수를 사용하여 녹색 영역의 범위만 검출할 수 있다.

그리고 cv2.copyTo() 함수를 사용하여 마스크 연산을 진행한다. 

일단 기본적인 사용 함수들은 위 2가지가 있고

 

실제로 함수들을 어떻게 활용하는지 보자

 

import sys
import numpy as np
import cv2

cap1 = cv2.VideoCapture('woman.mp4')

if not cap1.isOpened():  #파일 오픈 에러처리
    print('video open failed')
    sys.exit()

cap2 = cv2.VideoCapture('raining.mp4')

if not cap2.isOpened():
    print('video open failed')
    sys.exit()

frame_cnt1 = round(cap1.get(cv2.CAP_PROP_FRAME_COUNT))
frame_cnt2 = round(cap2.get(cv2.CAP_PROP_FRAME_COUNT))
print('frame_cnt1:', frame_cnt1)
print('frame_cnt2:', frame_cnt2)

fps = cap1.get(cv2.CAP_PROP_FPS)
delay = int(1000/fps)

# 합성 여부 변수
do_composit = False

while True:
    ret1, frame1 = cap1.read()

    if not ret1:
        break

    #do_composit 플래그가 True 일때만 합성
    if do_composit:
        ret2, frame2 = cap2.read()

        if not ret2:
            break

        hsv = cv2.cvtColor(frame1, cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(hsv, (50,150,0)(70,255,255))
        cv2.copyTo(frame2, mask, frame1)

    cv2.imshow('frame', frame1)
    key = cv2.waitKey(delay)

    #스페이스바를 누르면 do_composit 플래그를 변경
    if key == ord(' '):
        do_composit = not do_composit
    elif key == 27:
        break

cap1.release()
cap2.release()

cv2.destroyAllWindows()

일단 2개의 영상을 Open 하여 변수에 입력시킨다.

물론 이는 2개의 영상의 사이즈와 fps가 동일하다는 가정하에 진행됐다.

 

스페이스바 입력이 들어왔을때만 크로마키 합성을 진행하도록 만들어야하기 때문에 

do_composit 이라는 변수를 만들어 스페이스바 입력이 들어왔을때 변수가 반전되도록 만들어놨다.

 

이후 while 루프를 돌려 cap1과 cap2의 frame을 받아오고

fps / 1000 의 Delay 값을 이용하여 프레임사이의 시간간격을 입력한 WaitKey 함수를 실행시켜준다. 

그리고 스페이스바 입력이 들어오게되면 do_composit 변수가 반전되면 크로마키 합성이 실행된다.

 

일단 cap.read() 함수를 통해 frame을 받아와 크로마키 합성을 진행할 Origin 영상을 HSV 성분으로 Convert 한 뒤 

inRange 함수로 녹색 혹은 파란색의 영상을 추출하여 Binary 처리한다.

 

그 이후 cv2.copyTo 함수를 통해 합성할 영상과 inRange 영상을 합친 뒤 그 영상을 

imshow 하는 방식으로 구성되어있는 소스이다.

 

하지만 사이즈가 다른 영상은 어떤 방법을 통해서 크로마키 합성을 진행할 수 있을까?

지금까지 챕터 3에서 배웠던 함수들을 이용하게 되면 합성을 진행할 수 있다.

 

일단 첫번째 영상에서 get(cv2.CAP_PROP_FRAME_WIDTH) 를 사용하여 합성을 진행할 영상의

Width , Height 를 구하고

합성할 영상을 resize 해주는 방식으로 크기를 조정해줄 수 있다. 

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

https://bit.ly/3L3avNW

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

728x90