OpenCV - VideoCapture

스윗포테이토·2022년 10월 7일
1

OpenCV

목록 보기
2/3

VideoCapture

OpenCV에서 카메라 또는 동영상 파일로부터 프레임을 받아올 때 사용하는 클래스.

우선 기본 코드는 이렇게 된다.

영상 읽어서 재생하기

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {
    //"path" 경로에 있는 영상을 읽어오기
    VideoCapture cap("path");
    
    // 에러 방지 코드 - 영상이 정상적으로 열렸는지 확인
    if (!cap.isOpened()) {
        cout << "video not found\n";
        return -1;
    }
    // 영상의 fps를 바탕으로 delay 계산
    double fps = cap.get(CAP_PROP_FPS);
    int delay = cvRound(1000 / fps);
    
    Mat frame; // 프레임을 받을 변수 선언
    int cnt = 0; // 프레임 개수를 저장하는 변수
    
    while (++cnt) {
        cap.read(frame);
        if (frame.empty()) { // 프레임을 받아오지 못함 (영상 종료)
            break;
        }
        imshow("video", frame); // "video"이름으로 창을 띄움
        if (waitKey(delay) > 0) { // delay만큼 입력을 기다림, 만약 키보드 입력이 있을 경우 break
            break;
        }
    }
    // 프레임 수 출력
    cout << "# of frame: " << cnt;
    return 0;
}

위에서 fps를 바탕으로 waitKey()에 delay를 설정해주는데, 이 부분에 대해서는 좀 더 자세히 적어보려고 한다.

waitKey()

우선 영상을 띄워주기 위해서 imshow()함수를 쓸 때 필수적으로 따라오는 함수이다. waitKey()는 인자로 받는 시간만큼 키 입력을 받아 리턴 값으로 돌려주고, 단위는 ms이다. 따라서 1초동안 입력을 받고 싶다면 1000을 넘겨주면 된다. 만약 키 입력을 제대로 받지 못한다면 이미지가 띄워진 창을 한번 클릭하여 포커스를 맞춰준 후 다시 입력해보길 바란다.
여기까지 말하면 뭔가 선택사항 인 것 같지만, 만약 이 코드를 쓰지 않으면, imshow()함수는 이미지 창을 바로 꺼버린다. 따라서 흔적이라도 보고 싶으면 1ms라도 waitKey()를 꼭 걸어주어야 한다.

fps

Frame per Second, 말 그대로 초당 몇 프레임짜리인지 표기하는 영상의 정보이다. 우리가 보는 영상은 프레임의 연속이다. 즉, 연속적인 사진의 모음이라고 생각하면 된다. 이 정보가 중요한 이유는 영상의 속도에 영향을 미치기 때문이다. 어떤 영상이 100개의 프레임으로 이루어진 영상이라고 생각해보자. 만약 fps가 25라면, 이 영상은 100/25 = 4초짜리 영상이라는 것을 알 수 있다. 만약 30이라면, 100/20 = 5초짜리 영상이 된다. 따라서 이 fps는 영상의 속도를 알기 위해 필요한 정보가 된다. OpenCV로 영상을 열어서 재생하기 위해서 fps를 꼭 알아야 하는 것은 아니지만, fps를 모른다면 원본 재생 속도에 맞추어 영상을 띄워 줄 수 없다.

정리하자면,

전체 프레임 수 = 초당 프레임[frame/s] x 영상의 길이[s]

그렇다면 하나의 프레임과 다음 프레임 사이의 간격을 얼마나 될까? 간단하다, 프레임 당 시간이니 Second per Frame, fps의 역수이다.

하나의 프레임이 차지하는 시간[s] = 전체 시간 / 프레임의 수
					      = 영상 길이[s] / 프레임의 수[frame]
                          = 1 / fps
                          = 1000 / fps (ms)

따라서 하나의 프레임을 1000 / fpsms 만큼 유지한 후, 다음 프레임을 보여주면 된다.

profile
나의 삽질이 미래의 누군가를 구할 수 있다면...

0개의 댓글