반응형

fps를 화면에 표시해주고 동영상 파일로 저장하면서 webcam 영상을 보여주는 OpenCV C++ 예제 코드입니다. 

저장된 동영상 파일이 빠르게 재생되는 문제가 없습니다.



2022. 1. 3  최초작성



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


using namespace std;
using namespace cv;


int main(int argc, char* argv[])
{

    cv::VideoCapture cap(0);

    if (!cap.isOpened())
    {
        std::cout << "웹캠을 열 수 없습니다.\n";
        return -1;
    }


    cv::Mat frame;

    bool ret = cap.read(frame);
    if (!ret)
    {
        cout << "캡쳐 실패" << endl;
        return -1;
    }


    VideoWriter writer;

    int fourcc = VideoWriter::fourcc('X','2','6','4');

    // 녹화된 파일이 빠르게 재생되는 현상은 웹캠의 fps를 가져와서 VideoWriter에 입력해주면 해결됨.
    // 웹캠에서 fps값을 가져오지 못하는 경우 cap.get(CAP_PROP_FPS)의 리턴값이 0이 됨. 수동으로 입력해줘야함.
    // https://answers.opencv.org/question/16522/video-recording-is-too-fast/
    double fps = cap.get(CAP_PROP_FPS);
    writer.open("output.avi", fourcc, fps, frame.size());
    if (!writer.isOpened()) {
        cout << "녹화를 준비할 수 없습니다.\n";
        return -1;
    }

    while(1)
    {
        auto total_start = chrono::steady_clock::now();

        bool ret = cap.read(frame);
        if (!ret)
        {
            cout << "캡쳐 실패" << endl;
            return -1;
        }

       
        writer.write(frame);
       
        auto total_end = chrono::steady_clock::now();


        float total_fps = 1000.0 / chrono::duration_cast<chrono::milliseconds>(total_end - total_start).count();


        std::ostringstream stats_ss;
        stats_ss << fixed << setprecision(2);
        stats_ss << "Total FPS: " << total_fps;
        auto stats = stats_ss.str();
         

        int baseline;
        auto stats_bg_sz = getTextSize(stats.c_str(), FONT_HERSHEY_COMPLEX_SMALL, 1, 1, &baseline);
        rectangle(frame, Point(0, 0), Point(stats_bg_sz.width, stats_bg_sz.height + 10), Scalar(0, 0, 0), FILLED);
        putText(frame, stats.c_str(), Point(0, stats_bg_sz.height + 5), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255, 255, 255));


        namedWindow("output");
        imshow("output", frame);
       

        int key = waitKey(1);
        if (key == 27) // ESC 키 누르면 중지
            break;
    }

    cap.release();
    writer.release();

    return 0;
}




반응형

해보고 확인한 것을 문서화하여 기록합니다.


부족함이 있지만 도움이 되었으면 합니다.
잘못된 부분이나 개선점을 알려주시면 감사하겠습니다.



포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
문제가 생기면 포스트와 바뀐 환경이 있나 먼저 확인해보세요.

질문을 남겨주면 가능한 빨리 답변드립니다.


제가 쓴 책도 한번 검토해보세요 ^^

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기

댓글을 달아 주세요

">