如何通过共享内存将cv :: Mat发送给python?

问题描述 投票:1回答:1

我有一个C ++应用程序,可通过共享内存将数据发送到python函数。这在Python中使用ctypes(例如double和float)非常有用。现在,我需要在函数中添加cv::Mat

我的当前代码是:

// h

#include <iostream>
#include <opencv2\core.hpp>
#include <opencv2\highgui.hpp>


struct TransferData
{
   double score;
   float other;  
   int num;
   int w;
   int h;
   int channels;
   uchar* data;

};

#define C_OFF 1000
void fill(TransferData* data, int run, uchar* frame, int w, int h, int channels)
{
   data->score = C_OFF + 1.0;
   data->other = C_OFF + 2.0;
   data->num = C_OFF + 3;   
   data->w = w;
   data->h = h;
   data->channels = channels;
   data->data = frame;
}

//。cpp

namespace py = pybind11;

using namespace boost::interprocess;

void main()
{

    //python setup
    Py_SetProgramName(L"PYTHON");
    py::scoped_interpreter guard{};
    py::module py_test = py::module::import("Transfer_py");


    // Create Data
    windows_shared_memory shmem(create_only, "TransferDataSHMEM",
        read_write, sizeof(TransferData));

    mapped_region region(shmem, read_write);
    std::memset(region.get_address(), 0, sizeof(TransferData));

    TransferData* data = reinterpret_cast<TransferData*>(region.get_address());


    //loop
    for (int i = 0; i < 10; i++)
    {
        int64 t0 = cv::getTickCount();

        std::cout << "C++ Program - Filling Data" << std::endl;

        cv::Mat frame = cv::imread("input.jpg");

        fill(data, i, frame.data, frame.cols, frame.rows, frame.channels());

        //run the python function   

        //process
        py::object result = py_test.attr("datathrough")();


        int64 t1 = cv::getTickCount();
        double secs = (t1 - t0) / cv::getTickFrequency();

        std::cout << "took " << secs * 1000 << " ms" << std::endl;
    }

    std::cin.get();
}

// Python//传输数据类

import ctypes


    class TransferData(ctypes.Structure):
_fields_ = [
    ('score', ctypes.c_double),
    ('other', ctypes.c_float),       
    ('num', ctypes.c_int),
    ('w', ctypes.c_int),
    ('h', ctypes.c_int),
    ('frame', ctypes.c_void_p),
    ('channels', ctypes.c_int)  
]


    PY_OFF = 2000

    def fill(data):
        data.score = PY_OFF + 1.0
        data.other = PY_OFF + 2.0
        data.num = PY_OFF + 3

//主要Python函数

import TransferData
import sys
import mmap
import ctypes




def datathrough():
    shmem = mmap.mmap(-1, ctypes.sizeof(TransferData.TransferData), "TransferDataSHMEM")
    data = TransferData.TransferData.from_buffer(shmem)
    print('Python Program - Getting Data')   
    print('Python Program - Filling Data')
    TransferData.fill(data)

如何将cv::Mat框架数据添加到Python端?我将其作为来自C ++的uchar*发送,据我了解,我需要将其作为numpy数组才能在Python中获得cv2.Mat。从“宽度,高度,通道,frameData”到opencv python cv2.Mat的正确方法是什么?

我使用共享内存是因为速度是一个因素,我已经使用Python API方法进行了测试,但是对于我的需求而言,它太慢了。

python c++ opencv shared-memory
1个回答
2
投票

一般的想法(在OpenCV Python绑定中使用)是创建一个与ndarray对象共享其数据缓冲区的numpy Mat,并将其传递给Python函数。

© www.soinside.com 2019 - 2024. All rights reserved.