如何在两个 python 程序中共享 OpenCV 图像? [英] How to share OpenCV images in two python programs?

查看:95
本文介绍了如何在两个 python 程序中共享 OpenCV 图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有三个 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 来做到这一点.它是一个非常快的内存数据结构服务器,可以提供字符串、整数、散列、列表、队列、集合、有序集合、图像.它可以免费且简单地安装在 ma​​cOSLinuxWindows 上.

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,命名为 Camera1Entrance 或将它们放入已排序的哈希中,以便您可以缓冲图像按帧数.您还可以给图像(或其他数据结构)一个 生存时间",这样您的 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.packstruct.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆