# YoloInferenceEngine **Repository Path**: testware/yolo-inference-engine ## Basic Information - **Project Name**: YoloInferenceEngine - **Description**: 基于ONNX Runtime或TensorRT进行YOLO推理的C++DLL - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-08-14 - **Last Updated**: 2026-08-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # YOLO Inference Engine 一个基于 ONNX Runtime 和 OpenCV 的高性能 YOLO 目标检测推理引擎,支持 C++ 原生调用和 DLL 导出供其他语言(如 C#)集成。 ## 开发计划 (TODO) ## TensorRT 加速推理 - [ ] 开发 C++ DLL 封装 TensorRT 推理引擎 ## 项目特性 - 🚀 **高性能推理**:基于 ONNX Runtime,启用图优化和多线程支持 - 🎯 **YOLO 模型支持**:兼容 YOLOv10、YOLO26 等最新 YOLO 系列模型 - 🔧 **Pimpl 设计模式**:隐藏实现细节,提供清晰的 API 接口 - 🌐 **跨语言调用**:提供 C 风格导出函数,支持 C#/Python 等语言集成 - 📦 **DLL 动态库**:可编译为共享库,便于项目集成 ## 技术栈 - **C++20**:现代 C++ 标准 - **ONNX Runtime**:微软开源的跨平台推理引擎 - **OpenCV**:图像处理与预处理 - **CMake**:跨平台构建系统 ## 目录结构 ``` YoloInferenceEngine/ ├── src/ │ ├── main.cpp # 测试示例程序 │ ├── onnx_engine.h # 引擎头文件(API 定义) │ └── onnx_engine.cpp # 引擎实现 ├── CMakeLists.txt # CMake 构建配置 └── README.md # 项目说明文档 ``` ## 环境要求 ### 依赖库 1. **ONNX Runtime** (>= 1.15) - 下载地址:[ONNX Runtime Releases](https://github.com/microsoft/onnxruntime/releases) - 需要包含头文件和链接库 2. **OpenCV** (>= 4.5) - 下载地址:[OpenCV Releases](https://opencv.org/releases/) - 需要编译好的库文件 ### 开发环境 - **编译器**:支持 C++20 的编译器(MSVC 2019+、GCC 10+、Clang 12+) - **构建工具**:CMake >= 4.2 - **操作系统**:Windows(当前配置),可扩展至 Linux/macOS ## 快速开始 ### 1. 配置依赖路径 编辑 `CMakeLists.txt`,修改以下路径为你的实际安装位置: ```cmake # ONNX Runtime 路径 set(ONNXRUNTIME_DIR "E:/libs/onnxruntime") # OpenCV 路径 set(OpenCV_DIR "E:/libs/opencv/build/x64/vc16/lib") ``` ### 2. 准备模型文件 将训练好的 YOLO 模型转换为 ONNX 格式,并放置在工作目录: - 模型文件:`yolo26n.onnx`(或其他 YOLO ONNX 模型) - 测试图片:`test.jpg` ### 3. 编译项目 ```bash # 创建构建目录 mkdir build cd build # 编译 cmake --build . --config Release ``` ### 4. 运行测试 #### 方式一:直接运行可执行文件(需取消注释 CMakeLists.txt 中的 YoloTest 配置) ```bash ./Release/YoloTest.exe ``` #### 方式二:作为 DLL 集成到其他项目 编译生成的 `YoloEngine.dll` 可在 C# 等其他语言中调用。 ## API 使用指南 ### DLL 导出函数(C 风格) 适用于 C#/Python 等语言调用: #### C# P/Invoke 示例 ```csharp using System; using System.Runtime.InteropServices; public class YoloDetector : IDisposable { [StructLayout(LayoutKind.Sequential)] public struct DetectionResult { public float x1, y1, x2, y2; public float confidence; public int classId; } [DllImport("YoloEngine.dll", CallingConvention = CallingConvention.StdCall)] private static extern IntPtr InitEngine(string modelPath); [DllImport("YoloEngine.dll", CallingConvention = CallingConvention.StdCall)] private static extern int Detect( IntPtr handle, byte[] imageData, int width, int height, [Out] DetectionResult[] results, ref int resultCount); [DllImport("YoloEngine.dll", CallingConvention = CallingConvention.StdCall)] private static extern void DestroyEngine(IntPtr handle); private IntPtr _handle; public bool Initialize(string modelPath) { _handle = InitEngine(modelPath); return _handle != IntPtr.Zero; } public DetectionResult[] Detect(byte[] imageData, int width, int height) { int maxResults = 300; var results = new DetectionResult[maxResults]; int resultCount = maxResults; int status = Detect(_handle, imageData, width, height, results, ref resultCount); if (status != 0) throw new Exception("Detection failed"); Array.Resize(ref results, resultCount); return results; } public void Dispose() { if (_handle != IntPtr.Zero) { DestroyEngine(_handle); _handle = IntPtr.Zero; } } } ``` ## 核心架构 ### Pimpl 设计模式 项目采用 **Pointer to Implementation** 模式,将 ONNX Runtime 的具体实现隐藏在 `Impl` 结构体中: ```cpp class OnnxEngine { private: struct Impl; // 前向声明 Impl* pImpl; // 指向实现的指针 }; ``` **优势:** - 隐藏第三方库依赖,减少编译依赖 - 提高编译速度,修改实现不影响接口 - 二进制兼容性更好,适合 DLL 导出 ### 推理流程 1. **模型加载**:初始化 ONNX Runtime 环境,加载 ONNX 模型 2. **图像预处理**: - 缩放至 640×640 - 归一化到 [0, 1] - HWC → CHW 格式转换 3. **模型推理**:执行前向传播 4. **结果解析**:解析输出张量,过滤低置信度检测结果 ### 数据流 ``` 原始图像 (HWC, uint8) ↓ 预处理 (Resize + Normalize) ↓ 输入张量 (CHW, float32, 1×3×640×640) ↓ ONNX Runtime 推理 ↓ 输出张量 (N×6, float32) ↓ 后处理 (置信度过滤) ↓ DetectionResult 数组 ``` ## 配置说明 ### 模型输入输出 - **输入尺寸**:640×640×3(可修改 `inputSize` 常量适配其他尺寸) - **输出格式**:每个检测框 6 个值 `[x1, y1, x2, y2, confidence, classId]` - **最大检测数**:300 个目标(可调整) - **置信度阈值**:0.5(在 `detect()` 方法中修改) ### 性能优化 - **线程数**:默认单线程推理(`SetIntraOpNumThreads(1)`) - **图优化**:启用全部优化级别(`ORT_ENABLE_ALL`) - **内存分配**:使用 CPU 内存分配器 ## 常见问题 ### 1. 找不到 ONNX Runtime 库 确保 `ONNXRUNTIME_DIR` 路径正确,且包含: - `include/` 目录(头文件) - `lib/onnxruntime.lib`(链接库) - `bin/onnxruntime.dll`(运行时库,需复制到输出目录) ### 2. OpenCV 链接错误 检查 `OpenCV_DIR` 是否指向正确的库目录,确认已调用 `find_package(OpenCV REQUIRED)`。 ### 3. DLL 加载失败 确保以下 DLL 在可执行文件目录或系统 PATH 中: - `onnxruntime.dll` - `opencv_world4xx.dll`(根据版本不同) ### 4. 模型不兼容 不同 YOLO 版本的输出格式可能不同,需调整 `detect()` 方法中的解析逻辑: - YOLOv5/v7/v8:输出格式通常为 `[batch, num_boxes, 84]` - YOLOv10/v26:输出格式为 `[batch, 300, 6]`(当前支持) ## 扩展开发 ### 添加自定义后处理 修改 `onnx_engine.cpp` 中的 `detect()` 方法,添加 NMS(非极大值抑制)等后处理: ```cpp // 在解析输出后添加 NMS std::sort(results.begin(), results.end(), [](const DetectionResult& a, const DetectionResult& b) { return a.confidence > b.confidence; }); // 实现 NMS 逻辑... ``` ### 支持动态输入尺寸 修改 `inputShape` 和预处理逻辑,支持任意尺寸输入: ```cpp std::vector inputShape = {1, 3, height, width}; ``` ### 添加 GPU 支持 启用 CUDA Execution Provider: ```cpp OrtCUDAProviderOptions cudaOptions; sessionOptions.AppendExecutionProvider_CUDA(cudaOptions); ``` ## 许可证 本项目仅供学习和研究使用。使用第三方库时请遵守其相应许可证: - ONNX Runtime:MIT License - OpenCV:Apache 2.0 License ## 联系方式 如有问题或建议,欢迎提交 Issue 或 Pull Request。 --- **祝使用愉快!** 🎉