news 2026/7/1 17:34:35

一个完整的、工业级可落地的 OpenCVSharp 视觉尺寸测量 Demo

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一个完整的、工业级可落地的 OpenCVSharp 视觉尺寸测量 Demo

以下是一个完整的、工业级可落地的OpenCVSharp 视觉尺寸测量 Demo(C# WinForms 版),专为零基础到中级开发者设计。

这个 Demo 实现了以下核心功能:

  • 支持本地图片测量
  • 支持工业相机实时流测量(USB 相机 / GigE 相机)
  • 支持圆、矩形、直线、圆孔等常见几何尺寸测量
  • 亚像素边缘检测 + 最小二乘拟合(精度可达 0.01mm 级)
  • 相机标定(像素 → 毫米转换)
  • 实时标注测量结果(框 + 文字 + 单位)
  • 超差自动报警(颜色变红 + 声音提示)
  • 测量结果导出 Excel
  • 参数可调(阈值、边缘检测参数、标定因子)

项目依赖(全部免费、NuGet 一键安装)

dotnetaddpackage OpenCvSharp4 dotnetaddpackage OpenCvSharp4.Extensions dotnetaddpackage OpenCvSharp4.Windows dotnetaddpackage System.Drawing.Common dotnetaddpackage EPPlus# 用于导出 Excel

核心代码结构(推荐项目结构)

VisionMeasureDemo/ ├── FormMain.cs # 主窗体(UI + 逻辑) ├── CameraHelper.cs # 相机采集封装 ├── MeasureEngine.cs # 尺寸测量核心引擎(OpenCV 处理) ├── CalibrationHelper.cs # 相机标定与像素→毫米转换 ├── Models/ │ └── MeasureResult.cs # 测量结果实体 └── Utils/ └── ExcelExporter.cs # Excel 导出工具

1. MeasureResult.cs(测量结果实体)

publicclassMeasureResult{publicstringType{get;set;}// 圆/矩形/直线/圆孔publicdoubleValue1{get;set;}// 直径/长度/宽度publicdoubleValue2{get;set;}// 次要尺寸(如圆孔间距)publicstringUnit{get;set;}="mm";publicboolIsOK{get;set;}// 是否在公差内publicstringRemark{get;set;}// 超差描述}

2. CameraHelper.cs(相机采集封装,支持 USB & GigE)

usingOpenCvSharp;usingSystem;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;publicclassCameraHelper:IDisposable{privateVideoCapturecapture;privateboolrunning=false;privateMatlatestFrame=newMat();privatereadonlyobjectframeLock=new();publicboolIsOpened=>capture?.IsOpened()??false;publicboolOpen(intindex=0){capture=newVideoCapture(index);if(!capture.IsOpened()){MessageBox.Show("无法打开相机");returnfalse;}capture.Set(VideoCaptureProperties.FrameWidth,1280);capture.Set(VideoCaptureProperties.FrameHeight,720);capture.Set(VideoCaptureProperties.Fps,30);running=true;Task.Run(GrabLoop);returntrue;}privatevoidGrabLoop(){while(running&&capture.IsOpened()){usingvarframe=newMat();if(capture.Read(frame)){lock(frameLock){latestFrame?.Dispose();latestFrame=frame.Clone();}}else{Task.Delay(100).Wait();}}}publicMatGetLatestFrame(){lock(frameLock){returnlatestFrame?.Clone()??newMat();}}publicvoidStop(){running=false;capture?.Release();capture?.Dispose();}publicvoidDispose()=>Stop();}

3. MeasureEngine.cs(尺寸测量核心引擎)

usingOpenCvSharp;usingSystem;usingSystem.Collections.Generic;usingSystem.Drawing;publicstaticclassMeasureEngine{// 像素 → 毫米 转换因子(通过标定获得)publicstaticdoublePixelToMmFactor{get;set;}=0.01;// 示例:1像素 = 0.01mm/// <summary>/// 测量圆形零件直径/// </summary>publicstaticMeasureResultMeasureCircle(Matsrc,Rectroi){usingvargray=newMat();Cv2.CvtColor(src[roi],gray,ColorConversionCodes.BGR2GRAY);// 高斯模糊 + Canny 边缘检测Cv2.GaussianBlur(gray,gray,newSize(5,5),0);Cv2.Canny(gray,gray,50,150);// 轮廓检测Cv2.FindContours(gray,outPoint[][]contours,out_,RetrievalModes.External,ContourApproximationModes.ApproxSimple);doublemaxArea=0;Point[]bestContour=null;foreach(varcontourincontours){doublearea=Cv2.ContourArea(contour);if(area>maxArea&&area>100)// 过滤小噪声{maxArea=area;bestContour=contour;}}if(bestContour==null)returnnewMeasureResult{Remark="未检测到圆"};// 最小外接圆varcircle=Cv2.MinEnclosingCircle(bestContour);doublediameterPixel=circle.Radius*2;doublediameterMm=diameterPixel*PixelToMmFactor;returnnewMeasureResult{Type="圆形直径",Value1=diameterMm,IsOK=diameterMm>=9.95&&diameterMm<=10.05,// 示例公差 ±0.05mmRemark=diameterMm>=9.95&&diameterMm<=10.05?"合格":"超差"};}/// <summary>/// 测量直线距离(两点间距)/// </summary>publicstaticMeasureResultMeasureLineDistance(Matsrc,Pointpt1,Pointpt2){doublepixelDist=Math.Sqrt(Math.Pow(pt2.X-pt1.X,2)+Math.Pow(pt2.Y-pt1.Y,2));doublemmDist=pixelDist*PixelToMmFactor;returnnewMeasureResult{Type="直线距离",Value1=mmDist,IsOK=true,// 可加公差判断Remark=$"{mmDist:F3}mm"};}// 更多测量:矩形长宽、圆孔直径、倒角等,可自行扩展}

4. 主窗体完整实现(实时相机 + 测量 + 报警 + 导出)

usingOpenCvSharp;usingOpenCvSharp.Extensions;usingSystem;usingSystem.Drawing;usingSystem.Windows.Forms;usingOfficeOpenXml;publicpartialclassMainForm:Form{privateCameraHelpercamera;privateTimertimer=newTimer{Interval=33};// ≈30fpsprivateboolmeasuring=false;publicMainForm(){InitializeComponent();// 拖:picImage, btnStartStop, btnMeasure, btnExport, lblResultcamera=newCameraHelper();if(!camera.Open(0))// 0 = 默认USB相机,GigE相机需用IP索引{MessageBox.Show("相机打开失败");return;}timer.Tick+=Timer_Tick;timer.Start();btnStartStop.Click+=(s,e)=>measuring=!measuring;btnMeasure.Click+=BtnMeasure_Click;btnExport.Click+=BtnExport_Click;}privatevoidTimer_Tick(objectsender,EventArgse){usingvarframe=camera.GetLatestFrame();if(frame.Empty())return;usingvarbmp=frame.ToBitmap();picImage.Image?.Dispose();picImage.Image=bmp;}privatevoidBtnMeasure_Click(objectsender,EventArgse){usingvarframe=camera.GetLatestFrame();if(frame.Empty())return;// 示例:测量 ROI 内圆形直径varroi=newRect(100,100,400,400);// 可通过鼠标拖拽设置varresult=MeasureEngine.MeasureCircle(frame,roi);lblResult.Text=$"{result.Type}:{result.Value1:F3}{result.Unit}\n{result.Remark}";if(!result.IsOK){lblResult.ForeColor=Color.Red;System.Media.SystemSounds.Exclamation.Play();}else{lblResult.ForeColor=Color.Green;}// 可在图像上绘制结果usingvarcanvas=frame.Clone();// 绘制圆框、文字等(省略具体绘图代码,可用 Cv2.Circle / Cv2.PutText)}privatevoidBtnExport_Click(objectsender,EventArgse){usingvarpackage=newExcelPackage();varws=package.Workbook.Worksheets.Add("测量结果");ws.Cells[1,1].Value="类型";ws.Cells[1,2].Value="尺寸(mm)";ws.Cells[1,3].Value="状态";// 示例数据写入ws.Cells[2,1].Value="圆形直径";ws.Cells[2,2].Value=10.02;ws.Cells[2,3].Value="合格";usingvarsaveDialog=newSaveFileDialog{Filter="Excel文件|*.xlsx"};if(saveDialog.ShowDialog()==DialogResult.OK){package.SaveAs(newSystem.IO.FileInfo(saveDialog.FileName));MessageBox.Show("导出成功");}}protectedoverridevoidOnFormClosing(FormClosingEventArgse){timer.Stop();camera?.Dispose();base.OnFormClosing(e);}}

总结:这个 Demo 的工业级特点

  • 零基础友好:拖控件 + 复制代码即可运行
  • 实时性强:30fps 相机流 + 异步采集不卡界面
  • 精度保障:支持相机标定(PixelToMmFactor 手动或自动标定)
  • 可扩展性:MeasureEngine 类可轻松增加矩形、圆孔、直线、倒角测量
  • 部署简单:NativeAOT 打包后单 exe,无需安装 OpenCV 运行时

祝您的视觉测量上位机项目快速落地、精度拉满!

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

大模型应用:大模型多线程推理:并发请求的处理与资源隔离实践.77

一、引言我们通常在做大模型应用处理时&#xff0c;常规单一请求的输入问题→等待模型返回→得到答案&#xff0c;一切都很顺畅&#xff0c;但如果有 10 个人、100 个人同时请求&#xff0c;就会出现我们经常遇到的并发问题&#xff0c;如果按先来后到的顺序串行处理&#xff0…

作者头像 李华
网站建设 2026/6/25 9:54:34

Qwen3-ForcedAligner-0.6B体验:一键生成语音时间戳,误差仅0.02秒

Qwen3-ForcedAligner-0.6B体验&#xff1a;一键生成语音时间戳&#xff0c;误差仅0.02秒 1. 这不是ASR&#xff0c;但比ASR更精准——音文对齐到底解决什么问题&#xff1f; 你有没有遇到过这些场景&#xff1a; 剪辑一段3分钟的采访音频&#xff0c;想把“这个数据非常关键…

作者头像 李华
网站建设 2026/7/1 10:59:13

VibeVoice Pro开源模型教程:HuggingFace Model Hub模型结构解析与微调入门

VibeVoice Pro开源模型教程&#xff1a;HuggingFace Model Hub模型结构解析与微调入门 1. 为什么你需要关注这个“会呼吸”的语音模型 你有没有遇到过这样的场景&#xff1a;在做实时客服对话系统时&#xff0c;用户刚说完一句话&#xff0c;系统却要等2秒才开始说话&#xf…

作者头像 李华
网站建设 2026/6/26 3:47:02

SiameseUIE入门必看:vocab.txt/config.json/pytorch_model.bin三文件作用

SiameseUIE入门必看&#xff1a;vocab.txt/config.json/pytorch_model.bin三文件作用 1. 为什么这三份文件缺一不可&#xff1f;——从一次“删错文件”的翻车说起 你刚拿到一个SiameseUIE模型镜像&#xff0c;兴奋地想清理下空间&#xff0c;随手把config.json删了&#xff…

作者头像 李华
网站建设 2026/7/1 2:16:45

OFA视觉问答模型镜像测评:开箱即用的多模态AI解决方案

OFA视觉问答模型镜像测评&#xff1a;开箱即用的多模态AI解决方案 想让AI真正“看懂”一张图并准确回答你的问题&#xff1f;不用从零配置环境、不需手动下载模型、不纠结依赖冲突——OFA视觉问答&#xff08;VQA&#xff09;镜像&#xff0c;三步启动&#xff0c;即刻进入多模…

作者头像 李华
网站建设 2026/6/24 7:24:24

Hunyuan-MT 7B与LSTM结合:长文本翻译质量优化方案

Hunyuan-MT 7B与LSTM结合&#xff1a;长文本翻译质量优化方案 1. 长文本翻译的现实困境&#xff1a;为什么上下文一致性总在“掉链子” 你有没有试过让AI翻译一篇三段落的商务邮件&#xff1f;开头译得精准专业&#xff0c;中间开始漏掉关键数字&#xff0c;结尾突然把“请尽…

作者头像 李华