-
以往的项目所使用的编程语言是Python作为开发语言,但是实际上Python的执行效率低和占用内存大,因此使用c++做模型推理似乎是一个好的选择。
-
这让我想到了使用Cython,Cython使用了用C编写的独立共享库,并将它们转换为Python模块。实际还是在Python上写库。
-
PyBind11相反,它提供C++ API,写的是C++代码库,然后转成Python模块。
-
Pybind11只支持C++,使用C++ 11特性。
-
此外,Pybind11的另一个优点是可以轻松处理来自Python的底层数据和类型(如Numpy array)。对于计算机视觉代码库的编写,无疑是一个好的选择。
-
本项目把yolov5核心模块,预处理,前处理,后处理用C++来写,使用pybind11把C++ 库/代码包装为可以在 Python 中使用的模块(本项目把类别,坐标,置信度封装成一个类与Python绑定),供Python调用,这样就可以大大提高代码的执行效率。
-
本项目基于:https://github.com/itsnine/yolov5-onnxruntime 来进行修改,
-
增加pybind11进行封装,封装yolov5核心流程,使用C++版本的onnxruntime,opencv,python仅需要import yolo_ort,通过配置模型,数据,类别来进行调用。
PYBIND11_MODULE(yolo_ort, m){
m.doc() = "pybind11 example yolov5 infer";
m.def("infer", &infer, "example yolov5 infer", py::arg("modelPath"), py::arg("imagePath"), py::arg("classNamesPath"));
// 注册识别类型
py::class_<Detection>(m, "Detection")
.def(py::init<>())
.def_readwrite("classId", &Detection::classId)
.def_readwrite("confidence", &Detection::conf) // 注意置信度的参数类型
// 由于python不支持Rect类型的数据,所以要把box数据转换成元组
.def_property("box", [](const Detection& detection) {
return py::make_tuple(detection.box.x, detection.box.y, detection.box.width, detection.box.height);
}, [](Detection& detection, const std::tuple<int, int, int, int>& box) {
detection.box.x = std::get<0>(box);
detection.box.y = std::get<1>(box);
detection.box.width = std::get<2>(box);
detection.box.height = std::get<3>(box);
});
}
- python 3.6(目前上传的yolo_ort.so只支持3.6,需要其他版本的需要重新在相关解释器上进行编译)
- OpenCV 4.x
- ONNXRuntime 1.7+
- OS: Windows 10 ,Ubuntu 20.04,centos7
- CUDA 11+ [CPU]
- pybind11
git clone https://github.com/opencv/opencv.git
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_EXAMPLES=ON ../opencv
make -j7
git clone --single-branch --branch rel-1.7.0 https://github.com/microsoft/onnxruntime.git
./build.sh --skip_tests --config Release --build_shared_lib --parallel
https://blog.csdn.net/qq_27149279/article/details/121352696
export PYTHONPATH=/root/miniconda3/envs/resa/lib/python3.7/site-packages
g++ your_source_files -o your_executable -L/path/to/onnxruntime/lib -lonnxruntime
make start
python test_yolo_pybind11.py
mkdir build
cd build
cmake ..
cmake --build .
python test_yolo_pybind11.py
import yolo_ort
# 创建YOLODetectorWrapper实例
detector = yolo_ort.YOLODetectorWrapper("models/yolov5s.onnx", True)
# 读取图像
image = "./images/bus.jpg"
# 进行推理
result = detector.infer(image, 0.5, 0.5)
# 处理结果
for detection in result:
print(detection)
pybind11-yolov5模型使用的CPU内存(MB): 53.48828125
python-yolov5模型使用的CPU内存(MB): 188.41796875
c++: 38.006s 平均每张0.253秒
python: 47.459s 平均每张0.449秒
c++: 95.975s 平均每张0.63秒
python: 142.574s 平均每张0.95秒