C#中结合YOLO算法的实战入门:从环境配置到目标检测

1次阅读
没有评论

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

image.webp

为什么选择 C# 调用 YOLO?

对于.NET 开发者来说,直接在 C# 中集成 YOLO 模型可以避免跨语言调用的复杂性。主流方案有三种:

C# 中结合 YOLO 算法的实战入门:从环境配置到目标检测

  • ONNX Runtime:支持跨平台,性能优秀,是微软官方推荐的推理引擎
  • ML.NET:微软自家机器学习框架,但对计算机视觉任务支持有限
  • 直接调用 Python:通过进程通信实现,性能损耗大且部署复杂

经过实测,ONNX Runtime 在 CPU/GPU 支持、模型格式兼容性方面表现最好,推荐作为首选方案。

环境准备(以 YOLOv8 为例)

  1. 安装 NuGet 包:

    Install-Package Microsoft.ML.OnnxRuntime
    Install-Package OpenCvSharp4
    Install-Package OpenCvSharp4.runtime.win

  2. 下载官方预训练模型(.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 加速配置

  1. 安装 CUDA Toolkit 和 cuDNN
  2. 添加 NuGet 包:
    Install-Package Microsoft.ML.OnnxRuntime.Gpu
  3. 创建会话时启用 CUDA:
    var options = SessionOptions.MakeSessionOptionWithCudaProvider(0);

模型量化

使用官方工具将 FP32 模型转为 INT8:

python -m onnxruntime.quantization.preprocess \
    --input yolov8n.onnx --output yolov8n_quant.onnx

生产环境避坑指南

  1. 版本兼容性:
  2. ONNX Runtime 版本需与模型导出时使用的 PyTorch 版本匹配
  3. 遇到 Shape 不匹配错误时,检查模型输入输出维度

  4. 内存泄漏预防:

  5. 确保所有 IDisposable 对象(Mat、InferenceSession 等)正确释放
  6. 建议使用 using 语句块或实现 Finalizer

  7. 跨平台部署:

  8. Linux 环境下需安装 libgomp.so.1:sudo apt-get install libgomp1
  9. ARM 设备推荐使用 ONNX Runtime 的 ARM64 版本

下一步探索方向

  1. 业务集成:
  2. 将检测结果存入数据库
  3. 触发后续业务流程(如报警、统计等)

  4. 模型再训练:

  5. 使用 Ultralytics YOLO 训练自定义数据集
  6. 导出为 ONNX 格式时注意保持前后处理一致性

通过这个完整的实现流程,你应该已经掌握了在 C# 中集成 YOLO 算法的核心方法。实际项目中还需要根据具体业务需求调整置信度阈值、NMS 参数等,建议通过 A / B 测试确定最佳参数组合。

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