황선규 박사님의 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 크기로 변환하여 출력할 수 있습니다.
'Python > 파이썬 OpenCV 공부' 카테고리의 다른 글
[파이썬 OpenCV] 키보드 입력으로 출력된 영상 반전 시키기 - cv2.waitkey, ord() 함수 (0) | 2020.09.27 |
---|---|
[파이썬 OpenCV] 동영상 저장하기 - cv2.VideoWriter 클래스 (0) | 2020.09.27 |
[파이썬 OpenCV] 그리기 함수 - line, rectangle, circle, polyines, putText (0) | 2020.09.25 |
[파이썬 OpenCV] 마스크 연산과 ROI - cv2.copyTo 함수 이용 방법 (0) | 2020.09.25 |
[파이썬 OpenCV] 영상의 생성, 복사, 부분 영상 추출 (0) | 2020.09.25 |