共计 3381 个字符,预计需要花费 9 分钟才能阅读完成。
为什么选择 C# 调用 YOLO?
对于.NET 开发者来说,直接在 C# 中集成 YOLO 模型可以避免跨语言调用的复杂性。主流方案有三种:

- ONNX Runtime:支持跨平台,性能优秀,是微软官方推荐的推理引擎
- ML.NET:微软自家机器学习框架,但对计算机视觉任务支持有限
- 直接调用 Python:通过进程通信实现,性能损耗大且部署复杂
经过实测,ONNX Runtime 在 CPU/GPU 支持、模型格式兼容性方面表现最好,推荐作为首选方案。
环境准备(以 YOLOv8 为例)
-
安装 NuGet 包:
Install-Package Microsoft.ML.OnnxRuntime Install-Package OpenCvSharp4 Install-Package OpenCvSharp4.runtime.win -
下载官方预训练模型(.onnx 格式),建议从 Ultralytics 官方仓库获取:
// 模型下载示例 var modelPath = "yolov8n.onnx"; if (!File.Exists(modelPath)) {using var client = new HttpClient(); await client.DownloadFileTaskAsync( "https://github.com/ultralytics/assets/releases/download/v8.1.0/yolov8n.onnx", modelPath); }
核心推理流程实现
1. 图像预处理
using OpenCvSharp;
Mat Preprocess(Mat image)
{
// 保持宽高比的缩放
const int targetSize = 640;
var (h, w) = (image.Height, image.Width);
var scale = Math.Min(targetSize / (float)w, targetSize / (float)h);
var resized = new Mat();
Cv2.Resize(image, resized, new Size(w * scale, h * scale));
// 填充到正方形
var padded = new Mat(targetSize, targetSize, MatType.CV_8UC3, Scalar.Black);
resized.CopyTo(padded[new Rect(0, 0, resized.Width, resized.Height)]);
// 归一化并转 CHW 格式
padded.ConvertTo(padded, MatType.CV_32FC3, 1.0 / 255);
return padded;
}
2. 创建推理会话
using Microsoft.ML.OnnxRuntime;
var options = new SessionOptions();
// 启用 GPU 加速(需 CUDA 环境)// options.AppendExecutionProvider_CUDA();
var session = new InferenceSession(modelPath, options);
// 获取输入输出信息
var inputMeta = session.InputMetadata;
var inputName = inputMeta.Keys.First();
var inputShape = inputMeta[inputName].Dimensions;
3. 执行推理
float[] RunInference(Mat image)
{
// 转换为 Tensor
var tensor = new DenseTensor<float>(new Memory<float>(image.Data, 0, image.Total() * 3),
inputShape);
using var inputs = new List<NamedOnnxValue>
{NamedOnnxValue.CreateFromTensor(inputName, tensor)
};
// 推理并获取原始输出
using var results = session.Run(inputs);
return results.First().AsTensor<float>().ToArray();}
结果解析与可视化
YOLOv8 的输出格式为[84, 8400]:
– 前 4 个值是边界框坐标(x,y,w,h)
– 第 5 个值是置信度
– 后 80 个值是 COCO 类别概率
class DetectionResult
{public Rect Box { get; set;}
public float Confidence {get; set;}
public int ClassId {get; set;}
}
List<DetectionResult> ParseOutput(float[] output, float confThreshold = 0.5)
{var results = new List<DetectionResult>();
for (int i = 0; i < 8400; i++)
{var confidence = output[4 * 8400 + i];
if (confidence < confThreshold) continue;
// 获取类别 ID
var classOffset = 5 * 8400 + i;
var maxProb = output[classOffset];
var classId = 0;
for (int j = 1; j < 80; j++)
{if (output[classOffset + j * 8400] > maxProb)
{maxProb = output[classOffset + j * 8400];
classId = j;
}
}
// 添加检测结果
results.Add(new DetectionResult
{
Box = new Rect((int)(output[i] - output[2 * 8400 + i] / 2), // x
(int)(output[8400 + i] - output[3 * 8400 + i] / 2), // y
(int)output[2 * 8400 + i], // width
(int)output[3 * 8400 + i]), // height
Confidence = confidence,
ClassId = classId
});
}
return results;
}
性能优化技巧
批处理推理
// 将多个图像数据拼接为单个 Tensor
var batchInput = new DenseTensor<float>(new[] {batchSize, 3, 640, 640});
// 填充数据...
// 执行批推理
var outputs = session.Run(new[]
{NamedOnnxValue.CreateFromTensor(inputName, batchInput)
});
GPU 加速配置
- 安装 CUDA Toolkit 和 cuDNN
- 添加 NuGet 包:
Install-Package Microsoft.ML.OnnxRuntime.Gpu - 创建会话时启用 CUDA:
var options = SessionOptions.MakeSessionOptionWithCudaProvider(0);
模型量化
使用官方工具将 FP32 模型转为 INT8:
python -m onnxruntime.quantization.preprocess \
--input yolov8n.onnx --output yolov8n_quant.onnx
生产环境避坑指南
- 版本兼容性:
- ONNX Runtime 版本需与模型导出时使用的 PyTorch 版本匹配
-
遇到 Shape 不匹配错误时,检查模型输入输出维度
-
内存泄漏预防:
- 确保所有 IDisposable 对象(Mat、InferenceSession 等)正确释放
-
建议使用
using语句块或实现 Finalizer -
跨平台部署:
- Linux 环境下需安装 libgomp.so.1:
sudo apt-get install libgomp1 - ARM 设备推荐使用 ONNX Runtime 的 ARM64 版本
下一步探索方向
- 业务集成:
- 将检测结果存入数据库
-
触发后续业务流程(如报警、统计等)
-
模型再训练:
- 使用 Ultralytics YOLO 训练自定义数据集
- 导出为 ONNX 格式时注意保持前后处理一致性
通过这个完整的实现流程,你应该已经掌握了在 C# 中集成 YOLO 算法的核心方法。实际项目中还需要根据具体业务需求调整置信度阈值、NMS 参数等,建议通过 A / B 测试确定最佳参数组合。
正文完
