通过 ZMQ 传输 OpenCV 图像 - 增强。
项目描述
imagezmq是一组 Python 类,它们使用 PyZMQ 消息传递将 OpenCV 图像从一台计算机传输到另一台计算机。例如,这是 Mac 计算机上的一个屏幕,显示来自 8 个 Raspberry Pi 摄像头的同步视频流:
使用imagezmq,在每个 Raspberry Pi 上使用 11 行 Python 并在 Mac 上使用 8 行 Python 就可以做到这一点。
首先,在 Mac(或其他显示计算机)上运行此代码:
<small class="ln"> 1 </small># run this program on the Mac to display image streams from multiple RPis
<small class="ln"> 2 </small>import cv2
<small class="ln"> 3 </small>import imagezmq
<small class="ln"> 4 </small>image_hub = imagezmq.ImageHub()
<small class="ln"> 5 </small>while True: # show streamed images until Ctrl-C
<small class="ln"> 6 </small>rpi_name, image = image_hub.recv_image()
<small class="ln"> 7 </small>cv2.imshow(rpi_name, image) # 1 window for each RPi
<small class="ln"> 8 </small>cv2.waitKey(1)
<small class="ln"> 9 </small>image_hub.send_reply(b'OK')
然后,在每个 Raspberry Pi 上,运行:
<small class="ln"> 1 </small># run this program on each RPi to send a labelled image stream
<small class="ln"> 2 </small>import socket
<small class="ln"> 3 </small>import time
<small class="ln"> 4 </small>from imutils.video import VideoStream
<small class="ln"> 5 </small>import imagezmq
<small class="ln"> 6 </small><small class="ln"> 7 </small>
sender = imagezmq.ImageSender(connect_to='tcp://jeff-macbook:5555')
<small class="ln"> 8 </small><small class="ln"> 9 </small>
rpi_name = socket.gethostname() # send RPi hostname with each image
<small class="ln">10 </small>picam = VideoStream(usePiCamera=True).start()
<small class="ln">11 </small>time.sleep(2.0) # allow camera sensor to warm up
<small class="ln">12 </small>while True: # send images as stream until Ctrl-C
<small class="ln">13 </small>image = picam.read()
<small class="ln">14 </small>sender.send_image(rpi_name, image)
哇!在 19 行 Python 中包含 8 个(或更多!)Raspberry Pi 摄像头的视频监控系统。
为什么要使用 imagezmq?
imagezmq是一个易于使用的分布式图像处理网络的图像传输机制。例如,一个由十几个带有摄像头的树莓派组成的网络可以将图像发送到功能更强大的中央计算机。树莓派执行图像捕获和简单的图像处理,如翻转、模糊和运动检测。然后图像通过imagezmq传递到中央计算机进行更复杂的图像处理,如图像标记、文本提取、特征识别等。
特征
使用 ZMQ 将 OpenCV 图像从一台计算机发送到另一台计算机。
可以发送 jpeg 压缩的 OpenCV 图像,以减轻网络负载。
通过 PyZMQ 绑定使用强大的 ZMQ 消息传递库。
允许选择 2 种不同的 ZMQ 消息传递模式(REQ/REP 或 PUB/SUB)。
使图像中心能够同时接收和处理来自多个图像发送者的图像。
为什么选择 ZMQ?为什么不使用其他消息传递协议?
有许多高质量且维护良好的消息传递协议用于在计算机之间传递消息。我将 MQTT、RabbitMQ、AMQP 和 ROS 作为替代方案。我选择 ZMQ 及其 Python PyZMQ 绑定有几个原因:
ZMQ 不需要消息代理。它是一种点对点协议,不需要先将图像传递给消息代理,然后再传递给 imagehub。这意味着更少的运行进程和更少的图像“双重处理”。与简单的文本消息相比,OpenCV 图像很大,因此没有消息代理很重要。
ZMQ 对于传递 OpenCV 图像非常快。它支持图像发送器和图像集线器之间的高吞吐量。
ZMQ 及其 PyZMQ 绑定很容易安装。
两年多来, imagezmq一直在将分散在我农场周围的十几台 Raspberry Pi 计算机的图像传输到 2 个 linux 图像中心服务器。RPi 每天捕获并发送数十到数千帧帧。 imagezmq工作非常可靠并且速度非常快。您可以在阴阳牧场项目概述中了解有关我的“科学实验城市永续农业农场”项目的 更多信息。
消息传递模式:REQ/REP 与 PUB/SUB
ZMQ 允许许多不同的消息传递模式。两个在imagezmq中实现:
REQ/REP:每个 RPi 发送一个图像并等待来自中央图像集线器的回复。RPi 仅在收到 REPLY 时才发送新图像。在 REQ/REP 消息传递模式中,每个图像发送者必须等待回复才能继续。对于发件人来说,这是一种“阻塞”模式。
PUB/SUB:每个 RPi 发送一个图像,但不期望来自中央图像集线器的回复。它可以继续发送图像,而无需等待图像中心的任何确认。图像中心不提供回复。对于发件人来说,这是一种“非阻塞”模式。
每种模式都有优点和缺点。 REQ/REP 是默认值。有关更多详细信息,请参阅文档(下面的链接)。
依赖和安装
imagezmq已经过测试:
Python 3.5、3.6、3.7 和 3.8
PyZMQ 16.0 和 17.1
Numpy 1.13 和 1.16
OpenCV 3.3 和 4.0
Raspbian Buster、Raspbian Stretch 和 Raspbian Jessie
picamera 1.13(用于为测试捕获图像)
imutils 0.4.6 和 0.5.2(用于从 PiCamera 捕获图像)
将 OpenCV(包括 Numpy)安装到 Python 虚拟环境中。然后确保将imagezmq安装到相同的虚拟环境中。例如,如果虚拟环境名为py3cv3,您将 使用 pip安装imagezmq ,如下所示:
workon py3cv3 # use your virtual environment name
pip install imagezmq
imagezmq有一个测试目录,分为发送者和接收者对。您将通过克隆 GitHub 存储库获得imagezmq的所有源代码,包括所有测试程序:
git clone https://github.com/jeffbass/imagezmq.git
源代码和完整文档
imagezmq是开源的。源代码、测试和文档位于GitHub 上的 Imagezmq。该文档(包括指向应用程序示例的链接)从 README 中的目录开始。