录像机的多线程

Posted

技术标签:

【中文标题】录像机的多线程【英文标题】:multithreading for video recorder 【发布时间】:2017-01-10 09:52:24 【问题描述】:

我使用的是 GigEPRO 相机,根据图像大小,它的能力为 60fps 或更高。因此对于 60fps 表示 1 帧/16ms。但是videowriter函数本身消耗2-4ms。所以我决定将图像存储在vector<Mat> 并创建一个child_thread,它负责使用来自OpenCV 的writer 函数通过访问矢量图像并擦除存储的图像来将图像写入视频。

我对此实现的查询很少。 我可以使用vector<Mat> 来存储图像还是应该创建一个队列。? 如何将 child_thread 与主线程同步?

我是多线程编程的新手,因此正在寻找一些输入

【问题讨论】:

你的数学错了。 60fps => 1000ms / 60 帧 = 每 16.666 ... 毫秒 1 帧。无论如何,将采集线程和写入/记录器线程与中间的帧队列解耦是一个很好的理智做法;-) 哦。是的,谢谢。但我不确定如何在编码中实现。一般来说,我想稍后通过减小图像大小将 fps 提高到 100 fps。 请参阅this answer 以获取灵感。 @Dan Masek,我看到了您的代码以及可能的最大 fps 是多少?因为我需要大约 1200*700 的 130fps 图像分辨率,单通道图像持续 20 秒。 【参考方案1】:

将采集线程和写入器/记录器线程与中间的帧队列解耦是一种良好的理智做法。

在某些时候,传入的流可能比输出写入操作更快(尤其是在写入速度较慢的设备(例如磁盘)时)。 为了防止队列不断增长(这会耗尽 PC 上的所有可用内存),您可以考虑使用具有最大项目限制的队列。

一种选择是编写您自己的类似队列的类: 1. 在内部使用合适的容器(即 std::queue 或 std::deque,因为默认的 std::queue 已经使用了 std::deque) 2. 只公开你需要的函数(即构造函数、push(frame)、pop()、size()、...)

为了线程安全,您可以考虑使用类内部 std::mutex 保护类似队列的类方法,最好使用 std::lock_guard。 更好的方法是使用无锁容器,正确编写更复杂,但您可以在 web 或 github 上找到一些实现。

【讨论】:

【参考方案2】:

高帧率录制的解决方案是使用 MATLAB 的图像采集工具箱,它支持 GigE 和 GenIcam。使用 ROI 为 1000x700,我将达到 150fps,这可以通过 32GBRam 的处理器和高处理速度实现。通常使用 8GB 内存和 i7 处理器我可以达到 50fps。此外,为了获得更好的图像质量,将曝光时间更改为 1000 微秒是最佳选择。在图像采集工具箱中,有一个将数据记录在内存或磁盘中的选项。登录内存是更好的选择,因为数据在停止采集后导出,同时将数据记录到磁盘,同时写入数据。

【讨论】:

以上是关于录像机的多线程的主要内容,如果未能解决你的问题,请参考以下文章

《计算机视觉中的多视图几何》笔记有限射影摄像机

使用 OpenCv 和多线程从 IP 摄像机提供实时视频

如何迁移EasyNVR视频监控系统视频录像文件的存储位置?

Opencv IP 摄像机错误

EasyCVR视频平台开发录像模块采用gRPC方式做负载均衡的步骤介绍

gRPC方式做负载均衡在EasyCVR视频平台录像模块的应用示例