如何在两个 python 程序中共享 OpenCV 图像? [英] How to share OpenCV images in two python programs?
问题描述
我有三个 python 文件:glob_var.py、read_cam.py、read_globVar.py.它们的内容如下:glob_var.py:
I have three python files: glob_var.py, read_cam.py, read_globVar.py. Their contents are as below: glob_var.py:
globVar = {}
def set(name, val):
globVar[name] = val
def get(name):
val = globVar.get(name, None)
return val
read_cam.py
import cv2
import glob_var
if __name__ == '__main__':
cam = cv2.VideoCapture(0)
key = 0
while key != 27:
ret, img = cam.read()
cv2.imshow('img', img)
key = cv2.waitKey(1) & 0xFF
glob_var.set('image', img)
read_globVar.py
import glob_var
import cv2
from time import sleep
if __name__ == '__main__':
key = 0
while key != 27:
img = glob_var.get('image')
if img is None:
print(f"no image in globVar")
sleep(1)
continue
print(f"read image with shape {img.shape}")
cv2.imshow('image', img)
key = cv2.waitKey(1) & 0xFF
从那三只巨蟒中,我想你们知道我想做什么.是的,我希望 read_cam.py 从相机读取图像并将其广播到全局变量.然后 read_globVar.py 可以获取图像并显示它.我在一个终端中运行 read_cam.py,在另一个终端中运行 read_globVar.py.但我没有让它正常工作.我想的可能吗?我该如何管理?非常感谢!
From those three python flies, I think you guys know what I want to do. Yes, I want read_cam.py to read images from the camera and broadcast it to a global variable. Then read_globVar.py can get the image an show it. I run read_cam.py in one terminal and read_globVar.py in another one. But I did not make it work properly. Is what I am thinking possible? How can I manage it? Thanks a lot!
======update1:python 中的 Pub 和 Sub=====
我已经使用了一段时间的 ROS(机器人操作系统)系统.它提供了 pub 和 sub 功能来在不同的程序或所谓的节点之间交换变量.所以我的问题是python中是否有任何包提供这样的功能? Redis提供了这个,它是最快的还是最好的方法?
=====update1: Pub and Sub in python=====
I have used the ROS(Robot Operating System) system for a while. It provide the pub and sub funtion to exchange variables between different programs or so called node. So my question is that is there any package in python provide such function? Redis provide this, is it the fastest or best way?
推荐答案
您可以使用 Redis 来做到这一点.它是一个非常快的内存数据结构服务器,可以提供字符串、整数、散列、列表、队列、集合、有序集合、图像.它可以免费且简单地安装在 macOS、Linux 和 Windows 上.
You could use Redis to do this. It is a very fast, in-memory data structure server that can serve strings, integers, hashes, lists, queues, sets, ordered sets, images. It is free and simple to install on macOS, Linux and Windows.
此外,您可以使用 bash
、Python、PHP、C/C++ 或许多其他语言读取或写入 Redis 值.此外,您可以从网络或世界各地的服务器读取或写入数据,只需在初始连接中更改 IP 地址即可.因此,您可以有效地在 Linux 下的 Raspberry Pi 上使用 Python 获取图像,并将它们存储在您的 PC 上,并在 Windows 下使用 C/C++ 进行处理.
Also, you can read or write Redis values with bash
, Python, PHP, C/C++ or many other languages. Furthermore, you can read or write to or from a server across the network or across the world, just change the IP address in the initial connection. So, effectively you could acquire images in Python on your Raspberry Pi under Linux and store them and process them on your PC under Windows in C/C++.
然后您只需将图像放入 Redis,命名为 Camera1
或 Entrance
或将它们放入已排序的哈希中,以便您可以缓冲图像按帧数.您还可以给图像(或其他数据结构)一个 生存时间",这样您的 RAM 就不会被填满.
Then you just put your images into Redis, named as Camera1
or Entrance
or put them in a sorted hash so you can buffer images by frame number. You can also give images (or other data structures) a "Time-To-Live" so that your RAM doesn't fill up.
以下是为使用 Redis 而粗略重写的代码骨架.目前没有内置严重的错误检查或灵活性.一切正常.
Here's the bones of your code roughly rewritten to use Redis. No serious error checking or flexibility built in for the moment. It all runs fine.
这是read_cam.py
:
#!/usr/bin/env python3
import cv2
import struct
import redis
import numpy as np
def toRedis(r,a,n):
"""Store given Numpy array 'a' in Redis under key 'n'"""
h, w = a.shape[:2]
shape = struct.pack('>II',h,w)
encoded = shape + a.tobytes()
# Store encoded data in Redis
r.set(n,encoded)
return
if __name__ == '__main__':
# Redis connection
r = redis.Redis(host='localhost', port=6379, db=0)
cam = cv2.VideoCapture(0)
key = 0
while key != 27:
ret, img = cam.read()
cv2.imshow('img', img)
key = cv2.waitKey(1) & 0xFF
toRedis(r, img, 'image')
<小时>
这里是read_globvar.py
:
#!/usr/bin/env python3
import cv2
from time import sleep
import struct
import redis
import numpy as np
def fromRedis(r,n):
"""Retrieve Numpy array from Redis key 'n'"""
encoded = r.get(n)
h, w = struct.unpack('>II',encoded[:8])
a = np.frombuffer(encoded, dtype=np.uint8, offset=8).reshape(h,w,3)
return a
if __name__ == '__main__':
# Redis connection
r = redis.Redis(host='localhost', port=6379, db=0)
key = 0
while key != 27:
img = fromRedis(r,'image')
print(f"read image with shape {img.shape}")
cv2.imshow('image', img)
key = cv2.waitKey(1) & 0xFF
<小时>
请注意,您可以将图像高度和宽度同样存储在 JSON 中,并将其存储在 Redis 中,而不是我所做的 struct.pack
和 struct.unpack
东西.
另请注意,您可以在内存中将图像编码为 JPEG,并将 JPEG 存储在 Redis(而不是 Numpy 数组)中,这可能会节省内存和网络带宽.
Note too that you could encode your image as a JPEG in memory and store the JPEG in Redis (instead of a Numpy array) and that might save memory and network bandwidth.
不管怎样,使用Redis的概念都是一样的.
Either way, the concept of using Redis is the same.
这篇关于如何在两个 python 程序中共享 OpenCV 图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!