Python/파이썬 OpenCV 공부

[파이썬 OpenCV] 카메라와 동영상 열기, 속성값 참조, 프레임 받아오기 - cv2.VideoCapture 클래스

AI 꿈나무 2020. 9. 27. 09:54
반응형

황선규 박사님의 OpenCV 강의를 공부하면서 정리하였습니다.

 


카메라와 동영상 열기

 OpenCV에서는 카메라와 동영상으로부터 프레임(frame)을 받아오는 작업을 cv2.VideoCapture 클래스 하나로 처리합니다.

 open()으로 카메라나 동영상을 열고 read()로 프레임을 가져옵니다.

 

1. 카메라 열기 - cv2.VideoCapture

cv2.VideoCapture() 명령어로 카메라를 열 수 있습니다.

 

[명령어 설명]

cv2.VideoCapture(index, apiPreference=None) -> retval

 

 index : camera_id + domain_offset_id 시스템 기본 카메라를 기본 방법으로 열려면 index에 0을 전달합니다. 장치관리자에 등록되어 있는 카메라 순서대로 인덱스가 설정되어 있습니다.

 apiPreference : 선호하는 카메라 처리 방법을 지정합니다.

 retval : cv2.VideoCapture 객체를 반환합니다.

 

cv2.VideoCapture.open(index, apiPreference=None) -> retval

 

 retval : 성공하면 True, 실패하면 False를 반환합니다.

 

[예시 코드]

# 카메라 열기
# 0은 기본 카메라(장치관리자에 저장되어있는 순서대로), 카메라가 두 대면 1~2
cap = cv2.VideoCapture(0) # 클래스 생성
# cap.open(0) # 0번 카메라 열기, videoCapture(0)을 하면 안해도 됌

 cap 변수에 cv2.VideoCapture() 객체를 저장했습니다.

 cap.open(0) 은 cv2.VideoCapture(0)으로 인덱스를 지정해준다면 안해줘도 됩니다.

 

2. 동영상 열기 - cv2.VideoCapture

 OpenCV를 이용해서 동영상 여는 방법은 카메라 여는 방법과 동일합니다.

 차이점은 cv2.VideoCapture() 안에 인덱스 대신에 파일명을 넣어주면 됩니다.

 

[명령어 설명]

cv2.VideoCapture(filename, apiPreference=None) -> retval

 

 filename : 비디오 파일 이름, 정지 영상 시퀀스, 비디오 스트림 URL 등, ex) 'video.avi', 'img_%02d.jpg', 'protocol://host:port/script?params|auth'

 apiPreference : 선호하는 카메라 처리 방법을 지정합니다.

 retval : cv2.VideoCapture 객체를 반환합니다.

 

[예시 코드]

cap = cv2.VideoCapture('video1.mp4')

 저는 미리 다운받아놨던 'video1.mp4'를 지정했습니다.

 

3. 비디오 캡쳐가 준비되었는지 확인하기 - cv2.VideoCapture.isOpened()

 VideoCapture 객체를 생성하면 잘 되었는지 확인해봅시다.

 cv2.VideoCapture.isOpened() 명령어로 확인할 수 있습니다.

 

[명령어 설명]

cv2.VideoCapture.isOpened() -> retval

 

retval : 성공하면 True, 실패하면 False 반환

 

[예시 코드]

 # 카메라가 열렸는지 확인
if not cap.isOpened():
    print("Camera open failed!") # 열리지 않았으면 문자열 출력
    sys.exit()

 

4. 프레임 받아오기 - cv2.VideoCapture.read()

 카메라, 동영상을 성공적으로 열었으면 read()명렁어를 통해 카메라, 동영상에서 프레임을 받아올 수 있습니다.

 

[명령어 설명]

cv2.VideoCapture.read(image=None) -> retval, image

 

 retval : 성공하면 True, 실패하면 False.

 image : 현재 프레임 (numpy.ndarray)

 두 개의 반환값이 있다는 점을 주의해야 합니다.

 

[예시 코드]

# 비디오 매 프레임 처리
while True: # 무한 루프
    ret, frame = cap.read() # 두 개의 값을 반환하므로 두 변수 지정

    if not ret: # 새로운 프레임을 못받아 왔을 때 braek
        break
        
    # 정지화면에서 윤곽선을 추출
    edge = cv2.Canny(frame, 50, 150)
    
    inversed = ~frame  # 반전

    cv2.imshow('frame', frame)
    cv2.imshow('inversed', inversed)
    cv2.imshow('edge', edge)

    # 10ms 기다리고 다음 프레임으로 전환, Esc누르면 while 강제 종료
    if cv2.waitKey(10) == 27:
        break

cap.release() # 사용한 자원 해제
cv2.destroyAllWindows()

 

 기존 동영상에 윤곽선과 반전 효과를 넣은 동영상도 출력하도록 했습니다.

 

 

 기존 영상, 반전 영상, 윤곽선 영상이 출력되었습니다.

 

5. 카메라와 비디오 장치 속성 값 참조 - cv2.VideoCapture.get()

 영상의 속성 값을 참조하는 방법을 알아보겠습니다.

 cv2.VideoCapture.get() 명령어를 이용하면 됩니다.

 

[명령어 설명]

cv2.VideoCapture.get(propId) -> retval

 

 proId에 속성 상수를 입력하면 원하는 속성을 얻어올 수 있습니다.

 prodID : 속성 상수. OpenCV 홈페이지에서 더 많은 속성 상수를 확인할 수 있습니다.

 retval : 성공하면 해당 속성 값, 실패하면 0

 

[예시 코드]

# 비디오 프레임 크기, 전체 프레임수, FPS 등 출력
print('Frame width:', int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)))
print('Frame height:', int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print('Frame count:', int(cap.get(cv2.CAP_PROP_FRAME_COUNT)))

fps = cap.get(cv2.CAP_PROP_FPS)
print('FPS:', fps)

영상의 속성

 1초 당 24프레임이고 전체 프레임은 85이므로 대략 3~4초 영상이라는 것을 확인할 수 있습니다.

 

6. 카메라나 동영상 장치 속성 값 지정 - cv2.VideoCapture.set()

cv2.VideoCapture.set() 명령어로 속성 값을 수정할 수 있습니다.

 

[명령어 설명]

cv2.VideoCapture.set(propId, value) -> retval

 

 prodID : 속성 상수. OpenCV 홈페이지에서 더 많은 속성 상수를 확인할 수 있습니다.

 value : 속성 값

 retval : 성공하면 True, 실패하면 False

 

[예시 코드]

# 프레임 속성 받아오기
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(w, h) # 640, 480


# set 명령어로 원하는 프레임 속성 지정 가능
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)

 

 이처럼 640, 480 크기의 영상을 320, 240 크기로 변환하여 출력할 수 있습니다.

 

반응형