OpenCV:来自 VideoWriter 的写入是不是应该在独立线程中运行?

Posted

技术标签:

【中文标题】OpenCV:来自 VideoWriter 的写入是不是应该在独立线程中运行?【英文标题】:OpenCV: Should the write from VideoWriter run in an independent thread?OpenCV:来自 VideoWriter 的写入是否应该在独立线程中运行? 【发布时间】:2014-03-13 09:01:50 【问题描述】:

我正在编写一个程序,它可以读取多个网络摄像头,将图片拼接在一起并将它们保存到一个视频文件中。

    我应该使用线程来捕获图像并将生成的大图像写入文件吗? 如果是,我应该使用 c+11 还是 boost? 您是否有一些简单的示例代码来说明如何避免赛车条件?

我已经找到了this thread,它使用线程进行写入,但它似乎无法避免出现竞速情况。

我的程序的伪代码:

camVector //vector with cameras
VideoWriter outputVideo //outputs the video

while(true)
    for(camera:camVector)
        camera.grab() //send signal to grab picture
    
    picVector = getFrames(camVector) //collect frames of all cameras into a Vector

    Mat bigImg = stitchPicTogether(picVector)

    outputVideo.write(bigImg)

【问题讨论】:

关于比赛条件:你能详细说明你的缝合吗?它是简单地平铺还是涉及边缘混合? 如有疑问,请避免使用线程。 (顺便说一句,捕获已经在运行一个单独的线程以进行 img 检索) @berak:如有疑问,请避免 *** 可以谈论任何事情!硬件限制决定了并行性将继续存在,因此更好地使用它;) @Antoine:Mat bigImg 被分成几个不重叠的Mat subimg。捕获的帧通过remap(使用仿射变换)复制到 bigImg 的正确 subImg 部分。完成所有帧的复制后,可以保存帧。 酷,如果没有重叠,那么您可以安全地并行执行remaps。 【参考方案1】:

这就是我要做的:

camVector //vector with cameras
VideoWriter outputVideo //outputs the video

for(camera:camVector) camera.grab(); // request first frame

while(true)
    parallel for(camera:camVector) 
        frame = getFrame(camera);
        pasteFrame(/* destination */ bigImg,
                   /* geometry    */ geometry[camera],
                   /* source      */ frame
                  );
        camera.grab(); // request next frame, so the webcam driver can start working
                       // while you write to disk
    
    outputVideo.write(bigImg)

这种拼接是并行完成的,如果您的网络摄像头驱动程序有不同的时间,您可以在等待另一个网络摄像头的帧时开始拼接您从一个网络摄像头收到的内容。

关于实现,您可以简单地使用已在 OpenCV 中使用的 OpenMP,例如 #pragma omp parallel。如果你更喜欢类似 C++ 的东西,试试 Intel TBB,很酷。

或者如您所说,您可以使用本机 C++11 线程或 boost。两者之间的选择主要取决于您的工作环境:如果您打算使用较旧的编译器,boost 更安全。

在所有情况下,除了最后的连接之外,不需要锁定来等待所有线程完成它们的工作。

如果您的瓶颈是写入输出,则限制因素是磁盘 IO 或视频压缩速度。对于磁盘,您可以尝试更改编解码器和/或压缩更多。对于压缩速度,请查看 GPU 编解码器,例如 this。

【讨论】:

我做到了,唯一的问题是我是否也应该在并行线程中进行写入。我不确定 OpenCV 是如何处理这些东西的。 OpenCV 逐行工作,对于子图像,它会更改标题,以便在选定行的范围内仅更新特定范围。如果范围不重叠,则写入不会发生冲突。 我们有一点误会。我的意思是使用VideoWriterbigImg 写入硬盘驱动器。在我的伪代码中,outputVideo.write(bigImg)好的,很抱歉让您误会了。确实,从多个文件写入文件将是一项挑战! OpenCV 只是 ffmpeg、directX 等库的包装器。但是您可以管道磁盘写入和网络摄像头驱动程序请求,我相应地编辑了我的答案。

以上是关于OpenCV:来自 VideoWriter 的写入是不是应该在独立线程中运行?的主要内容,如果未能解决你的问题,请参考以下文章

OPENCV,无法打开类 VideoWriter

使用opencv中的VideoWriter函数,保存视频

OpenCV videowriter 不写视频

无法在 iOS 10 上使用 OpenCV 3.1 使用 VideoWriter 创建文件

Python OpenCV 将摄像头/视频写入视频文件

cv2.VideoWriter 不会使用fourcc h.264写入文件(使用罗技c920,python 2.7,windows 8)