ITPub博客

首页 > > > C++调用Python脚本

C++调用Python脚本

作者:bluetooth 时间:2019-09-20 16:35:37 0 删除 编辑

C++调用Python(一)

1 背景

最近在写一个数码管识别的代码,基于opencv4.1.0框架,在机器学习的背景下,我用过ANN,聚类和SVM支持向量机三种框架,最终发现效果不是特别好,ANN效果最好,在环境变化不大的情况下准确度能到99%以上。但是依然达不到要求,因为这个识别率要求比较高,力求达到99%以上,所以决定用深度学习的框架试试。

深度学习的框架用的tensorflowflow。所以最近在研究深度学习的框架其中之一的tensorflowflow,tensorflow网上主要都是用python写的demo。而且tensorflow在c++环境下部署特别麻烦。我需要用Cmake配置,最开始是准备python生产pb和pbtxt训练集,再用DNN模块加载,在c++中做图像预处理,由于失败了,就不做介绍了;最终我采用的策略是tensorflow的框架用python写,最后用c++加载python脚本。但是这个过程极其曲折和痛苦。

2 TensorFlow库部分介绍

2.1介绍

TensorFlow™是一个基于数据流编程(dataflow programming)的符号数学系统,被广泛应用于各类机器学习(machine learning)算法的编程实现,其前身是谷歌的神经网络算法库DistBelief [1] 。

Tensorflow拥有多层级结构,可部署于各类服务器、PC终端和网页并支持和TPU高性能数值计算,被广泛应用于谷歌内部的产品开发和各领域的科学研究 [1-2] 。

TensorFlow由谷歌人工智能团队(Google Brain)开发和维护,拥有包括TensorFlow Hub、TensorFlow Lite、TensorFlow Research Cloud在内的多个项目以及各类应用程序接口(Application Programming Interface, API) [2] 。自2015年11月9日起,TensorFlow依据阿帕奇授权协议(Apache 2.0 open source license) [2]

2.2背景

谷歌大脑自2011年成立起开展了面向科学研究和谷歌产品开发的大规模应用研究,其早期工作即是TensorFlow的前身DistBelief [1] 。DistBelief的功能是构建各尺度下的神经网络分布式学习和交互系统,也被称为"第一代机器学习系统" [1] 。DistBelief在谷歌和旗下其它公司的产品开发中被改进和广泛使用 [3-4] 。2015年11月,在DistBelief的基础上,谷歌大脑完成了对"第二代机器学习系统"TensorFlow的开发并对代码开源。相比于前作,TensorFlow在性能上有显著改进、构架灵活性和也得到增强 [1] 。此后TensorFlow快速发展,截至稳定API版本1.12,已拥有包含各类开发和研究项目的完整生态系统。在2018年4月的TensorFlow开发者峰会中,有21个TensorFlow有关主题得到展示 [2]

3. C++如何调用python库文件

3.1.环境配置

安装完python后,把python的include和lib拷贝到自己的工程目录下

然后在工程中包括进去

3.2测试实例

先写一个python的测试脚本,如下

这个脚本里面定义了两个函数Hello()和_add()。我的脚本的文件名叫mytest.py

C++代码:
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include "include\Python.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//初始化Python环境
Py_Initialize();
PyRun_SimpleString("import sys");
//添加Insert模块路径
//PyRun_SimpleString(chdir_cmd.c_str());
PyRun_SimpleString("sys.path.append('./')");
//导入模块
PyObject* pModule = PyImport_ImportModule("mytest");
if (!pModule)
{
cout << "Python get module failed." << endl;
return 0;
}
cout << "Python get module succeed." << endl;
PyObject * pFunc = NULL;
pFunc = PyObject_GetAttrString(pModule, "Hello");
PyEval_CallObject(pFunc, NULL);
//获取Insert模块内_add函数
PyObject* pv = PyObject_GetAttrString(pModule, "_add");
if (!pv || !PyCallable_Check(pv))
{
cout << "Can't find funftion (_add)" << endl;
return 0;
}
cout << "Get function (_add) succeed." << endl;
//初始化要传入的参数,args配置成传入两个参数的模式
PyObject* args = PyTuple_New(2);
//将Long型数据转换成Python可接收的类型
PyObject* arg1 = PyLong_FromLong(4);
PyObject* arg2 = PyLong_FromLong(3);
//将arg1配置为arg带入的第一个参数
PyTuple_SetItem(args, 0, arg1);
//将arg1配置为arg带入的第二个参数
PyTuple_SetItem(args, 1, arg2);
//传入参数调用函数,并获取返回值
PyObject* pRet = PyObject_CallObject(pv, args);
if (pRet)
{
//将返回值转换成long型
long result = PyLong_AsLong(pRet);
cout << "result:" << result << endl ;
}
Py_Finalize();
system("pause");
return 0;

3.3后续内容

这种方式只能解决在python基础文件的调用,在需要加入 opencv 和tensorflowflow模块的时候,其中有好几个坑,后续再介绍。



辞话Love

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/3402/viewspace-3129729/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-07-11

  • 博文量
    280
  • 访问量
    20980