新手必看:C#调用YOLO模型完成图片/视频目标检测(上位机版)

张开发
2026/4/9 19:09:26 15 分钟阅读

分享文章

新手必看:C#调用YOLO模型完成图片/视频目标检测(上位机版)
新手必看C#调用YOLO模型完成图片/视频目标检测上位机版作为一名常年做C#上位机开发的程序员我经常收到新手朋友的提问“刚学C#想做目标检测YOLO模型怎么调用”“网上全是Python版的YOLO教程C#的例子要么残缺要么跑不起来有没有零基础能上手的”确实YOLO模型的主流教程都是基于Python的而C#作为上位机开发的核心语言相关的实战资料不仅零散还常常跳过新手最需要的基础步骤。比如直接扔一段代码却不解释“为什么要做图像预处理”“模型导出时的参数有什么用”导致新手复制代码后要么推理结果为空要么界面卡死、内存暴涨。这篇文章就专门针对C#上位机新手从“零”开始一步步教你用C#调用YOLO模型以YOLOv11为例完成图片、视频、摄像头实时的目标检测。全程用WinForm做演示代码完整可直接复制运行还会把新手常踩的坑一一标注出来确保你跟着做就能成功。一、前期准备新手别绕远路先把基础环境搭好新手最容易犯的错是“准备工作没做足上来就写代码”结果各种报错。这部分我们只做“必要且简单”的准备复杂的优化等后续再讲。1. 软件环境选对工具少走弯路开发工具Visual Studio 2022社区版免费足够用别用旧版本避免.NET框架兼容问题。.NET版本创建项目时选Windows Forms App (.NET 9)2026年推荐性能最好、跨平台支持最完善。如果电脑没有.NET 9选.NET 8也可以后续升级简单。2. 必须安装的NuGet包全部免费在项目中右键 → 管理NuGet程序包 → 浏览 → 搜索安装以下包全部选最新稳定版Install-PackageYoloSharp# YOLO推理库推荐最简单# 或者用这个功能更全但稍复杂# Install-Package YoloDotNetInstall-PackageSkiaSharp.Views.WinForms# 高效绘图画检测框Install-PackageAForge.Video.DirectShow# 摄像头采集USB工业相机/普通摄像头都支持Install-PackageSystem.Drawing.Common# Bitmap处理.NET 8必须3. 获取YOLO模型文件最关键一步两种最简单的方式任选其一方式A直接下载已转换好的ONNX模型推荐新手下载地址https://github.com/ultralytics/assets/releases/download/v8.3.0/yolov11n.onnx选择 yolov11n.onnxnano版最轻最快416×416或640×640都行新手建议先用416放到项目根目录新建的models文件夹里右键该文件 → 属性 → 复制到输出目录 始终复制方式B自己从Python导出如果想自定义类别# 安装ultralytics只需一次pipinstallultralytics# 导出onnx模型416x416最快yoloexportmodelyolo11n.ptformatonnximgsz416opset12simplifyTruedynamicFalse导出后得到yolo11n.onnx文件放到models文件夹。二、完整代码实现单文件可运行版新建项目后直接把下面代码全部粘贴到Form1.cs里即可。usingSystem;usingSystem.Drawing;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;usingAForge.Video;usingAForge.Video.DirectShow;usingSkiaSharp;usingYoloSharp;namespaceYoloCSharpDemo{publicpartialclassForm1:Form{privateVideoCaptureDevicevideoSource;privateYoloPredictoryolo;privateboolisRunningfalse;publicForm1(){InitializeComponent();this.TextC# YOLO 实时目标检测新手版;this.SizenewSize(1000,700);// 界面布局代码创建方便复制varpicnewPictureBox{DockDockStyle.Fill,SizeModePictureBoxSizeMode.Zoom};varlblnewLabel{TextFPS: -- | 状态未启动,DockDockStyle.Bottom,Height40,FontnewFont(微软雅黑,12)};varbtnStartnewButton{Text启动检测,Width120,Height40};varbtnStopnewButton{Text停止,Width120,Height40};btnStart.ClickBtnStart_Click;btnStop.ClickBtnStop_Click;varpanelnewFlowLayoutPanel{DockDockStyle.Bottom,Height60};panel.Controls.Add(btnStart);panel.Controls.Add(btnStop);panel.Controls.Add(lbl);this.Controls.Add(pic);this.Controls.Add(panel);// 保存控件引用this.picPreviewpic;this.lblStatuslbl;}privatePictureBoxpicPreview;privateLabellblStatus;privateasyncvoidBtnStart_Click(objectsender,EventArgse){if(isRunning)return;// 加载模型只需一次try{yolonewYoloPredictor(models/yolo11n.onnx,YoloTask.Detect);}catch(Exceptionex){MessageBox.Show(模型加载失败\nex.Message\n请确认models文件夹里有yolo11n.onnx);return;}// 启动摄像头vardevicesnewFilterInfoCollection(FilterCategory.VideoInputDevice);if(devices.Count0){MessageBox.Show(未找到摄像头);return;}videoSourcenewVideoCaptureDevice(devices[0].MonikerString);videoSource.NewFrameVideo_NewFrame;videoSource.Start();isRunningtrue;lblStatus.Text状态运行中 | FPS计算中...;}privatevoidBtnStop_Click(objectsender,EventArgse){if(!isRunning)return;videoSource?.SignalToStop();videoSource?.WaitForStop();yolo?.Dispose();isRunningfalse;lblStatus.Text状态已停止;}privateBitmapcurrentFrame;// 用于保存最新帧privatevoidVideo_NewFrame(objectsender,NewFrameEventArgseventArgs){// 关键优化只保留最新一帧丢弃旧帧if(currentFrame!null)currentFrame.Dispose();currentFrame(Bitmap)eventArgs.Frame.Clone();// 异步处理防止卡界面_Task.Run(()ProcessFrame(currentFrame));}privateintframeCount0;privateDateTimelastFpsTimeDateTime.Now;privatevoidProcessFrame(Bitmapframe){try{usingvarskBmpSKBitmap.FromImage(SKImage.FromBitmap(frame));varresultsyolo.Detect(skBmp);usingvarcanvasnewSKCanvas(skBmp);foreach(varrinresults){if(r.Confidence0.5f)continue;varrectr.BoundingBox;usingvarpaintnewSKPaint{StyleSKPaintStyle.Stroke,ColorSKColors.Red,StrokeWidth3};canvas.DrawRect(rect.X,rect.Y,rect.Width,rect.Height,paint);canvas.DrawText(${r.Label.Name}{r.Confidence:P0},rect.X,rect.Y-5,newSKPaint{ColorSKColors.Yellow,TextSize20});}// 计算FPSframeCount;if((DateTime.Now-lastFpsTime).TotalSeconds1){doublefpsframeCount;this.Invoke((MethodInvoker)delegate{lblStatus.Text$状态运行中 | FPS{fps:F1};});frameCount0;lastFpsTimeDateTime.Now;}// 更新UI必须在主线程this.Invoke((MethodInvoker)delegate{picPreview.Image?.Dispose();picPreview.ImageskBmp.ToBitmap();});}catch(Exceptionex){this.Invoke((MethodInvoker)delegate{lblStatus.Text错误ex.Message;});}}protectedoverridevoidOnFormClosing(FormClosingEventArgse){videoSource?.SignalToStop();yolo?.Dispose();currentFrame?.Dispose();base.OnFormClosing(e);}}}四、常见踩坑 快速解决新手必看序号问题描述现象解决方法已包含在代码中1模型加载失败“Could not load model”确认onnx文件在输出目录右键属性→始终复制2画面卡顿、延迟越来越大FPS下降到个位数使用最新帧丢弃机制 Task.Run后台推理3内存持续上升最终闪退运行10分钟后崩溃所有Bitmap/SKBitmap用using块4检测结果为空框画不出来检查模型路径、输入尺寸416或6405界面无响应、点击不动UI卡死推理全部放后台线程6摄像头打不开“No video devices found”确认设备管理器有摄像头、关闭其他占用软件7FPS很低10画面严重卡用yolo11n 416×416输入 DirectML加速五、快速上手 下一步建议新建WinForms项目.NET 9安装上面4个NuGet包下载yolov11n.onnx416×416放到项目根目录/models替换Form1.cs全部内容F5运行 → 点击“启动检测” → 对准物体测试下一步进阶建议加PLC报警检测到异常 → 写Modbus线圈加语音播报用NAudio或Windows Speech加Excel报表用EPPlus记录异常截图时间加GPU加速安装Microsoft.ML.OnnxRuntime.DirectML如果想看这些进阶功能的完整代码、项目压缩包、或遇到任何报错直接评论或私信我24小时内回复并帮你debug点赞收藏这可能是你今年最适合新手的C# YOLO上位机教程

更多文章