如何将 opencv Mat 类型传递给 Python 并返回一个数组?

Posted

技术标签:

【中文标题】如何将 opencv Mat 类型传递给 Python 并返回一个数组?【英文标题】:How to pass opencv Mat type to Python and get an array back? 【发布时间】:2019-03-05 11:41:17 【问题描述】:

我有一个深度学习 python 代码,它获取图像并返回该图像中的检测位置数组。

我已经用 C++ 开发了我项目的所有其他部分,我想将一个 opencv Mat 图像 (cv::Mat) 传递给 python 脚本,它会将一个数组返回给 C++。

有没有办法在 C++/Python 之间传递这些数据类型?我应该使用什么功能?

【问题讨论】:

如果不是性能关键,最简单的方法就是将其存储在一个文件中并再次读取它 @user463035818 性能正是我的问题。 this 是您要找的吗?只需将指向数据的指针传递给您的 python 脚本并将其解压缩为结构。然后再次打包以将其传递回您的 C++ 应用程序。或者使用 Cython 将你的 python 脚本编译成 C 并尝试将其集成到你的代码中。如果性能真的很关键,另一种方法是完全在 C++ 或 Python 中完成,而不是混合使用。 Tensorflow 有一个 C++ API。 “有没有办法在 C++/Python 之间传递这些数据类型?” -- 当然,看看 OpenCV Python 绑定是如何工作的。 SO上有多个关于如何处理Matndarray 的映射的帖子。还有 Boost.Numpy。 【参考方案1】:

所以这可以通过两种方式实现。

1.) 你可以为python开发一个后端服务器,然后公开那些api,然后你可以使用你的api发送数据并返回结果。

2.) 你也可以让你的python函数被c++程序调用,因为你可以使用像Python.h这样的lib来调用和接收来自python脚本的数据。

例如,假设您有一个名为aiDosomething.py 的python 文件,它有一个函数detect 来执行检测任务。 然后在 c++ 中你可以做类似的事情

#include <Python.h>

int main()


pModule = PyImport_ImportModule("aiDosomething");

//chose the function in file Sample

pFunc = PyObject_GetAttrString(pModule,"detect");

pDict = PyModule_GetDict(pModule);   // Create a dictionary for the contents of the module.

//make the args to be passes in the function

pArgs = PyTuple_New(1);     // Create a Python tuple to hold the arguments to the method.
PyTuple_SetItem(pArgs, 0, insertArray); // insertArray can be your cv::mat array

//run the code and get the result
PyObject* pResult = PyObject_CallObject(pFunc, pArgs);
return 0;


为了简单起见,您可以将 python 代码和 c++ 放在同一目录下。

【讨论】:

这是我想使用 cv::Mat 作为 insertArray 时返回的错误:"没有合适的从 "cv::Mat" 到 "PyObject *" 的转换存在" 尝试将 cv::mat 数组转换为普通数组并发送 这怎么可能?只需键入casting? 您可以将图像视为二维数组,首先初始化形状等于 cv::Mat 的二维数组,然后您可以简单地遍历 cv::mat 中的每个值,然后将值设置为普通的 c++ 数组。此外,如果您在 c++ 中做的不多,您可以直接将您的 imagePath 传递给 python 并在函数本身中加载图像。 我通过PyTuple_SetItem(pArgs, 0, (PyObject*)(char*)img.data); 没有错误地做到了,但python脚本中没有显示任何内容。甚至print(img.shape()) 什么都不做!

以上是关于如何将 opencv Mat 类型传递给 Python 并返回一个数组?的主要内容,如果未能解决你的问题,请参考以下文章

简单的opencv问题,如何把一个vector中的值传递给mat?

OpenCV大型阵列类型Mat类

将 opencv Mat 传递给函数时,对非常量的引用的初始值必须是左值

OpenCV 3:如何将 cv::Mat 作为可选参数传递

如何将 cv::mat 对象从 python 模块传递给 c++ 函数并返回返回的 cv::mat 类型的对象?

SCNProgram - 如何将“mat4”类型的制服传递给自定义着色器?