C++ 调用 Python 脚本,并把 cv::Mat 类型传参到 Python 端
前言
查看了很多参考,最后找到一个完整的示例并且跑通,在开始这个任务之前,首先应该确保你的环境是没有问题的,比如:
- C++ 和 Python 之间可以传递简单类型的参数
- C++ 端独立通过 opencv 加载图像是没有问题的
- Python 端 import cv2 独立加载图像是没有问题的
具备上面这些条件后,可以参考下面的代码,将 cv::Mat 类型的参数传递到 Python 端。
代码
这部分主要参考 sending Mat。
C++ 端需要借助 numpy,所以也需要配置好 numpy 的头文件位置。
C++ code
#include "Python.h"
#include "numpy/arrayobject.h"
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
// for the references to all the functions
PyObject *m_PyDict, *m_PyFooBar;
// for the reference to the Pyhton module
PyObject* m_PyModule;
int main() {
Py_Initialize();
// PySys_SetArgv(argc, (wchar_t**)argv);
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyRun_SimpleString("sys.path.append('/home/tt/test')");
PyObject *sys_path = PySys_GetObject("path");
PyList_Append(sys_path, PyUnicode_FromString("."));
// this macro is defined be NumPy and must be included
import_array1(-1);
m_PyModule = PyImport_ImportModule("cal");
if (m_PyModule != NULL)
{
// get dictionary of available items in the module
m_PyDict = PyModule_GetDict(m_PyModule);
// grab the functions we are interested in
m_PyFooBar = PyDict_GetItemString(m_PyDict, "foo_bar");
// execute the function
if (m_PyFooBar != NULL)
{
// take a cv::Mat object from somewhere (we'll just create one)
// cv::Mat img = cv::Mat::zeros(480, 640, CV_8UC3);
cv::Mat img = cv::imread("/home/tt/test/1.png");
int r = img.rows;
int c = img.cols;
int chnl = img.channels();
// total number of elements (here it's an RGB image of size 640x480)
int nElem = r * c * chnl;
// create an array of apropriate datatype
uchar* m = new uchar[nElem];
// copy the data from the cv::Mat object into the array
std::memcpy(m, img.data, nElem * sizeof(uchar));
// the dimensions of the matrix
npy_intp mdim[] = { r, c, chnl};
// convert the cv::Mat to numpy.array
PyObject* mat = PyArray_SimpleNewFromData(chnl, mdim, NPY_UINT8, (void*) m);
// create a Python-tuple of arguments for the function call
// "()" means "tuple". "O" means "object"
PyObject* args = Py_BuildValue("(O)", mat);
// execute the function
PyObject* result = PyEval_CallObject(m_PyFooBar, args);
// process the result
// ...
// decrement the object references
Py_XDECREF(mat);
Py_XDECREF(result);
Py_XDECREF(args);
delete[] m;
}
}
else
{
std::cerr << "Failed to load the Python module!" << std::endl;
PyErr_Print();
}
return 0;
}
Python code
def foo_bar(img=None):
if img is not None:
cv2.imshow("image in python", img)
cv2.imwrite("/home/tt/test/111.png", img)
cv2.waitKey(0)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2022-08-22 Windows10/11 三步安装wsl2 Ubuntu20.04(任意盘)
2022-08-22 win10离线安装WSL2 Ubuntu20.04系统
2016-08-22 insmod module_param 模块参数
2013-08-22 C++的四种cast操作符的区别--类型转换
2013-08-22 __stdcall,__cdecl,_cdecl,_stdcall,。__fastcall,_fastcall 区别简介
2013-08-22 cdecl、pascal、stdcall、fastcall
2012-08-22 VC中动态添加控件