目前在工业 C# 上位机中使用最广泛的 YOLOv8 实时检测代码模板
以下是一套目前在工业 C# 上位机中使用最广泛的YOLOv8 实时检测代码模板2025 年最新稳定写法。usingMicrosoft.ML.OnnxRuntime;usingMicrosoft.ML.OnnxRuntime.Tensors;usingOpenCvSharp;usingSystem;usingSystem.Collections.Generic;usingSystem.Drawing;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;namespaceYoloV8LiveDemo{publicpartialclassMainForm:Form{privateVideoCapturecap;privateInferenceSessionsession;privateconstintINPUT_SIZE640;// YOLOv8 官方默认 640也可改 416/320 提速privatereadonlyTimertimernew(){Interval40};// 目标 25 fps// 你自己的类别按模型训练时的顺序写privatereadonlystring[]classNamesnew[]{person,bicycle,car,motorcycle,airplane,bus,train,truck,boat,traffic light,fire hydrant,/* ... */toothbrush};publicMainForm(){InitializeComponent();InitCamera();InitYolo();timer.Tickasync(_,_)awaitProcessFrameAsync();timer.Start();}privatevoidInitCamera(){// 0 默认 USB 摄像头可改为 1、2 或 RTSP 地址capnewVideoCapture(0,VideoCaptureAPIs.DSHOW);// cap new VideoCapture(rtsp://admin:123456192.168.1.100:554/h264/ch1/main/av_stream);if(!cap.IsOpened()){MessageBox.Show(无法打开摄像头);Close();}}privatevoidInitYolo(){varoptnewSessionOptions{IntraOpNumThreadsEnvironment.ProcessorCount/2,GraphOptimizationLevelGraphOptimizationLevel.ORT_ENABLE_ALL,EnableMemPatterntrue};// 优先尝试 DirectML核显加速失败回退 CPUtry{opt.AppendExecutionProvider_DML(0);}catch{// 回退 CPU}sessionnewInferenceSession(yolov8n.onnx,opt);}privateasyncTaskProcessFrameAsync(){usingvarframenewMat();if(!cap.Read(frame))return;// 推理放在后台线程避免阻塞 UIvardetectionsawaitTask.Run(()Detect(frame));// UI 更新必须在主线程BeginInvoke((){usingvarannotatedDrawDetections(frame,detections);pictureBox1.Image?.Dispose();pictureBox1.Imageannotated.ToBitmap();lblStatus.Textdetections.Count0?$检测到{detections.Count}个目标:未检测到目标;});}/// summary/// YOLOv8 推理核心函数最简通用版/// /summaryprivateListDetectionDetect(Matframe){usingvarresizedframe.Resize(newSize(INPUT_SIZE,INPUT_SIZE));usingvarblobCv2.Dnn.BlobFromImage(resized,1f/255f,newSize(INPUT_SIZE,INPUT_SIZE),swapRB:true);vartensornewDenseTensorfloat(blob.GetDatafloat(),[1,3,INPUT_SIZE,INPUT_SIZE]);usingvarinputsnew[]{NamedOnnxValue.CreateFromTensor(images,tensor)};usingvarresultssession.Run(inputs);// YOLOv8 输出为 [1, 84, n] 或 [1, 4 num_classes, n] 格式varoutputresults[0].AsTensorfloat();returnPostProcess(output,frame.Width,frame.Height);}/// summary/// YOLOv8 后处理NMS 坐标还原/// /summaryprivateListDetectionPostProcess(Tensorfloatoutput,intorigW,intorigH){vardetectionsnewListDetection();introwsoutput.Dimensions[1];// 通常 84intcolsoutput.Dimensions[2];// 检测框数量for(inti0;icols;i){// 取置信度最高的那一类floatmaxConf0f;intbestClass-1;for(intc0;cclassNames.Length;c){floatconfoutput[0,4c,i];if(confmaxConf){maxConfconf;bestClassc;}}if(maxConf0.45f)continue;// 置信度阈值// 中心坐标 宽高floatcxoutput[0,0,i];floatcyoutput[0,1,i];floatwoutput[0,2,i];floathoutput[0,3,i];intx(int)((cx-w/2)*origW/INPUT_SIZE);inty(int)((cy-h/2)*origH/INPUT_SIZE);intwidth(int)(w*origW/INPUT_SIZE);intheight(int)(h*origH/INPUT_SIZE);detections.Add(newDetection(newRect(x,y,width,height),maxConf,classNames[bestClass]));}// NMS 非极大值抑制detectionsApplyNMS(detections,iouThreshold:0.45f);returndetections;}privatestaticListDetectionApplyNMS(ListDetectiondetections,floatiouThreshold){detections.Sort((a,b)b.Conf.CompareTo(a.Conf));varkeepnewListDetection();foreach(vardetindetections){boolsuppressedfalse;foreach(varkinkeep){if(IoU(det.Box,k.Box)iouThresholddet.Labelk.Label){suppressedtrue;break;}}if(!suppressed)keep.Add(det);}returnkeep;}privatestaticfloatIoU(Recta,Rectb){intinterXMath.Max(0,Math.Min(a.Right,b.Right)-Math.Max(a.Left,b.Left));intinterYMath.Max(0,Math.Min(a.Bottom,b.Bottom)-Math.Max(a.Top,b.Top));floatinterAreainterX*interY;floatunionAreaa.Width*a.Heightb.Width*b.Height-interArea;returninterArea/unionArea;}privateMatDrawDetections(Matframe,ListDetectiondetections){varimgframe.Clone();foreach(vardindetections){Cv2.Rectangle(img,d.Box,Scalar.Red,2);Cv2.PutText(img,${d.Label}{d.Conf:F2},newPoint(d.Box.X,d.Box.Y-10),HersheyFonts.HersheySimplex,0.7,Scalar.Red,2);}returnimg;}protectedoverridevoidOnFormClosing(FormClosingEventArgse){timer.Stop();cap?.Release();session?.Dispose();base.OnFormClosing(e);}}publicrecordDetection(RectBox,floatConf,stringLabel);}最关键的几点工业级写法说明为什么用 Task.Run 做推理ONNX Runtime 推理是 CPU/GPU 密集型任务如果放在 UI 线程会导致界面卡顿甚至无响应。必须异步执行。为什么用 BeginInvoke 更新 UIWinForms 的控件只能在创建它的线程UI 线程上操作跨线程直接赋值会抛 InvalidOperationException。为什么用 using 包裹 MatOpenCvSharp 的 Mat 是非托管资源不及时 Dispose 会导致内存泄漏长时间运行后程序崩溃。如何进一步提速工业现场常用招数把 INPUT_SIZE 从 640 降到 416 或 320速度提升 50–100%使用 int8 量化模型yolov8n_int8.onnx启用 DirectML核显加速opt.AppendExecutionProvider_DML(0)加跳帧逻辑每 2–3 帧只推理一次用计数器控制如何处理多相机每个相机开一个独立的 Task 独立的 InferenceSession避免锁竞争。快速验证步骤10 分钟跑通新建 WinForms 项目.NET 8安装 OpenCvSharp4 runtime把 yolov8n.onnx 放项目根目录复制上面代码到 Form1.cs运行 → 看到实时画面 检测框即成功如果想继续加功能直接告诉我我可以帮你补充多路摄像头分屏显示自定义类别 颜色映射检测到特定目标后写 PLC 寄存器截图保存 报警日志跳帧 内存优化版祝你快速跑通 YOLOv8 实时检测
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2512857.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!