【问题标题】:Python API to C++ - return pointer to object instead of full objectPython API to C++ - 返回指向对象而不是完整对象的指针
【发布时间】:2021-08-01 02:17:36
【问题描述】:

我创建了一个 python 模块来调用我的库的一些 c++ 函数。 它使用opencv来操作一些矩阵。

我的python代码

image = "zebre_1080p.png"
intput_image = cv2.resize(image, (int(cols - cols % ratio), int(rows - rows % ratio)))

output_image = image

cv2.imshow('input',intput_image)
cv2.waitKey(0)

test = py_module.testProcess(input_image, output_image) //increase the resolution of the input image

cv2.imshow('output',output_image)  // same as image
cv2.waitKey(0)


cv2.imshow('output',test) // input_image with new resolution
cv2.waitKey(0)

我的 C++ 代码

static PyObject* testProcess(PyObject* self, PyObject* args) {

PyArrayObject *input, *output;
if ( ! PyArg_ParseTuple(args, "OO", &input, &output) ) return NULL; 

cv::Mat in = cv::Mat(cv::Size(in_dims[0], in_dims[1]), CV_8UC3, PyArray_DATA(input));
cv::Mat out = cv::Mat(cv::Size(out_dims[0], out_dims[1]), CV_8UC3);

in ret = Process(in, out);
    if(ret < 0){
        printf("Erreur Process : %x\n", ret);
        return NULL;
    }

npy_intp dimens[] = {out.rows, out.cols};
PyObject* obj = PyArray_SimpleNewFromData(out.dims, dimens, NPY_UINT8, out.data);

return obj;

所以这个解决方案有效,但我想返回与我的 C++ 函数相同的值,并且像 c++ 函数一样返回 output_image 对象中的输出矩阵。 像这样:

ret = py_module.testModule(input_image, output_image) //increase the resolution of the input image

cv2.imshow('output',output_image)  // intput_image with new resolution
cv2.waitKey(0)

我不知道这是否可能,也许是:

Py_BuildValue("O", obj);

还是别的什么?

谢谢。

【问题讨论】:

  • 既然您使用的是 C++,您是否考虑过一些更高级别的与 Python 交互的方式?使用 pybind11 这应该很容易,我在 answer 中展示了如何从 C++ 转到 Python。 |否则,请查看 OpenCV 的 this part(绑定生成器的支持代码),并了解他们如何使用低级 API 将 Mats 编组为 numpy 数组。

标签: python c++ api opencv


【解决方案1】:

我成功地做到了:

static PyObject* testProcess(PyObject* self, PyObject* args) {

    _import_array();
    PyArrayObject *input, *output;
    if ( ! PyArg_ParseTuple(args, "OO", &input, &output) ) return NULL;
     
    npy_intp* in_shape = PyArray_SHAPE(input);
    npy_intp* out_shape = PyArray_SHAPE(output);

    cv::Mat in =    cv::Mat(in_shape[0], in_shape[1], CV_8UC3, PyArray_DATA(input));
    cv::Mat out =   cv::Mat(out_shape[0], out_shape[1], CV_8UC3, PyArray_DATA(output));

    int ret = Process(in, out);
    if(ret < 0){
        printf("Erreur Process : %x\n", ret);
        return NULL;
    }

    PyArrayObject *obj = (PyArrayObject *)PyArray_SimpleNewFromData(out.channels(), out_shape, PyArray_TYPE(output), out.data);
    
    PyArray_MoveInto(output, obj);
    
    return PyLong_FromLong( 0 );
}

我的python脚本:

def main():
    ratio = 2

    image = "zebre.png"

    #Read image
    orgHRImage = cv2.imread(image)
    
    cols, rows, dim = orgHRImage.shape
    #crop to %2
    orgHRImage = cv2.resize(orgHRImage, (int(cols - cols % ratio), int(rows - rows % ratio)))

    #downscale image
    downSize = (int(cols/ratio), int(rows/ratio))
    downScaledImage = cv2.resize(orgHRImage, downSize)

    #create empty output image 
    output = np.zeros(orgHRImage.shape, orgHRImage.dtype)

    #cv2.imshow('downScaledImage',downScaledImage)
    #cv2.waitKey(0)

    #cv2.imshow('output',output)
    #cv2.waitKey(0)

    py_module.testProcess(downScaledImage, output)

    #cv2.imshow('output',output)
    #cv2.waitKey(0)

所以我创建了一个输入矩阵 (cv::Mat in) 与 &input (这是一个图像) 的信息和一个输出矩阵 (cv::Mat out) 与 &output 的信息 (在零初始化我的python脚本。 我调用 Process 函数来填充我的输出矩阵。

我创建了一个新的 PyArrayObject,它具有与 &output 相同的属性,并且输出矩阵的新数据。

我将指向新对象的指针移动到我的旧输出指针以获取新对象。

我能够看到图片调整大小除以 2,然后是黑色图像,最后是输出调整大小的图像。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    • 1970-01-01
    • 2020-05-15
    相关资源
    最近更新 更多