news 2026/5/10 6:18:00

C# WinForms 多摄像头分屏显示 的完整工业级实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C# WinForms 多摄像头分屏显示 的完整工业级实现

以下是C# WinForms 多摄像头分屏显示的完整工业级实现(2025 年最实用写法),专为工控机/上位机场景设计。

支持特点:

  • 动态添加任意路数摄像头(USB / RTSP / 工业相机)
  • 网格自动布局(1×1 → 2×2 → 3×3 → 4×4 自适应)
  • 每个画面独立采集 + 独立线程(互不干扰)
  • 全局限流(防止低配机 CPU/内存爆炸)
  • 异常隔离(一路掉线不影响其他路)
  • 画面自适应缩放 + 实时 FPS 显示
  • 支持暂停/恢复、切换分辨率

核心类:MultiCameraPanelManager

usingOpenCvSharp;usingSystem;usingSystem.Collections.Generic;usingSystem.Drawing;usingSystem.Threading;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;publicclassMultiCameraPanelManager:IDisposable{privatereadonlyPanel_containerPanel;privatereadonlyList<CameraDisplay>_cameras=new();privatereadonlySemaphoreSlim_semaphore;// 全局并发限流privatereadonlyCancellationTokenSource_cts=new();publicMultiCameraPanelManager(PanelcontainerPanel,intmaxConcurrent=4){_containerPanel=containerPanel;_semaphore=newSemaphoreSlim(maxConcurrent,maxConcurrent);}/// <summary>/// 添加一路摄像头/// </summary>/// <param name="source">0=USB, 1=USB2, 或 "rtsp://..."</param>/// <param name="title">显示标题(可选)</param>publicvoidAddCamera(stringsource,stringtitle=null){vardisplay=newCameraDisplay(source,title);_cameras.Add(display);// 动态创建 PictureBoxvarpb=newPictureBox{SizeMode=PictureBoxSizeMode.Zoom,BorderStyle=BorderStyle.FixedSingle,BackColor=Color.Black,Dock=DockStyle.Fill};varlabel=newLabel{Text=title??$"Camera{_cameras.Count}",ForeColor=Color.White,BackColor=Color.FromArgb(120,0,0,0),Dock=DockStyle.Bottom,TextAlign=ContentAlignment.MiddleCenter,AutoSize=false,Height=25};varpanel=newPanel{Dock=DockStyle.Fill};panel.Controls.Add(pb);panel.Controls.Add(label);// 异步采集线程_=Task.Run(()=>CaptureLoopAsync(display,pb,label));// 动态布局ReLayoutCameras();}privateasyncTaskCaptureLoopAsync(CameraDisplaycam,PictureBoxpb,Labellbl){while(!_cts.IsCancellationRequested){await_semaphore.WaitAsync(_cts.Token);try{usingvarframe=newMat();if(!cam.Cap.Read(frame)||frame.Empty()){awaitTask.Delay(100);continue;}// 可在此处添加 YOLO 检测或其他处理// var detections = yolo.Detect(frame);varbitmap=frame.ToBitmap();InvokeIfNeeded(()=>{pb.Image?.Dispose();pb.Image=bitmap;lbl.Text=$"{cam.Title}-{cam.Fps:F1}fps";});}catch(Exceptionex){InvokeIfNeeded(()=>lbl.Text=$"错误:{ex.Message}");}finally{_semaphore.Release();}awaitTask.Delay(33);// 约30fps}}privatevoidReLayoutCameras(){_containerPanel.SuspendLayout();_containerPanel.Controls.Clear();intcount=_cameras.Count;intcols=(int)Math.Ceiling(Math.Sqrt(count));introws=(int)Math.Ceiling((double)count/cols);_containerPanel.RowCount=rows;_containerPanel.ColumnCount=cols;for(inti=0;i<count;i++){introw=i/cols;intcol=i%cols;varpanel=newPanel{Dock=DockStyle.Fill};panel.BackColor=Color.Black;varpb=newPictureBox{Dock=DockStyle.Fill,SizeMode=PictureBoxSizeMode.Zoom,BackColor=Color.Black};varlbl=newLabel{Dock=DockStyle.Bottom,Height=25,TextAlign=ContentAlignment.MiddleCenter,ForeColor=Color.White,BackColor=Color.FromArgb(120,0,0,0),Text=$"Cam{i+1}"};panel.Controls.Add(pb);panel.Controls.Add(lbl);_containerPanel.Controls.Add(panel,col,row);}_containerPanel.ResumeLayout();}privatevoidInvokeIfNeeded(Actionaction){if(_containerPanel.InvokeRequired)_containerPanel.Invoke(action);elseaction();}publicvoidDispose(){_cts.Cancel();_semaphore.Dispose();foreach(varcamin_cameras)cam.Cap?.Release();}privateclassCameraDisplay{publicVideoCaptureCap{get;}publicstringTitle{get;}publicdoubleFps{get;privateset;}privateDateTime_lastFrameTime=DateTime.Now;publicCameraDisplay(stringsource,stringtitle){Cap=source.StartsWith("rtsp")?newVideoCapture(source):newVideoCapture(int.Parse(source),VideoCaptureAPIs.DSHOW);Title=title??$"Camera{source}";}publicvoidUpdateFps(){varnow=DateTime.Now;Fps=1000.0/(now-_lastFrameTime).TotalMilliseconds;_lastFrameTime=now;}}}

使用方式(在主窗体中)

publicpartialclassMainForm:Form{privateMultiCameraPanelManager_manager;publicMainForm(){InitializeComponent();_manager=newMultiCameraPanelManager(panelContainer,maxConcurrent:4);// 添加摄像头(可动态添加)_manager.AddCamera("0","正面机位");_manager.AddCamera("1","侧面机位");_manager.AddCamera("rtsp://admin:12345@192.168.1.100:554/stream1","远端监控");}protectedoverridevoidOnFormClosing(FormClosingEventArgse){_manager?.Dispose();base.OnFormClosing(e);}}

关键工业级优化说明

优化点实现方式效果
并发控制SemaphoreSlim(3,3) ~ (6,6)4核机稳定4–6路
画面不卡每个采集独立 Task + BeginInvoke 更新UI 线程始终响应
内存泄漏所有 Mat 用 using + Dispose Bitmap长期运行内存稳定
一路掉线不影响其他每个相机 Task 独立 try-catch容错性极高
低配机友好maxConcurrent=2 + 延时 50msCPU 占用 < 70%
动态路数ReLayoutCameras() 自动网格布局支持随时增减摄像头

快速扩展方向(可直接说要哪一个)

  • 每个画面叠加 YOLO 检测框
  • 异常区域高亮 + 报警联动
  • 画面录制 + 异常片段保存
  • 自定义分辨率 / 帧率切换
  • 支持 ONVIF 自动发现摄像头
  • Linux / Jetson 跨平台适配

祝你的多路监控系统稳定流畅!有任何需求直接告诉我,我继续帮你完善。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/19 10:52:53

【Scala PyTorch深度学习】PyTorch On Scala 系列课程 第四章 08 :神经网络【AI Infra 3.0】[PyTorch Scala 硕士研一课程]

PyTorch Scala 高校计算机 硕士研一课程 章节 4: 使用 torch.nn 搭建模型 在熟悉了PyTorch张量和用于梯度计算的Autograd系统后&#xff0c;我们现在开始构建神经网络本身。本章主要介绍torch.nn包&#xff0c;它是PyTorch用于高效构建网络结构的专用库。 你将学习如何使用核心…

作者头像 李华
网站建设 2026/4/22 1:57:38

LLM工程化实践——大模型部署与推理框架vLLM

vLLM&#xff1a;大语言模型推理与服务库vLLM 是由加州大学伯克利分校天空计算实验室最初研发、现由学术界和工业界共同贡献的社区驱动型大语言模型推理与服务库&#xff0c;核心定位为简单、高速、低成本的 LLM 服务工具&#xff0c;其核心特性围绕极致的推理性能和高度的灵活…

作者头像 李华
网站建设 2026/4/17 23:54:31

MP4视频修复终极指南:5分钟快速拯救损坏视频文件的完整方案

MP4视频修复终极指南&#xff1a;5分钟快速拯救损坏视频文件的完整方案 【免费下载链接】untrunc Restore a truncated mp4/mov. Improved version of ponchio/untrunc 项目地址: https://gitcode.com/gh_mirrors/un/untrunc 你是否曾因为相机突然断电、存储卡故障或文件…

作者头像 李华
网站建设 2026/4/17 18:20:48

3大实战场景:dnSpyEx .NET逆向调试与编辑的完整指南

3大实战场景&#xff1a;dnSpyEx .NET逆向调试与编辑的完整指南 【免费下载链接】dnSpy Unofficial revival of the well known .NET debugger and assembly editor, dnSpy 项目地址: https://gitcode.com/gh_mirrors/dns/dnSpy dnSpyEx是一款功能强大的.NET逆向工具&am…

作者头像 李华
网站建设 2026/4/18 0:52:44

【Claude Code 源码解析教程】总体大纲

教程概述本教程旨在深入解析 Anthropic Claude Code 项目的源码架构和实现细节。Claude Code 是一个基于 TypeScript Bun 构建的 AI 编程助手 CLI 工具&#xff0c;代号 "Tengu"&#xff0c;具有复杂的多模块架构和丰富的功能特性。教程目标读者&#xff1a;对 AI 编…

作者头像 李华