OpenCV/OpenCV 강좌

OpenCV2 강좌 3 - 비디오 프레임 캡처 및 표시

KALILIVE 2020. 9. 11. 19:35
반응형

저번 강의에서는 이미지 파일을 입출력을 배웠습니다.

이번 시간에는 동영상의 입출력에 대해 배워볼까 합니다.

비디오란?

비디오를 다루려면 비디오에 대한 구성을 알고 있어야 합니다.

비디오를 간단히 생각하면 이전에 배운 여러 장의 이미지 파일이 순차적으로

재생되면서 잔상효과로 인하여 마치 실제 움직이는 것처럼 보입니다.

비디오 캡처는 아날로그 비디오를 디지털 비디오로 변환하는 과정입니다.

프레임(frame, 동영상을 구성하는 사진 1장 단위)은 비디오에서 캡처한 한 장의 영상입니다.

비디오는 이러한 프레임으로 구성된 연속 시퀀스(Sequence)입니다.

 

비디오 캡처와 관련된 함수

함수 설명 출력
cv2,VideoCapture(device) 웹캠 같은 장치에서 비디오를 불러온다.
카메라가 한개이면 0, 두 개이면 0,1로 구분
VideoCapture object
cv2,VideoCapture(filename) filename에 위치한 비디오를 불러온다. VideoCapture object
cv2.VideoCapture.read(img) 위 함수를 이용해 얻은 VideoCapture object에서 다음 비디오 프레임을 얻어
디코딩하여 프레임을 반환한다.
retval, img
cv2.VideoCapture.grab() 위와 동일한 역할을 수행한다.
자세한 설명은 아래를 참조
img
cv2.VideoCapture.retrieve(img) 위와 동일한 역할을 수행한다.
자세한 설명은 아래를 참조
retval
cv2.VideoCapture.release() 비디오 흭득 객체를 해제 X
cv2.VideoCapture.set() 비디오 특성 얻기 retval
cv2.VideoCapture.set(propld,value) 비디오 특성 설정 retval

 

예제

import cv2

cap2 = cv2.VideoCapture(0,cv2.CAP_DSHOW) # 0번 카메라에서 비디오를 불러온다.
cap = cv2.VideoCapture('./data/vtest.avi') # data 풀더에서 vtest.avi비디오를 불러온다.

#cap에 저장된 비디오로 부터 높이와 너비정보를 저장한다.
frame_size=(int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)), #cap에 저장된 비디오프레임의 높이정보를 불러온다.
            int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)))  #cap에 저장된 비디오프레임의 너비정보를 불러온다.
print('frame_size = ',frame_size)

while True:
    retval, frame = cap.read() # cap에 저장된 동영상의 프레임을 불러온다.
    #retval은 불러올 비디오가 없을시 Bool자료형인 False를 반환
    if not retval:
        break

    cv2.imshow('frame',frame)

    key = cv2.waitKey(25)
    if key==27:
        break
if cap.isOpened():
    cap.release()
cv2.destroyAllWindows()

위 코드에서 볼 수 있듯이 예제는 data 폴더에 있는 vtest.avi라는 영상을 이용했습니다.

(cap2로 출력 코드를 변경하시면 노트북의 웹캠으로 출력합니다.)

 

cap.release()

저도 OpenCV를 공부하다가 이 함수에 대해 설명이 미흡한 책들이 많아 이 함수가 뭔지 찾게 되었습니다.

https://stackoverflow.com/questions/48213499/whats-the-meaning-of-cv2-videocapture-release

 

What's the meaning of cv2.videoCapture.release()?

I am working with a raspberry pi to capture the first 20 frames of a video. Now this is more of a concepts question but while going through the openCV documentation on videoCapture, they emphasize ...

stackoverflow.com

StackOverflow에서도 저와 같은 궁금증을 갖는 분이 계셨습니다.

위 링크에서 보듯이 저희는 웹캠에서 동영상 데이터를 요청하여 지속적으로 데이터를 받습니다.

저희가 이 데이터를 1곳에서만 불러오면 괜찮겠지만 만약 여러 곳에서 한 카메라에게 다량의 데이터를 불러오면 

카메라는 신속하게 데이터를 처리하지 못할 것입니다. 

그래서 만약 저희가 필요한 상황에 데이터를 요청하고 다른 곳에서 이 카메라 디바이스에 정보를 요청할 수도 있으니

이제부터 우리가 선언한 변수에게 데이터를 그만 요청하라는 뜻을 가진 함수가 바로 cap.release() 함수입니다.

 

제 노트북은 카메라가 사용되면 렌즈 옆에 파란색 불빛이 들어와서 카메라의 사용 여부를 확인할 수 있습니다.

간단하게 코드를 수정하여 실제로 카메라 디바이스에 요청이 그만되는지 확인해 봅시다.

원래 코드를 실행한뒤 위 사진처럼 렌즈옆에 LED가 꺼진것을 확인할 수 있습니다.

 

from time import sleep
#if cap2.isOpened():
#    cap2.release()
cv2.destroyAllWindows()
sleep(10000)

다음과 같이 마지막 코드를 수정하여 cap.release()를 주석 처리해버렸습니다.

또한 cv2.destroyAllWindows() 실행 후 main함수에 return이 작동되어 종료하기 때문에 sleep() 함수를 이용해

실행파일이 종료되지 않도록 설정하였습니다.

(저는 혹시 몰라 cv2.destroyAllWindows()도 주석 처리해서 확인해서 아래 그림에서 종료 후 윈도우 창이 그대로 켜져 있는 겁니다, 확인 결과 cv2.destroyAllWindows()의 작동 여부에 관계없이 카메라 디바이스에 불빛은 계속 들어왔습니다.)

 

cap.release()를 주석처리하여 실행하면 위 노트북 렌즈옆에 파란불빛이 동영상재생후에도 켜져있는것을 확인할 수 있습니다.

동영상이 재생된 후에도 카메라 렌즈 옆에 LED가 켜져 있는 것이 확인되어 저희가

cap.release() 함수를 실행하지 않았기 때문에 계속 cap 변수에 카메라가 동영상 데이터를 전송하는 것을 확인할 수 있었습니다.

 

혹시 추가적으로 궁금하시거나 오류가 발생하면 댓글을 통해 알려주세요.(지금까지는 매일 블로그를 확인하고 있습니다)

반응형