最近在做基于OpenCV的车牌识别, 其中需要用到深度学习的一些代码(Python), 所以一开始的时候开发语言选择了Python(祸患之源).
固然现在Python的速度不算太慢, 但你一定要用Python来操作图像, 实现某些算法的时候, 效率就变得非常重要. 可惜的是, Python在大多数算法实现中, 由于其循环操作实在是太慢, 导致实现的算法效率非常之低.
所以现在我要把深度学习中的一个类(分类器)转换到C++中, 在这个过程之前, 需要做一些test projects, 我主要参照的文章是: C++调用Python(3).
开发环境为 VS2012, WIN7 64.
所有代码都在最后放出, 这里先逐步讲解.
首先我们需要导入合适的头文件: Python.h, 它位于你的Python安装目录的include目录下. (2.6, 2.7版本实测通过)
使用VS的话, 可以按如下方法设置一下项目属性:
- 调试 -> xxx属性(最后一栏) -> VC++目录 -> 右侧库目录
- 增加C:\Python27\libs, 具体路径个人可能不同.
这样就完成了最基本的配置, 下面我们开始导入.py文件并使用它.
我们使用的.py文件非常简单, 代码如下:
1 #!/usr/bin/python 2 # Filename: testpy.py 3 class Person: 4 def sayHi(self): 5 print ‘hi‘ 6 class Second: 7 def invoke(self,obj): 8 obj.sayHi() 9 def sayhi(name): 10 print ‘hi‘,name;
注: 下述所有导入方法在导入失败时不会报错, 只会返回空指针.
第一步是导入.py文件:
- 使用PyObject* pModule来存储导入的.py文件模块, 调用的方法是PyImport_ImportModule(path): PyObject* pModule = PyImport_ImportModule("testpy");
- 使用PyObject* pDict来存储导入模块中的方法字典, 调用的方法是PyModule_GetDict(module): PyObject* pDict = PyModule_GetDict(pModule);
这样就完成了.py文件的导入.
第二步是导入已导入模块中的方法或类:
- 获取方法, 调用的方法是PyDict_GetItemString(dict, methodName): PyObject* pFunHi = PyDict_GetItemString(pDict, "sayhi");
- 获取类, 调用的方法同上, 注意红体部分的字符串对应于.py文件中的类/方法名: PyObject* pClassSecond = PyDict_GetItemString(pDict, "Second");
第三步是使用导入的方法或类:
- 使用方法, 调用PyObject_CallFunction(pFunc, "s", args)即可: PyObject_CallFunction(pFunHi, "s", "lhb");
- 使用类构造对象, 调用PyInstance_New(pClass, NULL, NULL)即可: PyObject* pInstanceSecond = PyInstance_New(pClassSecond, NULL, NULL); , 注意其中的pClassSecond为第二步.2中获取的类指针
- 使用类对象的方法, 调用PyObject_CallMethod(pInstance, methodname, "O", args)即可: PyObject_CallMethod(pInstanceSecond, "invoke", "O", pInstancePerson);
最后不要忘记销毁这些对象: Py_DECREF(pointer);
下面是C++的实现代码, 代码来自于我参考的博客, 略有修改.
1 /* 2 * test.cpp 3 * Created on: 2010-8-12 4 * Author: lihaibo 5 */ 6 #include <C:/Python27/include/Python.h> 7 #include <iostream> 8 #include <string> 9 10 int main(void) { 11 Py_Initialize(); // 启动虚拟机 12 if (!Py_IsInitialized()) 13 return -1; 14 // 导入模块 15 PyObject* pModule = PyImport_ImportModule("testpy"); 16 if (!pModule) { 17 printf("Cant open python file!/n"); 18 return -1; 19 } 20 // 模块的字典列表 21 PyObject* pDict = PyModule_GetDict(pModule); 22 if (!pDict) { 23 printf("Cant find dictionary./n"); 24 return -1; 25 } 26 // 演示函数调用 27 PyObject* pFunHi = PyDict_GetItemString(pDict, "sayhi"); 28 PyObject_CallFunction(pFunHi, "s", "lhb"); 29 Py_DECREF(pFunHi); 30 // 演示构造一个Python对象,并调用Class的方法 31 // 获取Second类 32 PyObject* pClassSecond = PyDict_GetItemString(pDict, "Second"); 33 if (!pClassSecond) { 34 printf("Cant find second class./n"); 35 return -1; 36 } 37 //获取Person类 38 PyObject* pClassPerson = PyDict_GetItemString(pDict, "Person"); 39 if (!pClassPerson) { 40 printf("Cant find person class./n"); 41 return -1; 42 } 43 //构造Second的实例 44 PyObject* pInstanceSecond = PyInstance_New(pClassSecond, NULL, NULL); 45 if (!pInstanceSecond) { 46 printf("Cant create second instance./n"); 47 return -1; 48 } 49 //构造Person的实例 50 PyObject* pInstancePerson = PyInstance_New(pClassPerson, NULL, NULL); 51 if (!pInstancePerson) { 52 printf("Cant find person instance./n"); 53 return -1; 54 } 55 //把person实例传入second的invoke方法 56 PyObject_CallMethod(pInstanceSecond, "invoke", "O", pInstancePerson); 57 //释放 58 Py_DECREF(pInstanceSecond); 59 Py_DECREF(pInstancePerson); 60 Py_DECREF(pClassSecond); 61 Py_DECREF(pClassPerson); 62 Py_DECREF(pModule); 63 Py_Finalize(); // 关闭虚拟机 64 return 0; 65 }
时间: 2024-10-04 13:22:11