C++实战YOLO算法:从环境搭建到模型推理的完整指南

1次阅读
没有评论

共计 2059 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

技术背景

YOLO(You Only Look Once)算法因其实时性和高精度在工业检测领域广受欢迎。相比 Python 生态,C++ 部署有以下优势:

C++ 实战 YOLO 算法:从环境搭建到模型推理的完整指南

  • 运行效率更高,适合嵌入式设备和边缘计算
  • 内存管理更精细,适合长期运行的工业级应用
  • 更容易与现有 C ++ 工业系统集成

环境配置

Ubuntu 系统

  1. 安装基础依赖

    sudo apt-get install build-essential cmake git libgtk2.0-dev pkg-config

  2. 安装 CUDA 和 cuDNN(以 CUDA 11.3 为例)

    sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/3bf863cc.pub
    sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"
    sudo apt-get install cuda-11-3 libcudnn8

  3. 编译 OpenCV(建议 4.5.5 版本)

    git clone --branch 4.5.5 https://github.com/opencv/opencv.git
    cd opencv && mkdir build && cd build
    cmake -D WITH_CUDA=ON -D CUDA_ARCH_BIN="7.5" ..
    make -j8
    sudo make install

Windows 系统

  1. 安装 Visual Studio 2019+ 和 CMake
  2. 下载预编译的 CUDA 和 cuDNN
  3. 使用 CMake-GUI 配置 OpenCV 时勾选 WITH_CUDA 选项

核心实现

模型加载

cv::dnn::Net net = cv::dnn::readNetFromONNX("yolov5s.onnx");
net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);

图像预处理

cv::Mat blob = cv::dnn::blobFromImage(
    image,                     // 输入图像
    1/255.0,                  // 归一化系数
    cv::Size(640, 640),       // 模型输入尺寸
    cv::Scalar(0,0,0),        // 均值减除
    true,                     // 交换 RB 通道
    false,                    // 不裁剪
    CV_32F                    // 输出类型
);

后处理实现

struct Detection {
    int class_id;
    float confidence;
    cv::Rect box;
};

std::vector<Detection> postprocess(
    const cv::Mat& output, 
    float conf_threshold=0.5, 
    float iou_threshold=0.4
) {
    std::vector<Detection> detections;

    // 解析输出层数据
    // [Nx25200x85] for YOLOv5

    // 置信度过滤
    // ...

    // NMS 处理
    // ...

    return detections;
}

代码规范

CMake 配置示例

cmake_minimum_required(VERSION 3.10)
project(YOLOInference)

find_package(OpenCV REQUIRED)

add_executable(yolo_inference main.cpp)
target_link_libraries(yolo_inference ${OpenCV_LIBS})

RAII 资源管理

class NetWrapper {
public:
    NetWrapper(const std::string& model_path) {net_ = cv::dnn::readNet(model_path);
    }

    ~NetWrapper() {// 自动释放资源}

private:
    cv::dnn::Net net_;
};

性能优化

精度模式 推理时间 (ms) 显存占用 (MB)
FP32 15.2 1200
FP16 9.8 800

多线程预处理方案:

void preprocessThread(
    const cv::Mat& frame, 
    std::promise<cv::Mat>&& promise
) {cv::Mat blob = cv::dnn::blobFromImage(frame, ...);
    promise.set_value(blob);
}

避坑指南

  1. OpenCV 版本与 CUDA 的兼容性
  2. OpenCV 4.5+ 对 CUDA 11.x 支持最好
  3. 编译时注意 CUDA_ARCH 设置

  4. 模型输出层解析

  5. 不同 YOLO 版本的输出维度不同
  6. 建议使用 netron 工具查看模型结构

  7. 跨平台部署

  8. Windows 下注意 DLL 依赖
  9. ARM 平台需要交叉编译

思考题

如何实现动态 batch 处理?考虑以下方向:
– 使用 std::vector 收集多帧
– 设计批处理队列
– 异步推理流水线

正文完
 0
评论(没有评论)