有没有办法在C / C ++和python之间共享内存以共享openCV图像(C +++中的MAT和python中的numpy)图像?不需要多平台,我在linux中这样做,我认为在mmap或类似的想法之间分享。
我有两个正在运行的进程,一个是用C编写的,另一个是python,我需要在它们之间共享一个映像。
我将通过socket调用c进程到python,但我需要发送和映像并通过内存。
另一种选择可能是写入内存文件,不确定它是否会耗费更多时间。
答案 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_redis
:https://github.com/cpp-redis/cpp_redis。