多个摄像机源的策略,每个摄像机的不同处理以及流式传输源后记[重复]

问题描述 投票:0回答:1

大家好,

我在使用 python 为我的问题选择策略时遇到困难。 我有两个摄像头(将来可能会更多)连接到我的本地网络,并且想要获取两个流,对它们进行一些图像处理,并在将来将它们流式传输到本地 http 服务器。

我的第一个问题是,从相机读取帧,主要是 IO 密集型还是 CPU 密集型。

其次,我想知道是否/何时选择多处理路线,我应该如何实现它。首先,我有一个“三层结构”的想法,其中获取帧是由一个处理器在“DAL”层中完成的,由另一个处理器完成处理,也许将来第三个处理器会处理所有的 http 内容。 (http服务器是另一个时间)。

但是经过一些研究后,我不确定这是正确的方法吗?也许一个处理器应该处理从相机收集的所有 IO,进行处理并将其流式传输到 http 服务器。

有比我更有经验的人可以给我一些见解吗?

我有一些使用 python 和 opencv 的经验,但没有使用任何多线程/处理库,因为它更多的是论文的概念证明。

感谢您阅读这篇头脑风暴

相机规格为: 1080x720分辨率 帧率 160 fps 使用 GigE Vision 协议

python computer-vision camera
1个回答
0
投票

我的第一个问题是,从相机读取帧,主要是 IO 密集型还是 CPU 密集型。

虽然网络 I/O 在某种程度上需要 CPU 密集型处理,但该处理发生在操作系统内核中。对于您的应用程序来说,它看起来就像 I/O。

其次,我想知道是否/何时选择多处理路线,我应该如何实现它。

您可以进行很多微调,但我认为坚持 KISS 原则并根据需要调整您的应用程序非常重要。

根据您的描述,我希望您的申请主要处于三个阶段之一:

  1. 等待下一帧或将其复制到 numpy 数组中
  2. 调用多个 C 函数来实现 OpenCV 处理
  3. 等待网络输出发送帧

如果您不想丢失帧,则应该(几乎)始终有一个专用线程执行步骤 1。否则 GigE 视觉会很高兴地丢弃它无法缓冲的帧。

对于步骤 2,您应该首先检查您的 OpenCV 处理是否在内部并行化,或者甚至可能使用 GPU 处理。在这种情况下,在其之上添加多处理或多线程几乎没有任何好处。

步骤 3 与步骤 1 类似,只是有一个线程随时准备发送图像,以保持网络层繁忙。由于此步骤涉及 TCP,因此并行使用多个 HTTP 连接可能会有所帮助。当然这取决于您的接收器。

就并行化而言,您最关心的是全局解释器锁(GIL)。 https://wiki.python.org/moin/GlobalInterpreterLock 但是,请注意该特定网站:

事后看来,GIL 并不理想,因为它会阻止多线程 CPython 程序在某些情况下充分利用多处理器系统。幸运的是,许多潜在的阻塞或长时间运行的操作(例如 I/O、图像处理和 NumPy 数字运算)都发生在 GIL 之外。因此,只有在多线程程序中,在 GIL 中花费大量时间来解释 CPython 字节码时,GIL 才会成为瓶颈。

换句话说,如果您所做的只是调用一些长时间运行的 C 函数,无论是网络 I/O 还是 OpenCV 处理,您都可以使用多线程。否则你可能需要多重处理。

请注意,多重处理会给整个处理带来更多成本,因为您需要将帧从一个应用程序复制到另一个应用程序。

总之,这是我的设置方法:

  1. 每个相机一个线程,除了获取图像之外什么都不做
  2. 一个线程或线程池执行图像处理(同样,如果 OpenCV 内部并行化,不要在其上放置线程池)
  3. 一个线程将帧发送到您的 http 服务器

所有阶段都应与

queue.Queues
queue.SimpleQueues
连接。这些应该受到大小限制,以避免在处理停止时耗尽内存。

如果您发现确实需要多处理,则可以将队列替换为

multiprocessing.Queues
,并将所有线程替换为专用
multiprocessing.Processes
。或者,阶段 1 中的线程可以简单地为每个传入帧调用
multiprocessing.Pool.apply_async
,并通过
Queue
将 AsyncResult 对象传递到阶段 3。

© www.soinside.com 2019 - 2024. All rights reserved.