C++ 迁移方案
用 C++ 重写可以进一步减少 10-20ms 的 Python 开销,尤其是后处理部分。
性能对比
| 实现方式 | 后处理耗时 | 总 FPS | 难度 |
|---|---|---|---|
| Python V2 (320×320) | 15-25ms | 40-60 | |
| C++ 原生 | 5-10ms | 60-80 | |
| C++ + 解析器 | 3-5ms | 70-90 |
两条 C++ 路径
方案 A:使用 hobot_dnn C++ API(推荐,简单)
// 核心代码框架
#include "hobot_dnn/hobot_dnn.h"
#include <opencv2/opencv.hpp>
int main() {
// 1. 加载模型(自动使用 ultralytics_yolo 解析器)
hobot::dnn::Model model;
model.Load("/home/sunrise/yolov5_best_quant(320).bin",
{{"parser", "ultralytics_yolo"}});
// 2. 摄像头
cv::VideoCapture cap(0);
cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480);
// 3. 推理循环
while (true) {
cv::Mat frame;
cap.read(frame);
// BGR → NV12
cv::Mat nv12;
cv::cvtColor(frame, nv12, cv::COLOR_BGR2NV12);
// 推理(解析器自动处理 DFL+NMS)
auto outputs = model.Forward({nv12});
// 直接获取解析后的检测结果
auto dets = outputs.GetDetections();
// 绘制 + 显示
for (auto& det : dets) {
cv::rectangle(frame, det.bbox, cv::Scalar(0, 255, 0), 2);
}
cv::imshow("YOLO", frame);
if (cv::waitKey(1) == 'q') break;
}
}
方案 B:参考社区 C++ 示例(完整实现)
官方 Model Zoo C++ 示例:
# 1. 克隆示例代码
git clone https://github.com/D-Robotics/rdk_model_zoo.git
cd rdk_model_zoo/samples/vision/ultralytics_yolo/cpp
# 2. 修改配置文件
# 编辑 config/yolo_seg_320.json
{
"model_file": "/home/sunrise/yolov5_best_quant(320).bin",
"dnn_parser": "ultralytics_yolo",
"reg_max": 16,
"class_num": 6,
"score_threshold": 0.25,
"nms_threshold": 0.30
}
# 3. 编译
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local
make -j4
# 4. 运行
./yolo_seg_example --config ../config/yolo_seg_320.json --camera 0
完整 C++ 示例(自包含版)
// yolo_seg_cpp.cpp
#include <iostream>
#include <vector>
#include <chrono>
#include <opencv2/opencv.hpp>
#include <hobot_dnn/hobot_dnn.h>
struct Detection {
int cls;
float conf;
cv::Rect bbox;
cv::Mat mask; // 可选
};
class YoloSeg {
public:
YoloSeg(const std::string& model_path) {
model_.Load(model_path, {{"parser", "ultralytics_yolo"}});
}
std::vector<Detection> Detect(const cv::Mat& frame) {
// BGR → NV12
cv::Mat nv12;
cv::cvtColor(frame, nv12, cv::COLOR_BGR2NV12);
// 推理
auto start = std::chrono::high_resolution_clock::now();
auto outputs = model_.Forward({nv12});
auto end = std::chrono::high_resolution_clock::now();
std::cout << "BPU: "
<< std::chrono::duration<double, std::milli>(end - start).count()
<< "ms" << std::endl;
// 解析结果(根据实际输出格式调整)
std::vector<Detection> dets;
// TODO: 解析 outputs 中的 boxes/scores/classes
return dets;
}
private:
hobot::dnn::Model model_;
};
int main() {
YoloSeg detector("/home/sunrise/yolov5_best_quant(320).bin");
cv::VideoCapture cap(0);
cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480);
cap.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));
cap.set(cv::CAP_PROP_BUFFERSIZE, 1);
int fps_count = 0;
auto fps_t0 = std::chrono::high_resolution_clock::now();
while (true) {
cv::Mat frame;
cap.read(frame);
if (frame.empty()) continue;
auto dets = detector.Detect(frame);
// 绘制
for (auto& det : dets) {
cv::rectangle(frame, det.bbox, cv::Scalar(0, 255, 0), 2);
cv::putText(frame, std::to_string(det.conf),
{det.bbox.x, det.bbox.y - 5},
cv::FONT_HERSHEY_SIMPLEX, 0.5, {0, 255, 0}, 1);
}
// FPS 统计
fps_count++;
if (fps_count >= 30) {
auto now = std::chrono::high_resolution_clock::now();
double fps = 30.0 / std::chrono::duration<double>(now - fps_t0).count();
std::cout << "FPS: " << fps << std::endl;
fps_count = 0;
fps_t0 = now;
}
cv::imshow("YOLO", frame);
if (cv::waitKey(1) == 'q') break;
}
return 0;
}
编译步骤
# 1. 创建项目目录
mkdir yolo_cpp && cd yolo_cpp
# 2. 创建 CMakeLists.txt
cat > CMakeLists.txt << 'EOF'
cmake_minimum_required(VERSION 3.10)
project(yolo_seg_cpp)
set(CMAKE_CXX_STANDARD 14)
find_package(OpenCV REQUIRED)
find_package(hobot_dnn REQUIRED)
add_executable(yolo_seg_cpp yolo_seg_cpp.cpp)
target_link_libraries(yolo_seg_cpp
${OpenCV_LIBS}
hobot_dnn
)
EOF
# 3. 编译
mkdir build && cd build
cmake ..
make -j4
# 4. 运行
./yolo_seg_cpp
参考资源
| 资源 | 链接 |
|---|---|
| hobot_dnn C++ API | GitHub - D-Robotics/hobot_dnn · GitHub |
| Model Zoo C++ 示例 | rdk_model_zoo/samples/vision/ultralytics_yolo at rdk_x5 · D-Robotics/rdk_model_zoo · GitHub |
| TROS C++ 部署教程 | 【技术分享】使用TROS 高效推理 Model Zoo 模型教程 |
建议
| 你的情况 | 推荐方案 |
|---|---|
| Python FPS ≥ 45 | 先用着,没必要换 C++ |
| Python FPS 30-45 | 试试 C++ + 解析器 |
| Python FPS < 30 | 先排查量化配置,再考虑 C++ |
先跑完 Python V2 的分层计时,把输出发出来,我帮你判断是否值得换 C++!![]()