해당 포스팅은 Mastering OpenCV 4 with Python 원서를 바탕으로 작성했습니다. 원서를 옮기는 과정에서 부자연스러운 부분이 있을 수 있습니다. 잘못 작성되거나 어색한 부분에 대해서 알려주시면 감사하겠습니다!
이번 포스팅에서는 이전 포스팅에 이어서 동영상에 관련한 내용을 포함하고 있습니다.
- 파일과 이미지를 다루기 위한 이론적 소개
- 이미지 불러오고 저장하기
- 카메라 프레임과 비디오 파일 불러오기
- 비디오 파일 저장하기
1. 카메라 프레임과 비디오 파일 불러오기
일부 프로젝트에서는 우리는 카메라 프레임을 캡쳐해야 합니다. OpenCV에서는 카메라로부터 캡쳐하기 위한 명령어인 cv2.VideoCapture가 존재합니다. VideoCapture는 이미지 시퀀스, 비디오 파일 및 카메라와 같이 다양한 소스로부터 비디오를 캡쳐합니다.
카메라 프레임 불러오고 저장하는 코드는 접은 글에 표현해놨습니다. 혹시 직접 돌려보고 싶으시다면, 접은 글을 참고해주세요. 아래에 나오는 코드 블럭은 일부를 포함하고 있어서 실행이 안될 수 있습니다.
import cv2
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("index_camera", help="index of the camera to read from", type=int)
args = parser.parse_args()
# 지정한 index의 카메라로부터 VideoCapture 객체를 생성
capture = cv2.VideoCapture(args.index_camera)
# get으로 caputure 객체의 속성을 얻을 수 있습니다
frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)
# 얻은 속성 값 표시
print(f"CV_CAP_PROP_FRAME_WIDTH: {frame_width}")
print(f"CV_CAP_PROP_FRAME_HEIGHT: {frame_height}")
print(f"CAP_PROP_FPS: {fps}")
# 카메라와 연결되어 있는 지 확인(연결: True, 아니면 False)
if capture.isOpened() is False:
print("Error opening the camera")
#frame_index 선언
frame_index = 0
while capture.isOpened():
# 카메라로부터 프레임을 반환하는 메소드
# ret은 카메라로부터 frame을 잘 얻어냈는 지를 알려주는 boolean type
ret, frame = capture.read()
# frame이 이상없이 읽어왔다면 True
if ret:
# frame을 표시
cv2.imshow('Input frame from the camera', frame)
# 얻은 frame을 gray_frame으로 변경
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 변경한 gray_frame도 표시
cv2.imshow('Grayscale input camera', gray_frame)
# c가 입력되면 프레임을 저장
if cv2.waitKey(20) & 0xFF == ord('c'):
frame_name = f"camera_frame_{frame_index}.png"
gray_frame_name = f"grayscale_camera_frame_{frame_index}.png"
cv2.imwrite(frame_name, frame)
cv2.imwrite(gray_frame_name, gray_frame)
frame_index += 1
# waitKey(20) 20ms동안 key를 기다립니다. 만약 0이면 무한대기, 입력된 키는 아스키코드와 관련이 있음.
# q가 입력되면 프로그램 종료
if cv2.waitKey(20) & 0xFF == ord('q'):
break
else:
break
# 카메라 연결 해제
capture.release()
cv2.destroyAllWindows()
1) 카메라 프레임 읽어오기
먼저, 컴퓨터에 연결된 카메라로부터 프레임을 읽어오는 read_camera.py를 작성해봅시다. read_camera.py를 작성하기 위해서는 연결된 카메라의 index가 필요합니다. 만약 컴퓨터에 웹캠이 연결되어 있다면, 그 웹캠은 0이라는 인덱스를 가지고 있습니다. 추가적으로 만약 두 번째의 카메라가 컴퓨터에 연결되어 있다면, 1번으로 선택하실 수 있습니다. 인덱스의 파라미터 타입은 항상 정수형을 가지고 있습니다.
import cv2
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("index_camera", help="index of the camera to read from", type=int)
args = parser.parse_args()
# 지정한 index의 카메라로부터 VideoCapture 객체를 생성
capture = cv2.VideoCapture(args.index_camera)
# get으로 caputure 객체의 속성을 얻을 수 있습니다
frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)
# 얻은 속성 값 표시
print(f"CV_CAP_PROP_FRAME_WIDTH: {frame_width}")
print(f"CV_CAP_PROP_FRAME_HEIGHT: {frame_height}")
print(f"CAP_PROP_FPS: {fps}")
# 카메라와 연결되어 있는 지 확인(연결: True, 아니면 False)
if capture.isOpened() is False:
print("Error opening the camera")
while capture.isOpened():
# 카메라로부터 프레임을 반환하는 메소드
# ret은 카메라로부터 frame을 잘 얻어냈는 지를 알려주는 boolen type
ret, frame = capture.read()
# frame이 이상없이 읽어왔다면 True
if ret:
# frame을 표시
cv2.imshow('Input frame from the camera', frame)
# 얻은 frame을 gray_frame으로 변경
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 변경한 gray_frame도 표시
cv2.imshow('Grayscale input camera', gray_frame)
# waitKey(20) 20ms동안 key를 기다립니다. 만약 0이면 무한대기, 입력된 키는 아스키코드와 관련이 있음.
# q가 입력되면 프로그램 종료
if cv2.waitKey(20) & 0xFF == ord('q'):
break
else:
break
# 카메라 연결 해제
capture.release()
cv2.destroyAllWindows()
각 코드가 의미하는 내용들은 주석처리로 표현했습니다. 내장 카메라가 있다고 가정했을 때, <python read_camera.py 0>을 실행하시면 아래와 같은 화면을 보실 수 있습니다.
위의 화면처럼 웹캠으로 촬영하는 실시간 화면을 보실 수 있습니다. 만약 종료하고 싶다면, q버튼을 누르면 종료할 수 있습니다.
2) 카메라 프레임 저장하기
카메라 프레임으로부터 저장하기 위해서는 위의 기본적으로 불러오는 코드에 일부만 추가하면 가능합니다.
#frame_index 선언(while문 위쪽에 작성)
frame_index = 0
# c가 입력되면 프레임을 저장(q버튼 if문 위에 작성)
if cv2.waitKey(20) & 0xFF == ord('c'):
frame_name = f"camera_frame_{frame_index}.png"
gray_frame_name = f"grayscale_camera_frame_{frame_index}.png"
cv2.imwrite(frame_name, frame)
cv2.imwrite(gray_frame_name, gray_frame)
frame_index += 1
frame_index를 설정해주고, c버튼을 누를 때마다 frame_index가 증가하면서 일반 화면과 흑백 화면의 frame을 imwrite 명령어로 저장합니다. 저는 3개의 이미지를 저장해서 아래처럼 6개의 이미지가 저장되었습니다.
2. 비디오 파일 불러오기
컴퓨터 카메라를 불러와서 capture했던 것과 유사하게 cv2.VideoCapture()에 우리가 캡쳐하고 싶은 비디오의 주소를 넣어주면 됩니다. IP camera도 마찬가지로 해당 IP camera에 연결할 수 있는 IP주소를 포함하면 됩니다. 원서에서는 https://www.cnps.cat/webcams 에 있는 웹캠에 연결하도록 했습니다만 실행이 안되었습니다. 혹시 몰라 해당 주소들을 남겨 놓겠습니다. (http://217.126.89.102:8010/axis-cgi/mjpg/video.cgi) 저는 따로 연결할 수 있는 IP camera가 없어서 융프라우 webcam 동영상 주소를 받아서 입력해줬는데 이상없이 작동했습니다. 융프라우 webcam은 너무 크다는 점을 미리 말씀드리고, 사이즈를 줄여보는 작업도 해봤는데, 적용이 안되는 것 같습니다.
비디오와 IP camera 모두 동일한 위치만 변경해주시면 됩니다. 해당 부분은 아래와 같습니다.
# Video
# Video_path argument 생성
parser.add_argument("video_path", help="path to the video file")
# 비디오 위치로부터 VideoCapture 객체를 생성
capture = cv2.VideoCapture(args.video_path)
# IP Camera
# IP Camera argument 생성
parser.add_argument("IP_Camera_path", help="path to the IP_Camera")
# IP Camera 위치로부터 VideoCapture 객체를 생성
capture = cv2.VideoCapture(args.IP_Camera_path)
해당 사이트 주소에서 영상 주소 가져오기 위해서는 아래의 과정을 통해서 얻을 수 있습니다.
- 사이트 주소에 들어갑니다 ( www.jungfrau.ch/webcams/top-of-europe-jungfraujoch/ )
- 빨간색 영상부분을 클릭합니다.
- F12를 눌러서 빨간 부분의 주소를 찾습니다. 1번 아이콘을 누르시고, 2번 영상부분을 클릭하면 해당 지점에 대한 소스코드를 확인할 수 있습니다.
- 해당 부분의 앞의 토글을 클릭합니다.
- 토글 아래에 생긴 코드에 source src의 주소를 복사해서 videoCapture에 path로 입력해주면 됩니다.
3. 비디오 저장하기
비디오 파일을 저장하기 위해서는 cv2.VideoWriter를 사용하면 되지만, fps, codecs, 비디오 파일의 형태를 먼저 소개하고 있습니다.
1) fps(frames per second) 계산하기
이전에 cv2.VideoCapture 객체로부터 속성들을 얻었을 때, fps가 포함되어 있었습니다. fps는 컴퓨터 비전에서 중요한 metric입니다. fps는 얼마나 많은 프레임을 1초에 처리하는지를 알려줍니다. 그래서 fps의 숫자가 높으면 높을수록 안전하다고 말할 수 있습니다. 하지만, 프레임의 수는 우리가 풀려는 문제가 어떤 것이냐에 따라 달라질 수 있습니다. 예를 들어, 만약 사람이 길을 걸어가는 것을 트레킹해야 한다면, 15 fps로도 충분할 것입니다. 하지만 만약 고속도로에서 지나가는 자동차를 트레킹해야 한다면, 최소 20-25 fps는 필요할 것입니다.
그래서 컴퓨터 비전에서는 fps 매트릭에 대해 어떻게 계산하는지 아는 것은 굉장히 중요합니다. 아래에 작성된 코드read_camera_fps.py는 앞에서 만들었던 read_camera.py를 fps수 출력을 위해 수정했습니다.
import cv2
import argparse
import time
parser = argparse.ArgumentParser()
parser.add_argument("index_camera", help="index of the camera to read from", type=int)
args = parser.parse_args()
# 지정한 index의 카메라로부터 VideoCapture 객체를 생성
capture = cv2.VideoCapture(args.index_camera)
# get으로 caputure 객체의 속성을 얻을 수 있습니다
frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)
# 얻은 속성 값 표시
print(f"CV_CAP_PROP_FRAME_WIDTH: {frame_width}")
print(f"CV_CAP_PROP_FRAME_HEIGHT: {frame_height}")
print(f"CAP_PROP_FPS: {fps}")
# 카메라와 연결되어 있는 지 확인(연결: True, 아니면 False)
if capture.isOpened() is False:
print("Error opening the camera")
while capture.isOpened():
# 카메라로부터 프레임을 반환하는 메소드
# ret은 카메라로부터 frame을 잘 얻어냈는 지를 알려주는 boolen type
ret, frame = capture.read()
# frame이 이상없이 읽어왔다면 True
if ret:
##### 변경된 부분 #####
# frame 처리하기 전 시간을 계산
processing_start = time.time()
######################
# frame을 표시
cv2.imshow('Input frame from the camera', frame)
# 얻은 frame을 gray_frame으로 변경
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 변경한 gray_frame도 표시
cv2.imshow('Grayscale input camera', gray_frame)
##### 변경된 부분 #####
# frame 처리 후 시간을 계산
processing_end = time.time()
# 걸린시간 구하기
processing_time_frame = processing_end - processing_start + 0.00000001
# FPS = 1/time_per_frame
print(f"fps: {1.0/processing_time_frame}")
#######################
# waitKey(20) 20ms동안 key를 기다립니다. 만약 0이면 무한대기, 입력된 키는 아스키코드와 관련이 있음.
# q가 입력되면 프로그램 종료
if cv2.waitKey(20) & 0xFF == ord('q'):
break
else:
break
# 카메라 연결 해제
capture.release()
cv2.destroyAllWindows()
위의 코드를 실행해보시면 계속해서 fps 값이 올라가는 것을 확인할 수 있습니다. 간혹 processing_end와 processing_start가 같아서 zerodivision error가 발생할 수 있기 때문에 작은 수를 더 해줬습니다.
2) 비디오 파일을 저장하기 위한 고려사항
비디오 코덱은 디지털 비디오를 압축하거나 압축을 풀어줄 때 사용하는 일종의 소프트웨어입니다. 그래서 코덱은 압축된 비디오를 압축되지 않은 비디오로 변환하거나 압축되지 않은 비디오를 압축된 비디오로 변환하는 데 사용할 수 있습니다. 압축된 비디오 형식은 보통 비디오 압축 규격이나 비디오 코딩 형식이라고 불리는 기준을 따릅니다. OpenCv는 비디오 코덱을 지정하는데 사용하는 4바이트 코드인 FOURCC를 제공합니다. FOURCC에서 사용가능한 리스트는 여기서 확인하실 수 있습니다(http://www.fourcc.org/codecs.php). 지원되는 코덱은 플랫폼에 따라 다르다는 점을 항상 고려해야 합니다. 즉, 특정 코덱으로 작업하려면 해당 코덱이 시스템에 설치되어 있어야 합니다. 일반적인 코덱에는 DIVX, XVID, X264, MJPG 등이 있습니다.
추가적으로, 비디오 파일 형식은 디지털 비디오 데이터를 저장할 때 사용되는 파일 형식입니다. 일반적인 비디오 파일 형식에는 AVI, MP4, MOV, WMV 등이 있습니다.
마지막으로, 비디오 파일 형식과 FOURCC 간의 올바른 조합은 쉽지 않다는 것을 고려해야 합니다. 그래서 OpenCV에서 비디오 파일을 만들 때, 위에서 언급한 모든 요소들을 고려해야 합니다.
위의 도표는 cv2.VideoWriter()를 사용해서 비디오를 저장할 때 고려사항들에 대해 표현하고 있습니다. 보시는 것처럼 FOURCC, 비디오 파일형식 외에도 width, height, fps들도 설정해야 합니다. 위의 그림을 예시로 해서 write_video_file.py를 만들어 보겠습니다.
import cv2
import argparse
parser = argparse.ArgumentParser()
# 비디오 파일을 저장할 위치 argument 생성
parser.add_argument("output_video_path", help="path to the video file to write")
parser.add_argument("camera_index", help="index of the camera to read from", type=int)
args = parser.parse_args()
capture = cv2.VideoCapture(args.camera_index)
frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)
# 코덱 XVID 정의
fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')
# fourcc = cv2.VideoWriter_foucc(*'XVID')
# 만약 컬러로 저장하려면 맨 마지막 boolen 값을 True로 해줘야 합니다.
out_gray = cv2.VideoWriter(args.output_video_path, fourcc, int(fps), (int(frame_width), int(frame_height)), False)
while capture.isOpened():
ret, frame = capture.read()
if ret:
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# gray_frame을 video에 저장
out_gray.write(gray_frame)
cv2.imshow('gray', gray_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
capture.release()
# out_gray 메모리 해제
out_gray.release()
cv2.destroyAllWindows()
위의 명령어를 <python write_video_file.py test.avi 0>로 치게 되면, 컴퓨터에 연결된 캠이 켜지면서 q를 누를 때까지 흑백 비디오를 얻을 수 있습니다.
3) VideoCapture 속성 정보 다루기
앞에서 frame_width, frame_height, fps 등을 얻었던 것을 기억하실 겁니다. 이번 섹션에서는 모든 속성을 어떻게 얻을 수 있는지와 그 작동 방식을 배웁니다. 마지막으로, 얻어낸 속성을 사용하여 비디오 파일을 로드하고 거꾸로 출력하는 것을 다룹니다.
먼저, read_video_file_all_properties.py를 통해 모든 속성 정보를 보여주는 스크립트를 만들어보겠습니다. 일부 속성은 비디오 파일이 아닌 카메라로 작업할 때만 작동합니다. 해당 속성에 대해서는 0이 반환됩니다. 추가적으로 capture.get(cv2.CAP_PROP_FOURCC)로 반환된 값을 코덱의 정수 표현을 포함하는 문자형 값으로 변환하는 decode_fourcc()을 아래에서 확인할 수 있습니다. 이 값은 코덱을 올바르게 출력하기 위해 4바이트 문자 표현으로 변환되어야 합니다.
def decode_fourcc(fourcc):
"""
Decodes the fourcc value to get the four chars identifying it.
"""
fourcc_int = int(fourcc)
# fourcc의 정수형 값을 표시
print(f"int value of fourcc: {fourcc_int}")
# one line
# return "".join([chr((fourcc_int >> 8 * i) & 0xFF) for i in range(4)])
fourcc_decode = ""
for i in range(4):
int_value = fourcc_int >> 8 * i & 0xFF
print(f"int_value: {int_value}")
fourcc_decode += chr(int_value)
return fourcc_decode
아래는 video를 불러와서 해당 정보들을 표시하는 코드입니다. 위에서 저장했던 비디오를 불러서 동작시켜봤더니, FRAME_WIDTH, FRAME_HEIGHT, FPS, FOURCC, FRAME_COUNT을 제외하고는 다 0이 나오는 것을 확인할 수 있었습니다.
import cv2
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("video_path", help="path to the video file")
args = parser.parse_args()
capture = cv2.VideoCapture(args.video_path)
# find decode_fourcc
fourcc_decode = decode_fourcc(capture.get(cv2.CAP_PROP_FOURCC))
print(f"decode_fourcc:{fourcc_decode}")
# Get and print these values:
print(f"CV_CAP_PROP_FRAME_WIDTH:{capture.get(cv2.CAP_PROP_FRAME_WIDTH)}")
print(f"CV_CAP_PROP_FRAME_HEIGHT:{capture.get(cv2.CAP_PROP_FRAME_HEIGHT)}")
print(f"CV_CAP_PROP_FPS:{capture.get(cv2.CAP_PROP_FPS)}")
print(f"CV_CAP_PROP_POS_MSEC:{capture.get(cv2.CAP_PROP_POS_MSEC)}")
print(f"CV_CAP_PROP_POS_FRAMES:{capture.get(cv2.CAP_PROP_POS_FRAMES)}")
print(f"CV_CAP_PROP_FOURCC:{capture.get(cv2.CAP_PROP_FOURCC)}")
print(f"CV_CAP_PROP_FRAME_COUNT:{capture.get(cv2.CAP_PROP_FRAME_COUNT)}")
print(f"CV_CAP_PROP_MODE:{capture.get(cv2.CAP_PROP_MODE)}")
print(f"CV_CAP_PROP_BRIGHTNESS:{capture.get(cv2.CAP_PROP_BRIGHTNESS)}")
print(f"CV_CAP_PROP_CONTRAST:{capture.get(cv2.CAP_PROP_CONTRAST)}")
print(f"CV_CAP_PROP_SATURATION:{capture.get(cv2.CAP_PROP_SATURATION)}")
print(f"CV_CAP_PROP_HUE:{capture.get(cv2.CAP_PROP_HUE)}")
print(f"CV_CAP_PROP_GAIN:{capture.get(cv2.CAP_PROP_GAIN)}")
print(f"CV_CAP_PROP_EXPOSURE:{capture.get(cv2.CAP_PROP_EXPOSURE)}")
print(f"CV_CAP_PROP_CONVERT_RGB:{capture.get(cv2.CAP_PROP_CONVERT_RGB)}")
print(f"CV_CAP_PROP_RECTIFICATION:{capture.get(cv2.CAP_PROP_RECTIFICATION)}")
print(f"CV_CAP_PROP_ISO_SPEED:{capture.get(cv2.CAP_PROP_ISO_SPEED)}")
print(f"CV_CAP_PROP_BUFFERSIZE:{capture.get(cv2.CAP_PROP_BUFFERSIZE)}")
if capture.isOpened() is False:
print("Error opening video stream or file")
while capture.isOpened():
ret, frame = capture.read()
if ret:
# iteration 당 현재 프레임 수 표시
print(f"CAP_PROP_POS_FRAMES: {capture.get(cv2.CAP_PROP_POS_FRAMES)}")
# milliseconds 현재 프레임의 timestamp를 표시
print(f"CAP_PROP_POS_MSEC: {capture.get(cv2.CAP_PROP_POS_MSEC)}")
# frame 표시
cv2.imshow('Original frame', frame)
# frame을 grayscale로 변환
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Grayscale frame 표시
cv2.imshow('Grayscal frame', gray_frame)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
else:
break
capture.release()
cv2.destroyAllWindows()
비디오에서 얻은 FOURCC를 위의 식에 넣었더니 아래와 같은 결과를 얻을 수 있었습니다.
4) 비디오 거꾸로 실행하기
비디오를 거꾸로 실행하기 위해서는 총 Frame의 개수를 알아야 합니다. 이를 위해 cv2.CAP_PROP_FRAME_COUNT 정보를 얻어야 합니다. 이를 활용해서 read_video_file_backwards.py 코드를 짜볼 수 있습니다.
import cv2
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("video_path", help="path to the video file")
args = parser.parse_args()
capture = cv2.VideoCapture(args.video_path)
if capture.isOpened() is False:
print('Error opening video stream or file')
# 전체 프레임 수를 구해서 1개 뺀 것을 frame_index로 넣어서 시작 frame으로 넣어줄 예정.
frame_index = capture.get(cv2.CAP_PROP_FRAME_COUNT) - 1
print((f"starting in frame: {frame_index}"))
# frame_index >=0일 때만 while문 실행
while capture.isOpened() and frame_index >= 0:
# 시작하는 frame을 맨 마지막 프레임으로 세팅
capture.set(cv2.CAP_PROP_POS_FRAMES, frame_index)
ret, frame = capture.read()
if ret:
print(f"CAP_PROP_POS_FRAMES : {capture.get(cv2.CAP_PROP_POS_FRAMES)}")
print(f"CAP_PROP_POS_MSEC : {capture.get(cv2.CAP_PROP_POS_MSEC)}")
cv2.imshow('Original frame', frame)
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('Grayscale frame', gray_frame)
# 거꾸로 실행 index 하나씩 빼주기
frame_index = frame_index-1
print(f"next index to read : {frame_index}")
if cv2.waitKey(25) & 0xFF == ord('q'):
break
else:
break
capture.release()
cv2.destroyAllWindows()
실행해보시면 아까 촬영한 동영상을 반대로 재생하는 화면을 보실 수 있습니다.
4. 요약
- 카메라 접근, IP 카메라, 비디오에 접근하기 위해서는 cv2.VideoCapture에 주소를 넣어주면 됩니다.
- 프레임을 저장할 때에는 imwrite를 사용합니다.
- 비디오를 저장할 때에는 fps, 코덱, 비디오 파일형식, width, height 등을 고려해야 합니다.
- 비디오 저장할 때, cv2.VideoWriter를 생성한 뒤 write 명령어로 저장할 수 있습니다.
- VideoCapture에는 많은 속성이 존재하지만 비디오와 웹캠에서 얻을 수 있는 정보 수는 다릅니다.
- 비디오나 웹캠으로부터 FOURCC값을 얻어서 decode하면 해당 FOURCC 코덱이 무엇인지 알 수 있습니다.
- 비디오를 거꾸로 실행할 때에는 cv2.CAP_PROP_FRAME_COUNT의 속성 정보를 얻어서 frame_index를 줄여가면 가능합니다.