DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  4737 随笔 :: 2 文章 :: 542 评论 :: 1615万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

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)
 
posted on   DoubleLi  阅读(787)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源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中动态添加控件
点击右上角即可分享
微信分享提示