이번 글에서는 OpenCV를 사용하여 비디오 파일을 불러오고 재생하는 방법을 알아보겠습니다. 이전 주제에서 배운 카메라 영상 처리 방식과 거의 동일한 절차를 따르지만, 한 가지 중요한 차이점이 있습니다. VideoCapture 클래스 객체의 인자에 숫자(카메라 인덱스) 대신 재생하려는 비디오 파일의 경로를 지정해야 한다는 것입니다.
기본 원리
OpenCV에서 웹캠과 같은 기본 카메라를 사용할 때는 VideoCapture cap(0);처럼 장치 번호를 넘겼습니다. 하지만 컴퓨터에 저장된 비디오 파일을 재생할 때는 파일명 또는 전체 경로를 문자열로 전달하면 됩니다. 예를 들어 프로젝트 폴더에 있는 'video.mp4' 파일을 열려면 다음과 같이 작성합니다.
VideoCapture cap("video.mp4");파일 경로가 올바르지 않거나 코덱 문제로 파일을 열 수 없는 경우를 대비해, isOpened() 함수로 스트림이 정상적으로 열렸는지 반드시 확인하는 것이 좋습니다.
예제 코드
다음 프로그램은 C++와 OpenCV를 이용해 컴퓨터에 저장된 비디오 파일을 불러와 재생하는 전체 과정을 보여줍니다.
#include<opencv2/opencv.hpp>// VideoCapture 클래스를 사용하기 위한 OpenCV 헤더 //
#include<iostream>
using namespace std;
using namespace cv;
int main() {
Mat myImage;// 프레임을 담을 행렬 선언 //
namedWindow("Video Player");// 비디오를 표시할 창 선언 //
VideoCapture cap("video.mp4");// 비디오 파일에서 프레임 스트림을 가져올 객체 선언 //
if (!cap.isOpened()){ // 비디오 스트림을 찾지 못하면 에러 메시지 출력 //
cout << "No video stream detected" << endl;
system("pause");
return-1;
}
while (true){ // 비디오를 계속 보여주기 위한 무한 루프 //
cap >> myImage;
if (myImage.empty()){ // 더 이상 읽어올 프레임이 없으면 루프 종료 //
break;
}
imshow("Video Player", myImage);// 비디오 화면 출력 //
char c = (char)waitKey(25);// 프레임당 25밀리초 대기 및 종료 조건 검사 //
if (c == 27){ // 'Esc' 키 입력 시 루프 종료 //
break;
}
}
cap.release();// 버퍼 메모리 해제 //
return 0;
}코드 설명
주요 부분을 단계별로 살펴보면 다음과 같습니다.
- Mat myImage; — 각 비디오 프레임을 저장할 행렬(Matrix) 변수입니다. OpenCV에서 이미지 데이터는 Mat 객체로 다룹니다.
- namedWindow() — 비디오가 출력될 창을 생성합니다.
- VideoCapture cap("video.mp4") — 핵심 부분으로, 숫자 대신 파일 경로를 인자로 전달하여 비디오 파일을 엽니다.
- cap >> myImage; — 추출 연산자(>>)를 사용해 프레임을 하나씩 행렬로 읽어옵니다.
- myImage.empty() — 비디오의 마지막 프레임까지 재생하면 빈 행렬이 반환되므로, 이를 감지해 루프를 종료합니다.
- waitKey(25) — 각 프레임 사이에 25밀리초의 지연을 두어 적절한 재생 속도를 만들며, 'Esc'(ASCII 코드 27) 키 입력 시 즉시 종료됩니다.
실행 결과
위 코드를 컴파일하고 실행하면 'Video Player'라는 제목의 창이 열리고, 지정한 비디오 파일이 자동으로 재생됩니다. 비디오가 끝나면 프로그램은 자동으로 종료되며, 재생 도중 'Esc' 키를 눌러 언제든 중단할 수 있습니다.

마무리
이처럼 OpenCV의 VideoCapture 클래스는 카메라 입력뿐만 아니라 로컬 비디오 파일도 손쉽게 처리할 수 있게 해줍니다. 실제 프로젝트에서는 파일 존재 여부 확인, 다양한 코덱 지원, 재생 속도 조절 등 추가적인 예외 처리를 함께 구현하는 것이 좋습니다.