如何将 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上有多个关于如何处理Mat
到ndarray
的映射的帖子。还有 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 传递给函数时,对非常量的引用的初始值必须是左值