【问题标题】:How to increase fps opencv multi camera setup如何增加 fps opencv 多摄像头设置
【发布时间】:2017-11-10 23:20:32
【问题描述】:

我有一个 OpenCV 程序,它可以尽可能快地同时从 2 个摄像头获取图像。为了让两个相机尽可能靠近拍摄图像,我使用了 grab() 和 retrieve() 函数。我现在得到的帧速率很慢(大约 6 fps)。我想增加这个fps。有谁知道如何提高fps?

我在想也许可以将每个相机放在不同的线程上或以某种方式利用多线程,但我担心它们不会以这种方式同时捕获图像。

void takeImages(VideoCapture& cap, VideoCapture& cap1, int imagecount){


    if(!cap.isOpened()|| !cap1.isOpened()) {  // check if we succeeded
        cout << "Can not open cameras." << endl;
        return;
    }


    Mat frame, frame2;
    for(int x = 0;x < imagecount; x++)
    {
        // Capture image from both camera at the same time (important).
        if( !cap.grab() || !cap1.grab() )
        {

            cout << "Can not grab images." << endl;
            return;
        }


        if( cap.retrieve(frame,3) || cap1.retrieve(frame,3)){

            //process images here..

        } else {
            cout << "Can not retrieve images." << endl;
            return;
        }

        printf("x = %d\n", x);
    }

    waitKey(0);
}



int main(int, char**)
{

    // trying to set higher program priority to increase fps here
    cout << "Nice = " << nice(21) << endl;

    VideoCapture cap(0); // open the default camera
    VideoCapture cap1(1);


    namedWindow("cam1",1);
    namedWindow("cam2",1);

    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    //Get the time it takes to get 200 frames from BOTH cameras.
    takeImages(cap,cap1, 200);

    std::chrono::steady_clock::time_point end= std::chrono::steady_clock::now();
    std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::seconds>(end - begin).count() <<std::endl;

    return 0;
}

【问题讨论】:

    标签: c++ opencv


    【解决方案1】:

    您应该能够通过将每个摄像头移动到自己的线程来使 fps 翻倍。要同步相机,您可以使用std::chrono::steady_clock 确保它们同时捕捉。

    可能是这样的:

    #include <thread>
    
    using steady_clock = std::chrono::steady_clock;
    
    void takeImages(VideoCapture& cap, int imagecount,
        steady_clock::time_point next_frame, unsigned fps)
    {
        assert(fps > 0);
        assert(fps <= 1000);
    
        Mat frame;
        for(int x = 0; x  < imagecount; x++)
        {
            // Capture image from both camera at the same time (important).
            std::this_thread::sleep_until(next_frame);
            next_frame += std::chrono::milliseconds(1000 / fps);
    
            if(!cap.grab())
                throw std::runtime_error("Can not grab image.");
    
            if(!cap.retrieve(frame, 3))
                throw std::runtime_error("Can not retrieve image.");
    
            // process image here
    
        }
    
        waitKey(0);
    }
    
    int main(int, char**)
    {
        try
        {
            // trying to set higher program priority to increase fps here
            // cout << "Nice = " << nice(21) << endl;
    
            VideoCapture cap0(0); // open the default camera
            VideoCapture cap1(1 + CAP_V4L2);
    
            if(!cap0.isOpened() || !cap1.isOpened())
            {  // check if we succeeded
                cout << "Can not open cameras." << endl;
                return EXIT_FAILURE;
            }
    
    //      namedWindow("cam1", WINDOW_AUTOSIZE);
    //      namedWindow("cam2", WINDOW_AUTOSIZE);
    
            std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    
            // pass the same time point to both threads to synchronize their
            // frame start times
            steady_clock::time_point next_frame = steady_clock::now() + std::chrono::milliseconds(50);
    
            std::thread t1{takeImages, std::ref(cap0), 200, next_frame, 10};
            std::thread t2{takeImages, std::ref(cap1), 200, next_frame, 10};
    
            t1.join();
            t2.join();
    
            std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
            std::cout << "Time difference = "
                << std::chrono::duration_cast<std::chrono::seconds>(end - begin).count()
                << std::endl;
        }
        catch(std::exception const& e)
        {
            std::cerr << e.what() << '\n';
            return EXIT_FAILURE;
        }
    
        return EXIT_SUCCESS;
    }
    

    【讨论】:

    • 我必须澄清我的 fps 很慢,因为还没有任何处理,只是运行我发布的代码。在那种情况下这会有帮助吗?
    • @bakalolo 因为cap.retrieve() 应该是较慢的部分,以前的方法可能提供了一些好处。但是我已经发布了一个新方法,它应该更有效,因为它不会在每次迭代时启动新线程。
    • 似乎 waitkey 阻止了我的代码,当我删除它时它运行良好..
    【解决方案2】:

    您使用单台相机可以获得多少 fps?多线程应该是探索以提高 fps 的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-05
      • 2014-03-18
      • 1970-01-01
      • 2022-06-10
      • 2015-04-30
      • 2019-05-28
      • 1970-01-01
      • 2012-10-24
      相关资源
      最近更新 更多