【问题标题】:Opencv cpp process different part of same video with multithreadOpencv cpp用多线程处理同一视频的不同部分
【发布时间】:2018-06-26 10:05:24
【问题描述】:

如何在 5 个不同的线程中只使用一个视频捕获?并同时处理它们?

我现在正在做的是在 5 个线程中使用 5 个视频捕获。但是,处理时间比在一个线程中线性执行视频要长。我想在 2 分钟内处理一个 10 分钟的视频(将 10 分钟的视频分成 5 个线程)。

有没有更好的建议?


更新:

我通过将巨大的内存空间分配给一个数组并将矩阵临时存储在该数组中来做到这一点。它非常消耗内存,最后我将视频帧存储在 jpg 文件中,并在需要时调用它。后者是一种更有效的方法。

【问题讨论】:

    标签: c++ opencv


    【解决方案1】:

    您可以通过相同的VideoCapture 对象抓取帧,但在多个线程中处理帧。下面是一个非常简单的例子。

    #include <iostream>
    #include <thread>
    
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    
    void blur(cv::Mat &image) {
      cv::GaussianBlur(image, image, cv::Size(7,7), -1);
    }
    
    int main(int argc, char *argv[]) {
    
        cv::VideoCapture cap("video.mp4");
    
        if(!cap.isOpened())
        {
            std::cout<<"VideoCapture did not open"<<std::endl;
            return -1;
        }
    
        cv::Mat frames[2];
        std::thread tds[2];
    
        while(true) {
            if(!cap.read(frames[0]) || !cap.read(frames[1]))
            {
                std::cout<<"Frames empty"<<std::endl;
                break;
            }
    
            tds[0] = std::thread(&blur, std::ref(frames[0]));
            tds[1] = std::thread(&blur, std::ref(frames[1]));
    
            tds[0].join();
            tds[1].join();
    
            cv::imshow("Frame", frames[0]);
            if ((cv::waitKey(30) & 0XFF) == 'q')
                break;
        }
    
        cap.release();
        cv::destroyAllWindows();
    
        return 0;
    }
    

    【讨论】:

    • 如果我有 2 小时的视频(超过 200k 帧),这可行吗?在这段代码中,线程总数与总帧数成正比
    • @VivianYeoh 您可以启动任意数量的线程。但请记住,您的处理器可以处理有限数量的线程。
    • 仍然认为它不是很有效。但是谢谢你告诉我
    猜你喜欢
    • 2021-06-23
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    相关资源
    最近更新 更多