2 minute read



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!