3.2 동영상 다루기
3.2.1 동영상 파일 처리
대부분의 동영상 파일들은 코덱을 사용해 압축된 형태로 저장된다. OpenCV에는 MPEG-4, H.264 등의 코덱 해석 기능을 제공. VideoCapture
클래스를 사용하여 동영상 파일을 불러오자. Sec. 3.1의 카메라 입력 처리와 비슷하다.
VideoCapture cap;
cap.open("video.mp4");
생성자를 사용해 한 줄로 줄이면,
VideoCapture cap("video.mp4");
동영상 파일은 FPS 값을 가지고 있다. 이걸 고려하지 않으면 영상 재생 속도가 이상해진다.
double fps = cap.get(CAP_PROP_FPS);
FPS 값으로부터 매 프레임 사이의 시간 간격을 계산 가능.
int delay = cvRound(1000 / fps);
예를 들어, 30 FPS의 동영상이라면 delay
값은 33. 즉 매 프레임이 33ms마다 출력되어야 한다는 의미이다. 이 delay
값은 영상을 출력하는 while
문 내에서 waitkey()
의 인자로써 쓰인다.
다음은 동영상 파일을 불러오는 예시 코드. Sec. 3.1과 별반 다르지 않다.
Line 19 : 전체 프레임 수 출력.
Line 21 ~ 22 : 비디오의 FPS를 받아 와 출력.
Line 23 : FPS 값으로부터 각 프레임 사이의 시간 간격 delay(ms) 계산.
Line 38 : delay 시간만큼 키 입력을 대기.
아, VideoCapture
클래스로 동영상을 재생할 때는 오디오는 출력되지 않는다.
3.2.2 VideoWriter
클래스 - 동영상 파일 저장
OpenCV로 일련의 프레임을 동영상 파일로 만들어 저장할 수 있다. 여기에는 VideoWriter
클래스가 필요.
VideoWriter
객체를 만들고 VideoWriter::open()
멤버 함수를 이용해 저장할 동영상 파일을 쓰기 모드로 연다.
VideoWriter::VideoWriter(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true);
bool VideoWriter::open(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true);
---
- filename : 저장할 동영상 이름.
- fourcc : 동영상 압축 코덱을 나타내는 4-문자 코드.
- fps : 저장할 동영상의 FPS.
- frameSize : 동영상 프레임의 가로, 세로 크기
- isColor : true 이면 컬러 동영상, false 이면 그레이스케일 동영상으로 저장.(Windows에서만 지원)
- return : 열기가 성공하면 true, 아니면 false.
VideoWriter::fourcc
- 코덱 생성
fourcc
는 코덱을 나타내는 정수 값, four charactor code의 약자이다. fourcc
에 해당하는 값은 VideoWriter::fourcc()
함수로 생성 가능.
static int VideoWriter::fourcc(char c1, char c2, char c3, char c4);
---
- c1, c2, c3, c4 : 코덱을 표현하는 1 byte 문자들.
- return : 정수형 4-문자 코드.
DivX MPEG-4 코덱을 이용하는 동영상 파일을 생성할 경우,
VideoWriter video;
int fourcc = VideoWriter::fourcc('D', 'I', 'V', 'X');
video.open("output.avi", fourcc, fps, Size(w, h));
VideoWriter
클래스는 VideoWriter::open()
과 같은 인자의 생성자를 지원하므로, 한 줄로 줄이면
VideoWriter video("output.avi", fourcc, fps, Size(w, h));
VideoWriter::write()
- 프레임 추가
열려 있는 동영상 파일에 새 프레임을 추가할 때는 VideoWriter::write()
멤버 함수 또는 <<
연산자 재정의를 사용한다.
VideoWriter& VideoWriter::operator << (const Mat& image);
void VideoWriter::write(InputArray image);
---
- image : 추가할 프레임.
이때 추가할 image
프레임은 동영상 파일을 생성할 때 지정한 프레임과 같은 크기를 가져야 한다. 컬러인지 그레이스케일인지 확인하는 것도 주의.
VideoWriter::release()
- 파일 닫기
virtual void VideoWriter::release();
열려 있던 파일을 닫는 함수. VideoWriter
클래스에는 소멸자가 있으므로 객체가 소멸되면 자동으로 파일이 닫힌다.
3.2.3 카메라 입력과 동영상 파일 저장
컴퓨터/노트북에 연결된 카메라로부터 프레임을 입력받아 동영상 파일을 생성해 보자.
그런데 실제로 실행하면 문제가 발생한다.
[ERROR:0@1.052] global C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\cap.cpp (597) cv::VideoWriter::open VIDEOIO(CV_IMAGES): raised OpenCV exception:
OpenCV(4.5.5) C:\build\master_winpack-build-win64-vc15\opencv\modules\videoio\src\cap_images.cpp:253: error: (-5:Bad argument) CAP_IMAGES: can't find starting number (in the name of file): asset/output.avi in function 'cv::icvExtractPattern'
File open failed!