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

时间:2017-10-07 11:16:21

标签: python c++ linux opencv

有没有办法在C / C ++和python之间共享内存以共享openCV图像(C +++中的MAT和python中的numpy)图像?不需要多平台,我在linux中这样做,我认为在mmap或类似的想法之间分享。

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

我将通过socket调用c进程到python,但我需要发送和映像并通过内存。

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

2 个答案:

答案 0 :(得分:1)

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

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

不要担心速度,管道非常快。本地和Unix套接字也是如此。获取字符串表示并将其转回矩阵时,大部分时间都将丢失。

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

答案 1 :(得分:0)

这并不完全是您所要求的,但是您可以使用诸如 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_redishttps://github.com/cpp-redis/cpp_redis