python - 如何在两个 python 程序中共享 OpenCV 图像?

标签 python opencv

我有三个 python 文件:glob_var.py、read_cam.py、read_globVar.py。它们的内容如下: 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

从那三只 python 苍蝇,我想你们知道我想做什么。是的,我想要 read_cam.py 从相机读取图像并将其广播到全局变量。然后 read_globVar.py 可以获得图像并显示它。 我在一个终端中运行 read_cam.py,在另一个终端中运行 read_globVar.py。 但是我没有让它正常工作。我想的可能吗?我该如何管理它?多谢!

=====update1:​​python中的Pub和Sub=====
我使用ROS(Robot Operating System)系统有一段时间了。它提供了 pub 和 sub 功能来在不同程序或所谓的节点之间交换变量。 所以我的问题是python中有没有包提供这样的功能?Redis提供了这个,这是最快的还是最好的方法?

最佳答案

您可以使用 Redis 来执行此操作。它是一个非常快速的内存数据结构服务器,可以提供字符串、整数、散列、列表、队列、集合、有序集合、图像等服务。它免费且易于安装在 ma​​cOSLinuxWindows 上。

此外,您还可以使用 bash、Python、PHP、C/C++ 或许多其他语言读取或写入 Redis 值。此外,您可以跨网络或跨世界读取或写入服务器,只需更改初始连接中的 IP 地址。因此,您可以有效地在 Linux 下的 Raspberry Pi 上使用 Python 获取图像,然后在 Windows 下的 PC 上以 C/C++ 存储和处理它们。

然后你只需将你的图像放入 Redis,命名为 Camera1Entrance 或者将它们放在一个排序的哈希中以便你可以缓冲图像按帧数。您还可以为图像(或其他数据结构)指定一个“生存时间”,这样您的 RAM 就不会填满。

以下是为使用 Redis 而粗略重写的代码的主干部分。目前没有内置严重的错误检查或灵 active 。一切运行良好。

这是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.packstruct.unpack 操作。

另请注意,您可以在内存中将图像编码为 JPEG,并将 JPEG 存储在 Redis(而不是 Numpy 数组)中,这可能会节省内存和网络带宽。

无论哪种方式,使用 Redis 的概念都是一样的。

关于python - 如何在两个 python 程序中共享 OpenCV 图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56944497/

相关文章:

python子进程没有终止

python - 使用 Beautifulsoup 抓取多个网站

python - 如何获得 geodjango 的 k 个最近邻居?

java - 在 Android 上录制实时 OpenCV 处理

java - 带有参数和类路径变量的 Jar 文件

Python IRC 机器人在 240 秒后超时

Python:如何窥视 pty 对象以避免阻塞?

c++ - opencv 使用 mask 和修复将一幅图像覆盖在另一幅图像上

java - 为什么 OpenCV 在使用 Mat 时抛出 UnsatisfiedLinkError?

c++ - Gstreamer 的 OpenCV 3.0.0 错误