开发者社区 问答 正文

使用共享内存共享从python到cpp的一个帧(numpy - opencv python)

我写了一个帧发送程序,从basler相机读取帧并对这些帧进行预处理。我想用“在cpp中处理这些帧的代码编写”来共享这些活动帧。cpp代码使用共享内存的特定名称从那里获取输入帧。我只想输入cpp代码,即python代码(帧)的输出。 我该怎么办? python版本= 3.7 谢谢 问题来源StackOverflow 地址:/questions/59386697/share-a-frame-numpy-opencv-python-from-python-to-cpp-with-shared-memory

展开
收起
kun坤 2019-12-25 21:53:37 835 分享 版权
阿里云 AI 助理回答

要在Python和C++之间共享数据,特别是像OpenCV处理的图像帧这样的大型数据结构,使用共享内存是一种高效的方法。这里是一个简化的步骤指南,帮助你实现从Python(使用OpenCV处理图像)到C++的数据传输:

1. 安装必要的库

确保你的环境中安装了numpy, cv2(OpenCV for Python),以及用于创建和管理共享内存的库,如multiprocessing(Python内置)。

2. Python端:创建共享内存并写入数据

在Python中,你可以使用multiprocessing模块来创建共享内存,并将Numpy数组或OpenCV图像数据复制到其中。以下是一个示例代码片段:

import cv2
import numpy as np
from multiprocessing import shared_memory
from ctypes import c_uint8

# 假设这是你从Basler相机读取并预处理后的图像
frame = cv2.imread('your_image.jpg') # 或者用cv2.VideoCapture()获取实时帧

# 将Numpy数组转换为一维字节视图,以便在共享内存中存储
frame_flattened = frame.flatten()
buf = frame_flattened.tobytes()

# 创建共享内存块
shm = shared_memory.SharedMemory(create=True, size=len(buf), name='image_frame')

# 将图像数据复制到共享内存
shm.buf[:len(buf)] = buf

# 记录一些元数据,例如形状,供C++端使用
shape_metadata = {'shape': frame.shape, 'dtype': str(frame.dtype)}
with open('shape_metadata.json', 'w') as f:
    json.dump(shape_metadata, f)

3. C++端:读取共享内存中的数据

在C++端,你需要访问共享内存并根据之前保存的元数据重构图像。这通常涉及直接操作内存和理解Numpy数组的布局。下面是一个基本的C++代码框架,假设你已经知道图像的维度和数据类型:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdint>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    // 读取元数据
    std::ifstream metadata_file("shape_metadata.json");
    std::string metadata_str((std::istreambuf_iterator<char>(metadata_file)), 
                             std::istreambuf_iterator<char>());
    nlohmann::json shape_metadata = nlohmann::json::parse(metadata_str);

    // 获取共享内存信息
    int shm_fd = shm_open("image_frame", O_RDONLY, 0666);
    if (shm_fd == -1) {
        perror("shm_open");
        return 1;
    }

    struct stat sb;
    if (fstat(shm_fd, &sb) == -1) {
        perror("fstat");
        return 1;
    }

    void* mem = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, shm_fd, 0);
    if (mem == MAP_FAILED) {
        perror("mmap");
        return 1;
    }

    // 根据元数据重构图像
    auto shape = shape_metadata["shape"].get<std::vector<int>>();
    auto dtype = shape_metadata["dtype"];
    int channels = shape[2]; // 对于BGR图像,通道数为3
    int height = shape[0];
    int width = shape[1];

    cv::Mat img(height, width, CV_MAKETYPE(CV_8U, channels));
    uint8_t* data = static_cast<uint8_t*>(mem);
    memcpy(img.data, data, sb.st_size);

    // 现在img是你的图像,可以进行进一步处理
    cv::imshow("Image from Shared Memory", img);
    cv::waitKey(0);

    munmap(mem, sb.st_size);
    close(shm_fd);

    return 0;
}

注意: - 上述C++代码使用了nlohmann/json库来解析JSON元数据文件,确保你已经安装了这个库。 - 请根据实际情况调整路径、权限等细节。 - 这个例子假设你知道图像的通道顺序(如BGR)。如果需要,根据实际图像格式调整CV_MAKETYPE的参数。

通过以上步骤,你应该能够实现在Python中处理图像后,通过共享内存传递给C++程序继续处理的功能。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答