====================================
imagezmq: Transporting OpenCV images
====================================
**imagezmq** is a set of Python classes that transport OpenCV images from one
computer to another using PyZMQ messaging. For example, here is a screen on a
Mac computer showing simultaneous video streams from 8 Raspberry Pi cameras:
.. image:: https://raw.githubusercontent.com/jeffbass/imagezmq/master/docs/images/screenshottest.png
Using **imagezmq**, this is possible with 11 lines of Python on each Raspberry
Pi and with 8 lines of Python on the Mac.
First, run this receiver program on the Mac (or other display computer):
.. code-block:: python
# run this program on the Mac to display image streams from multiple RPis
import cv2
import imagezmq
image_hub = imagezmq.ImageHub()
while True: # show streamed images until Ctrl-C
rpi_name, image = image_hub.recv_image()
cv2.imshow(rpi_name, image) # 1 window for each RPi
cv2.waitKey(1)
image_hub.send_reply(b'OK')
Then, on each Raspberry Pi, run this sender program:
.. code-block:: python
# run this program on each RPi to send a labelled image stream
# you can run it on multiple RPi's; 8 RPi's running in above example
import socket
import time
from picamera2 import Picamera2
import imagezmq
sender = imagezmq.ImageSender(connect_to='tcp://jeff-macbook:5555')
rpi_name = socket.gethostname() # send RPi hostname with each image
picam = Picamera2()
picam.start()
time.sleep(2) # allow camera sensor to warm up
while True: # send images as stream until Ctrl-C
image = picam.capture_array()
sender.send_image(rpi_name, image)
Wow! A video surveillance system with 8 (or more!) Raspberry Pi cameras in
19 lines of Python.
Why use imagezmq?
=================
**imagezmq** is an easy to use image transport mechanism for a distributed image
processing network. For example, a network of a dozen Raspberry Pis with cameras
can send images to a more powerful central computer. The Raspberry Pis perform
image capture and simple image processing like flipping, blurring and motion
detection. Then the images are passed via **imagezmq** to the central computer for
more complex image processing like image tagging, text extraction, feature
recognition, etc.
Each **imageZMQ** message is a ``(text_message, image)`` tuple. The text
portion of the tuple identifies the source and other info about the image. In
the example above, the ``text_message`` portion identifies which RPi is sending the
the image so that the receiver can put each unique RPi image stream into a
specific window. More details about the **imageZMQ** tuples in the above example
are `here <https://github.com/jeffbass/imagezmq>`_.
Features
========
- Sends OpenCV images from one computer to another using ZMQ.
- Can send jpeg compressed OpenCV images, to lighten network loads.
- Uses the powerful ZMQ messaging library through PyZMQ bindings.
- Allows a choice of 2 different ZMQ messaging patterns (REQ/REP or PUB/SUB).
- Enables the image hub to receive and process images from multiple image senders
simultaneously.
Why ZMQ? Why not some other messaging protocol?
===============================================
There are a number of high quality and well maintained messaging protocols for
passing messages between computers. I looked at MQTT, RabbitMQ, AMQP and ROS as
alternatives. I chose ZMQ and its Python PyZMQ bindings for several reasons:
- ZMQ does not require a message broker. It is a peer to peer protocol that does
not need to pass an image first to a message broker and then to the imagehub.
This means fewer running processes and less “double handling” of images.
OpenCV images are large compared to simple text messages, so the absence of a
message broker is important.
- ZMQ is very fast for passing OpenCV images. It enables high throughput between
image senders and image hubs.
- ZMQ and its PyZMQ bindings are easy to install.
**imagezmq** has been transporting images from a dozen Raspberry Pi computers
scattered around my farm to 2 linux image hub servers for over 2
years. The RPi's capture and send dozens to thousands of frames frames a day.
**imagezmq** has worked very reliably and is very fast. You can learn more about
my "science experiment urban permaculture farm" project at
`Yin Yang Ranch project overview <https://github.com/jeffbass/yin-yang-ranch>`_.
Messaging Patterns: REQ/REP versus PUB/SUB
==========================================
ZMQ allows many different messaging patterns. Two are implemented in **imagezmq**:
- REQ/REP: Each RPi sends an image and waits for a REPLY from the central image
hub. The RPi sends a new image only when the REPLY is received. In the REQ/REP
messaging pattern, each image sender must await a REPLY before continuing. It is a
"blocking" pattern for the sender.
- PUB/SUB: Each RPi sends an image, but does not expect a REPLY from the central
image hub. It can continue sending images without awaiting any acknowledgement
from the image hub. The image hub provides no REPLY. It is a "non-blocking"
pattern for the sender.
There are advantages and disadvantages for each pattern.
**REQ/REP is the default.** See the documentation (link below) for more details.
Dependencies and Installation
=============================
**imagezmq** has been tested with:
- Python 3.5, 3.6, 3.7, 3.8, 3.9, 3.10 and 3.11
- PyZMQ 16.0, 17.1, 19.0 and 26.0
- Numpy 1.13, 1.16, 1.18 and 1.24
- OpenCV 3.3, 4.0, 4.1 and 4.6
- Raspberry Pi OS Bookworm and Bullseye using PiCamera2
- Raspbian OS Buster, Stretch and Raspbian Jessie using legacy PiCamera
Install OpenCV, including Numpy, into a Python Virtual Environment. Then be sure
to install **imagezmq** into the **same** virtual environment. For example,
on a Raspberry Pi running Raspberry Pi OS Bookworm, my virtual
environment is named **py311cv4**.
Install **imageZMQ** using pip:
.. code-block:: bash
workon py311cv4 # use your virtual environment name
pip install imagezmq
**imagezmq** has a directory of tests organized into sender and receiver pairs.
You will get all the source code for **imagezmq** including all the test
programs by cloning the GitHub repository:
.. code-block:: bash
git clone https://github.com/jeffbass/imagezmq.git
Source Code and Full Documentation
==================================
**imagezmq** is open source. The source code, tests and
documentation are at `Imagezmq on GitHub <https://github.com/jeffbass/imagezmq>`_.
The documentation, including links to application examples,
starts from the table of contents in the README.
Raw data
{
"_id": null,
"home_page": "https://github.com/jeffbass/imagezmq",
"name": "imagezmq",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.5",
"maintainer_email": null,
"keywords": "opencv-python, pyzmq, raspberrypi",
"author": "Jeff Bass",
"author_email": "jeff@yin-yang-ranch.com",
"download_url": "https://files.pythonhosted.org/packages/00/2b/bda02b566a0ae651f4e7dc313d1d50ea508220aceec9f1e3a7c7d98ae554/imagezmq-1.2.0.tar.gz",
"platform": null,
"description": "====================================\nimagezmq: Transporting OpenCV images\n====================================\n\n**imagezmq** is a set of Python classes that transport OpenCV images from one\ncomputer to another using PyZMQ messaging. For example, here is a screen on a\nMac computer showing simultaneous video streams from 8 Raspberry Pi cameras:\n\n.. image:: https://raw.githubusercontent.com/jeffbass/imagezmq/master/docs/images/screenshottest.png\n\nUsing **imagezmq**, this is possible with 11 lines of Python on each Raspberry\nPi and with 8 lines of Python on the Mac.\n\nFirst, run this receiver program on the Mac (or other display computer):\n\n.. code-block:: python\n\n # run this program on the Mac to display image streams from multiple RPis\n import cv2\n import imagezmq\n image_hub = imagezmq.ImageHub()\n while True: # show streamed images until Ctrl-C\n rpi_name, image = image_hub.recv_image()\n cv2.imshow(rpi_name, image) # 1 window for each RPi\n cv2.waitKey(1)\n image_hub.send_reply(b'OK')\n\n\nThen, on each Raspberry Pi, run this sender program:\n\n.. code-block:: python\n\n # run this program on each RPi to send a labelled image stream\n # you can run it on multiple RPi's; 8 RPi's running in above example\n import socket\n import time\n from picamera2 import Picamera2\n import imagezmq\n\n sender = imagezmq.ImageSender(connect_to='tcp://jeff-macbook:5555')\n\n rpi_name = socket.gethostname() # send RPi hostname with each image\n picam = Picamera2()\n picam.start()\n time.sleep(2) # allow camera sensor to warm up\n while True: # send images as stream until Ctrl-C\n image = picam.capture_array()\n sender.send_image(rpi_name, image)\n\n\nWow! A video surveillance system with 8 (or more!) Raspberry Pi cameras in\n19 lines of Python.\n\nWhy use imagezmq?\n=================\n\n**imagezmq** is an easy to use image transport mechanism for a distributed image\nprocessing network. For example, a network of a dozen Raspberry Pis with cameras\ncan send images to a more powerful central computer. The Raspberry Pis perform\nimage capture and simple image processing like flipping, blurring and motion\ndetection. Then the images are passed via **imagezmq** to the central computer for\nmore complex image processing like image tagging, text extraction, feature\nrecognition, etc.\n\nEach **imageZMQ** message is a ``(text_message, image)`` tuple. The text \nportion of the tuple identifies the source and other info about the image. In \nthe example above, the ``text_message`` portion identifies which RPi is sending the\nthe image so that the receiver can put each unique RPi image stream into a\nspecific window. More details about the **imageZMQ** tuples in the above example\nare `here <https://github.com/jeffbass/imagezmq>`_.\n\nFeatures\n========\n\n- Sends OpenCV images from one computer to another using ZMQ.\n- Can send jpeg compressed OpenCV images, to lighten network loads.\n- Uses the powerful ZMQ messaging library through PyZMQ bindings.\n- Allows a choice of 2 different ZMQ messaging patterns (REQ/REP or PUB/SUB).\n- Enables the image hub to receive and process images from multiple image senders\n simultaneously.\n\nWhy ZMQ? Why not some other messaging protocol?\n===============================================\n\nThere are a number of high quality and well maintained messaging protocols for\npassing messages between computers. I looked at MQTT, RabbitMQ, AMQP and ROS as\nalternatives. I chose ZMQ and its Python PyZMQ bindings for several reasons:\n\n- ZMQ does not require a message broker. It is a peer to peer protocol that does\n not need to pass an image first to a message broker and then to the imagehub.\n This means fewer running processes and less \u201cdouble handling\u201d of images.\n OpenCV images are large compared to simple text messages, so the absence of a\n message broker is important.\n- ZMQ is very fast for passing OpenCV images. It enables high throughput between\n image senders and image hubs.\n- ZMQ and its PyZMQ bindings are easy to install.\n\n**imagezmq** has been transporting images from a dozen Raspberry Pi computers\nscattered around my farm to 2 linux image hub servers for over 2\nyears. The RPi's capture and send dozens to thousands of frames frames a day.\n**imagezmq** has worked very reliably and is very fast. You can learn more about\nmy \"science experiment urban permaculture farm\" project at\n`Yin Yang Ranch project overview <https://github.com/jeffbass/yin-yang-ranch>`_.\n\nMessaging Patterns: REQ/REP versus PUB/SUB\n==========================================\n\nZMQ allows many different messaging patterns. Two are implemented in **imagezmq**:\n\n- REQ/REP: Each RPi sends an image and waits for a REPLY from the central image\n hub. The RPi sends a new image only when the REPLY is received. In the REQ/REP\n messaging pattern, each image sender must await a REPLY before continuing. It is a\n \"blocking\" pattern for the sender.\n- PUB/SUB: Each RPi sends an image, but does not expect a REPLY from the central\n image hub. It can continue sending images without awaiting any acknowledgement\n from the image hub. The image hub provides no REPLY. It is a \"non-blocking\"\n pattern for the sender.\n\nThere are advantages and disadvantages for each pattern.\n**REQ/REP is the default.** See the documentation (link below) for more details.\n\nDependencies and Installation\n=============================\n\n**imagezmq** has been tested with:\n\n- Python 3.5, 3.6, 3.7, 3.8, 3.9, 3.10 and 3.11\n- PyZMQ 16.0, 17.1, 19.0 and 26.0\n- Numpy 1.13, 1.16, 1.18 and 1.24\n- OpenCV 3.3, 4.0, 4.1 and 4.6\n- Raspberry Pi OS Bookworm and Bullseye using PiCamera2\n- Raspbian OS Buster, Stretch and Raspbian Jessie using legacy PiCamera\n\nInstall OpenCV, including Numpy, into a Python Virtual Environment. Then be sure\nto install **imagezmq** into the **same** virtual environment. For example,\non a Raspberry Pi running Raspberry Pi OS Bookworm, my virtual \nenvironment is named **py311cv4**.\n\nInstall **imageZMQ** using pip:\n\n.. code-block:: bash\n\n workon py311cv4 # use your virtual environment name\n pip install imagezmq\n\n**imagezmq** has a directory of tests organized into sender and receiver pairs.\nYou will get all the source code for **imagezmq** including all the test\nprograms by cloning the GitHub repository:\n\n.. code-block:: bash\n\n git clone https://github.com/jeffbass/imagezmq.git\n\nSource Code and Full Documentation\n==================================\n\n**imagezmq** is open source. The source code, tests and\ndocumentation are at `Imagezmq on GitHub <https://github.com/jeffbass/imagezmq>`_.\nThe documentation, including links to application examples,\nstarts from the table of contents in the README.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Transporting OpenCV images via ZMQ",
"version": "1.2.0",
"project_urls": {
"Homepage": "https://github.com/jeffbass/imagezmq"
},
"split_keywords": [
"opencv-python",
" pyzmq",
" raspberrypi"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "f289b6aa9b9ffce26511cf2ed105e6587596879ec7c7ce1ae1a5c3a52aabe476",
"md5": "2faecff2510d5ae4afe858dd4ddc7184",
"sha256": "4e29959dc6316c5819f241382a32dd8cd9eb63e29996501c07de35f198005b02"
},
"downloads": -1,
"filename": "imagezmq-1.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2faecff2510d5ae4afe858dd4ddc7184",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.5",
"size": 8881,
"upload_time": "2024-07-18T05:11:00",
"upload_time_iso_8601": "2024-07-18T05:11:00.866780Z",
"url": "https://files.pythonhosted.org/packages/f2/89/b6aa9b9ffce26511cf2ed105e6587596879ec7c7ce1ae1a5c3a52aabe476/imagezmq-1.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "002bbda02b566a0ae651f4e7dc313d1d50ea508220aceec9f1e3a7c7d98ae554",
"md5": "9aae566de231bd0c4fb50cd96005d100",
"sha256": "4e83ec867b6abb26a987235f7c2c71955f5e2755422ca309337a53bc8aa6e5b4"
},
"downloads": -1,
"filename": "imagezmq-1.2.0.tar.gz",
"has_sig": false,
"md5_digest": "9aae566de231bd0c4fb50cd96005d100",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.5",
"size": 18017,
"upload_time": "2024-07-18T05:11:02",
"upload_time_iso_8601": "2024-07-18T05:11:02.462626Z",
"url": "https://files.pythonhosted.org/packages/00/2b/bda02b566a0ae651f4e7dc313d1d50ea508220aceec9f1e3a7c7d98ae554/imagezmq-1.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-07-18 05:11:02",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jeffbass",
"github_project": "imagezmq",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "imagezmq"
}