在C/C++和Python之间共享内存

Share memory between C/C++ and Python

本文关键字:之间 共享 内存 Python C++      更新时间:2023-10-16

有没有一种方法可以共享内存,以便在C/C++和python之间共享openCV映像(C++中的MAT和python中的numpy)映像?不需要多平台,我在linux中做,我认为mmap之间的共享或类似的想法。

我有两个正在运行的进程,一个是用C编写的,另一个是python,我需要在它们之间共享一个映像。

我将通过套接字从c进程调用python,但我需要通过内存发送和镜像。

另一种选择可能是在内存中写入文件,不确定它是否会更耗时。

好吧,这并不是真正意义上的内存共享。您想要的是IPC将图像数据从一个进程发送到另一个进程。

我建议您使用Unix命名管道。您必须获得C/C++中字符串格式的原始数据,通过管道或Unix套接字将其发送到Python,然后从发送的数据中获得numpy数组。也许使用np.fromstring()函数。

不用担心速度,管道很快。本地和Unix套接字。获取字符串表示并将其转换回矩阵将浪费大部分时间。

有一种可能性是,你可以创建真正的共享内存空间,并将C/C++中的OpenCV中的数据直接获取到Python中,然后在Python中使用OpenCV来获取numpy数组,但这会很复杂。如果你不需要光速,你最好的选择就是命名管道。

这并不是您想要的,但您可以使用内存中的数据库(如Redis)作为在程序之间交换OpenCV映像的管道。虽然不如原始内存映射直接,而且它引入了一个额外的应用层,但数据仍然在RAM中严格操作。根据我的经验,这种策略足够快,在现代机器上几乎是实时的。

我用这样的架构https://github.com/vmlaker/hello-websocket,尽管它在两端都使用Python。

下面是一个类似协议的极简主义示例,该协议在C++中实现源代码,在目标应用程序中实现Python。以下C++程序使用OpenCV从磁盘上的文件中读取图像,并将图像存储在Redis中的密钥image:下

#include <opencv4/opencv2/opencv.hpp>
#include <cpp_redis/cpp_redis>
int main(int argc, char** argv)
{
cv::Mat image = cv::imread("input.jpg");
std::vector<uchar> buf;
cv::imencode(".jpg", image, buf);
cpp_redis::client client;
client.connect();
client.set("image", {buf.begin(), buf.end()});
client.sync_commit();
}

然后在Python中,您可以从数据库中获取图像并执行您想要的操作:

import cv2
import numpy as np
import redis
store = redis.Redis()
image = store.get('image')
array = np.frombuffer(image, np.uint8)
decoded = cv2.imdecode(array, flags=1)
cv2.imshow('hello', decoded)
cv2.waitKey()

走另一条路很简单。您可以在此处获取cpp_redis:https://github.com/cpp-redis/cpp_redis.