利用cmake将c++文件编译成.so库文件,通过import调用
- 简单调用
- 高级用法-调用c++项目
简单调用
创建trypybind.cpp文件
#include <pybind11/pybind11.h>
#include <iostream>
namespace py = pybind11;
using namespace std;
//绑定一个函数
int main()
{ cout<<"hello world!!!"<<endl;return 0;
}
PYBIND11_MODULE(tryPybind, m) {m.def("main", &main);
}
PYBIND11_MODULE(trypybind, m) {
m.def(“main”, &main);
}
trypybind,库名,
import trypybind
“main”, &main意思是将c++ 中的main函数绑定到 python中可以引用的函数main上。
PYBIND11_MODULE( 模块名, 模块实例对象 ){m.doc() = "pybind11 example"; //可选,说明这个模块是做什么的//封装的具体操作。这些操作包括普通的函数的封装,类的访问等下面用不同例子来说明问题m.def( "给python调用方法名", &实际操作的函数, "函数功能说明" ). //其中函数功能说明为可选
}
编译步骤:
- 创建CMakeLists.txt ;
# 版本号无关轻重
cmake_minimum_required(VERSION 3.21)
# 项目名称
project(trypybind)
# 指定python解释器的位置
set(PYTHON EXECUTABLE "/usr/bin/python")
# 添加pybind11到项目
add_subdirectory(extern/pybind11)
Pybind11_add_module(trypybind trypybind.cpp)
- clone pybind11库;
mkdir extern
cd extern
git clone https://github.com/pybind/pybind11.git
- 编译;
mkdir build && cd build
cmake ..&& make
编译成功生成tryPybind.cpython-38-x86_64-linux-gnu.so文件
4. 引用;
创建try.py文件
import trypybind
trypybind.main()
高级用法-调用c++项目
有项目文件如下:
trypybind.cpp
salt.cpp
salt.h
trypybind.cpp
#include <pybind11/pybind11.h>
#include <iostream>
namespace py = pybind11;
#include <opencv2/opencv.hpp>
#include"salt.h"
using namespace cv;
using namespace std;
//绑定一个函数
int main()
{ Mat image1 = imread("test.jpg"); //读取图像;if (image1.empty()){cout << "读取错误" << endl;return -1;}Salt(image1, 5000); //加入5000个噪声点imwrite("test_salt.jpg", image1); //保存图像return 0;
}
PYBIND11_MODULE(trypybind, m) {m.def("main", &main);
}
salt.h
#include<iostream>
#include<opencv2/opencv.hpp>
#include <random> //随机数头文件
using namespace cv;
using namespace std;
void Salt(Mat image, int n); //n:加入噪声点数
salt.cpp
#include "salt.h"
void Salt(Mat image, int n)
{//随机数生成器default_random_engine generater;uniform_int_distribution<int>randomRow(0, image.rows - 1);uniform_int_distribution<int>randomCol(0, image.cols - 1);int i, j;for (int k = 0; k < n; k++){i = randomCol(generater);j = randomRow(generater);if (image.channels() == 1){ // cout<<image.at<uchar>(j, i)<<endl;image.at<uchar>(j, i) = 255;}else if (image.channels() == 3){// cout<<static_cast<int>(image.at<Vec3b>(j, i)[0])<<endl;// cout<<static_cast<int>(image.at<Vec3b>(j, i)[1])<<endl;// cout<<static_cast<int>(image.at<Vec3b>(j, i)[2])<<endl;image.at<Vec3b>(j, i)[0] = 255;image.at<Vec3b>(j, i)[1] = 255;image.at<Vec3b>(j, i)[2] = 255;}}
}
CMakeLists.txt
# 版本号无关轻重
cmake_minimum_required(VERSION 3.21)
# 项目名称
project(trypybind)
# 添加opencv依赖
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
# 指定python解释器的位置
set(PYTHON EXECUTABLE "/usr/bin/python")
# 添加pybind11到项目
add_subdirectory(extern/pybind11)
SET(SOURCES${CMAKE_CURRENT_SOURCE_DIR}/trypybind.cpp${CMAKE_CURRENT_SOURCE_DIR}/salt.h${CMAKE_CURRENT_SOURCE_DIR}/salt.cpp
)
# pybind11的一个cmake函数 将trypybind.cpp编译成一个C++模块,并绑定python,生成一个python可导入的拓展模块,"trypybind"即为模块名
Pybind11_add_module(trypybind ${SOURCES})
target_link_libraries(trypybind PRIVATE ${OpenCV_LIBS} )
步骤与简单调用一样
clone pybind11库
mkdir build && cd build
cmake .. && make编译
编译完成生成tryPybind.cpython-38-x86_64-linux-gnu.so文件,即可通过python引用
参考:使用pybind11实现python调用c++实现的opencv代码