C/C++调用Python [OpenCV与Numpy]

本文介绍了如何在C/C++环境中调用Python,特别是在使用OpenCV和Numpy的情况下。首先,文章详细阐述了环境配置,包括OpenCV、Python和Numpy的设置。接着,讲解了C/C++与Python之间的类型转换,包括基本类型和复杂对象的转换。然后,展示了C调用Python的实例,特别讨论了引用计数和opencv与numpy类型转换的问题。最后,提到了如何编写Python扩展来加速代码执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C/C++调用Python [opencv与numpy]

目前的情况下,如果你有一个深度学习模型,很想在项目中使用,但模型是用python写的,项目使用的是C++,怎么办?直观的做法是从C++调用python解释器,本文遇到的情景是C++环境下有张图片,需要将其中一个区域(ROI)进行放大(超分辨率重建),放大算法是python环境下的函数(pytorch模型),之后在C++环境下进行后续处理,假设希望从C/C++端调用的python函数如下(暂不介绍超分辨率,用opencv的resize替代):

import cv2 as cv
def super_resolution(img, scale=4):
    height, width = img.shape[:2]
    dsize = (width*scale, height*scale)
    big_img = cv.resize(img, dsize)
    return big_img

先介绍环境配置,再讲从C/C++调用Python的关键操作。

1. 环境设置

以windows环境为例,开发时需要做好相关配置,我的环境:Windows10,VS2017 Community,Python3.6.4_x64,OpenCV3.4.1_x64。

OpenCV环境

官方文档

  1. Visual Studio配置包含目录(编译错),D:\Program Files\opencv3\build\include
  2. Visual Studio配置库目录(链接错),D:\Program Files\opencv3\build\x64\vc15\lib
  3. Visual Studio配置链接器输入(链接错):opencv_world341.lib
  4. 追加Path环境变量(运行错):Path=Path;D:\Program Files\opencv3\build\x64\vc15\bin,改完环境变量一定要重启Visual Studio才能生效。

下面的例子读取一张图片并显示。

//opencv_demo.cpp
#include<opencv/cv.hpp>
using namespace cv;

int main(int argc, char *argv[]){
   
    Mat img = imread("lena.jpg");
    imshow("lena", img);
    waitKey(0);
    destroyAllWindows();
    return 0;
}

Python环境

官方文档——Python和C相互调用

  1. Visual Studio配置包含目录(编译错):D:\Program Files\Python36\include
  2. Visual Studio配置库目录(链接错):D:\Program Files\Python36\libs
  3. 新增环境变量(运行错):PYTHONHOME=D:\Program Files\Python36,改完环境变量一定要重启Visual Studio才能生效。

下面的例子从C调用Python解释器,并执行Python代码,打印时间和日期。

//python_demo.cpp
// https://docs.python.org/3.6/extending/embedding.html#very-high-level-embedding
#include <Python.h> 

int main(int argc, char *argv[])
{
   
    wchar_t *program = Py_DecodeLocale(argv[0], NULL);
    if (program == NULL) {
   
        fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
        exit(1);
    }
    Py_SetProgramName(program);  /* optional but recommended */
    Py_Initialize();
    PyRun_SimpleString("from time import time,ctime\n"
                       "print('Today is', ctime(time()))\n");
    if (Py_FinalizeEx() < 0) {
   
        exit(120);
    }
    PyMem_RawFree(program);
    getchar();
    return 0;
}

Numpy环境

官方文档——如何利用Numpy的C API

numpy更多C API

  1. Visual Studio头文件目录(编译错):D:\Program Files\Python36\Lib\site-packages\numpy\core\include
  2. 关键代码(运行错):在Py_Initialize();之后必须调用import_array();以加载所有numpy函数(C API),与加载dll类似。

下面的例子展示用numpy接口实现矩阵计算矩阵乘法,并验证结果。

// numpy_demo.cpp 
#include <Python.h> 
#include <iostream>
#include <numpy/arrayobject.h>
using namespace std;

int main(int argc, char *argv[])
{
   
    wchar_t *program = Py_DecodeLocale(argv[0], NULL);
    if (program == NULL) {
   
        fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
        exit(1);
    }
    Py_SetProgramName(program);  /* optional but recommended */
    Py_Initialize();
    
    import_array();		/* load numpy api */
    double array_1[2][3] = {
    {
    2,5,6 },{
    5,6,5 } };
    npy_intp dims_1[] = {
    2, 3 };
    PyObject *mat_1 = PyArray_SimpleNewFromData(2, dims_1, NPY_DOUBLE, array_1);

    double array_2[3][4] = {
    {
    1,
### 配置 VSCode 使用 C/C++OpenCV 为了使 Visual Studio Code 支持 C/C++ 并能够调用 OpenCV 库,在 Ubuntu 上需完成几个必要的设置。 #### 安装依赖项 安装 GCC 编译器以及 GDB 调试工具,这些可以通过包管理器 apt-get 来实现。另外还需要安装 cmake 工具来构建项目[^2]。 ```bash sudo apt update && sudo apt upgrade -y sudo apt install build-essential gdb cmake pkg-config libgtk-3-dev \ libavcodec-dev libavformat-dev libswscale-dev python3-dev \ python3-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev \ libtiff-dev libdc1394-22-dev git ``` #### 下载并编译 OpenCV 获取最新版本的 OpenCV 源码,并通过 cmake 构建它。这一步骤会创建所需的共享库文件以便后续链接到自己的程序里。 ```bash git clone https://github.com/opencv/opencv.git opencv cd opencv/ mkdir build && cd build cmake .. make -j$(nproc) sudo make install ``` #### 设置 VSCode 的工作区 打开目标文件夹作为新的工作空间,接着添加 `.vscode` 文件夹用来保存特定于项目的配置文件如 `c_cpp_properties.json`, `tasks.json` 及 `launch.json`. ##### c_cpp_properties.json 此 JSON 文件定义 IntelliSense 对头文件路径的理解方式: ```json { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/usr/local/include/", "/usr/local/include/opencv4" ], "defines": [], "compilerPath": "/usr/bin/gcc", "cStandard": "gnu17", "cppStandard": "gnu++17", "intelliSenseMode": "gcc-x64" } ], "version": 4 } ``` ##### tasks.json 该任务描述符告诉编辑器如何执行预处理器命令行参数以启动实际编译过程: ```json { "version": "2.0.0", "tasks": [ { "label": "build hello world", "type": "shell", "command": "g++", "args": [ "-fdiagnostics-color=always", "-g", "./main.cpp", "`pkg-config --libs --cflags opencv4`", // 获取 opencv 参数 "-o", "${fileDirname}/hello_world" ], "group": { "kind": "build", "isDefault": true }, "problemMatcher": ["$gcc"], "detail": "Generated task from snippet." } ] } ``` ##### launch.json 最后这部分指定了运行时环境变量和可执行文件的位置,允许直接从 IDE 启动应用程序进行测试或调试操作. ```json { "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/hello_world", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ], "preLaunchTask": "build hello world", "miDebuggerPath": "/usr/bin/gdb", "logging": {"trace":true,"traceResponse":true}, "internalConsoleOptions": "openOnSessionStart" } ] } ``` 以上就是完整的配置流程,确保每一步都严格按照说明执行可以有效减少错误的发生概率。如果遇到任何问题,请查阅官方文档或者社区论坛寻求帮助。
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值