目的: 由于python遍历图像像素的方式问题,处理相同图像比C语言要慢很多,不能实现实时的处理图像,所以需要将遍历图像的部分代码改写成c++代码,因为c++中遍历数组的方式是通过地址直接访问,所以速度很快;然后编译成库函数,通过Python调用库函数实现python和c++混合编写,加速代码的处理速度。
实现方式: ctypes, pybind11, cython,等等,目前有很多种连接Python和c++的工具型项目;其中的cython和pybind11较为流行,而他们各有优缺点,参见:不同的python-c++调用方式比较
使用的方法: pybind11,因为我需要处理的图像数据是nd.array类型,查看资料发现pybind11对这个数据类型支持较好,很好方便的使用;
实现过程: 运行环境:Linux+anaconda3
- 先下载pybind11,从下面连接下载:
git clone https://github.com/pybind/pybind11.git
- 然后在环境中安装pytest:
pip install pytest
- 编译安装:
cd pybind11-master
mkdir build
cd build
cmake ..
cmake --build . --config Release --target check
- 将python代码改为C++代码格式,设置为example.cpp, 改写格式参见以下博客:
python与C++数据传递
python-c++ Numpy处理
C++和Python的混合编程-C++数据类型的导出和调用 - 在项目文件下编译存在的cpp文件
c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix`
需要根据自己的cpp函数修改example.cpp和-o后面的名称,编译成功会得到.so后缀的库,python代码调用的就是这个文件,过程中需要设置相应的python路径,否则会报错,详情参见:使用pybind11 将C++代码编译为python模块,需要将python的路径改为pybind11源码所在的路径;
对于上述编译代码的解释可以参见:pybind11使用
- 最后在python代码中import上述编译好的库就ok啦。
其他可以参考的资料如下:
python调用C++之pybind11入门
基于pybind11实现Python调用c++编写的CV算法–下 (Linux+Cmake)
pybind11 数据交互
Python与C/C++的混合调用
pybind11使用指南
其他cython相关的资料:
用Cython加速Python到“起飞”
用Cython写高性能的数组操作