题主想问的是其实是C/C++与Python的交互吧,这块我也研究了挺久的,碰到的情况也比较极端,相信我是比较有发言权的。
首先讲一下我搞c与python交互的理由。我从事的是深度学习领域,常见的问题是将算法部署到嵌入式硬件中去,这些硬件通常自带算法加速单元,比如海思的编解码器和npu,能提高算法运行速度,降低cpu负载,而且这些平台的cpu都比较弱。操作这些专用硬件需要用c语言,然而算法工程师通常使用python,即使他们懂c,硬件适配也不是他们的主要工作。这导致算法工程师对算法的掌控力下降,与硬件团队对接时效率很低。如果硬件接口能以python的形式暴露出来,算法工程师就很容易对部署在硬件上面的算法进行验证测试,同时也减轻硬件工程师的工作量。另外,python以开发效率高著称,业务逻辑能用python就不要用c开发,硬件团队使用python也能很好地提高工作效率。
有了c/python交互的需求,接下来就讲讲其最终达到的效果。c/python交互最简单的形式就是函数的相互调用,这个问题的回答基本都是在讲这个,我就不赘述了。复杂一点的形式是同一个对象不同语言的交互,可以借助一些开源库来实现,比如pybind11,boost。更复杂的也是我最终想达到的目的是array的交互。注意这里的array不是c的array,而是numpy的array。这在数值计算领域尤其重要!
需求和目的都明确了,下面来看看实现的方案!
1、boost。caffe实现c/python交互就是用这个,因此我研究过一段时间,结论是难用,文档少,不推荐。
2、pybind11。优点是简单易用,无依赖,文档齐全。但是有一个致命的缺点让我不得不抛弃他,就是用海思的编译器编译不通过!原因是他使用了c++的exception,海思的编译器太老了,不支持。
3、用opencv当做c/python交互的桥梁。当我在看opencv-python bindings的实现时,心中默默在念”天哪!这就是我想要的”。opencv的优点也是boost和pybind11的缺点:不需要写module文件,假如你有100个类要暴露给python,你就要在cpp文件里面写100个module,而opencv只需要在类名前面加上CV_EXPORTS_W关键字,在方法前面加上CV_WRAP就可以了。很优雅,后期维护也很方便。
numpy array的无缝镶嵌,c代码里的cv::Mat类型,就是python里的numpy array,opencv已经帮你做了Mat和array间的转换,无需再写转换代码,在c里面使用Mat也很方便。
opencv代码兼容性好,通俗易懂,能在多种平台编译通过,包括arm-linux交叉编译。
综上,强势安利opencv的python bindings!
如何将opencv-python bindings应用于自己的项目中呢?可以参照opencv_contrib的方式,将自己的项目作为opencv的extra modules,这样就可以调用CV_EXPORTS_W、CV_WRAP等宏,同时也可以调用opencv的其他modules。当你项目要用到opencv的时候,这种方案是最好不过了。相信现在搞机器视觉的最离不开import numpy和import cv2这两行代码吧,哈哈哈。
最后附上opencv_contrib和opencv-python bindings tutorials的链接,希望对各位看官能有一点点启发。opencv/opencv_contrib?github.comHow OpenCV-Python Bindings Works??docs.opencv.org
更新!我这里写了一个小小的sample,涵盖了深度学习里常用的python/C++交互方式,希望能帮助大家了解opencv python扩展的使用。Zondabb/pybindcpp?github.com