当前位置: 首页 > news >正文

C#编程下的自定义控件与OpenCVSharp结合应用:卡尺测距功能实现

C# 自定义控件 opencvsharp 卡尺测距

最近在工业检测项目里折腾卡尺测距功能,用C#搞了个带图像分析的控件。这玩意儿核心就三件事:自定义控件画界面、OpenCvSharp处理图像、像素转实际尺寸。咱们直接上干货。

先撸个控件框架,继承UserControl太笨重,直接继承Control更灵活:

public class CaliperControl : Control { private Mat _sourceImage; protected override void OnPaint(PaintEventArgs e) { // 这里画标尺线和测量结果 using var pen = new Pen(Color.Cyan, 2); e.Graphics.DrawLine(pen, startPoint, endPoint); } }

重点在图像处理部分。用OpenCvSharp读取标定板图像,先做边缘强化:

using (var src = Cv2.ImRead("caliper.jpg", ImreadModes.Grayscale)) { var edges = new Mat(); Cv2.Canny(src, edges, 50, 200); // 参数别照搬,根据实际调整 FindMeasurementPoints(edges); }

找测量点时得注意,工业场景里经常遇到反光干扰。我一般用ROI区域约束+亚像素级检测:

private void FindEdges(Mat edges) { using var roi = new Mat(edges, new Rect(100, 50, 300, 400)); // 限定检测区域 var lineSegment = Cv2.HoughLinesP(roi, 1, Math.PI / 180, 50); // 亚像素级角点修正 var corners = new Mat(); Cv2.CornerSubPix(roi, corners, new Size(3,3), new Size(-1,-1), new TermCriteria(CriteriaType.Epsilon | CriteriaType.MaxIter, 30, 0.1)); }

测距算法最怕像素抖动。我的土办法是取连续20帧做移动平均:

private Queue<float> _distanceBuffer = new Queue<float>(20); public float StableDistance => _distanceBuffer.Average(); void UpdateDistance(float newVal) { if(_distanceBuffer.Count >= 20) _distanceBuffer.Dequeue(); _distanceBuffer.Enqueue(newVal); Invalidate(); // 触发重绘 }

像素转实际尺寸的玄学环节来了。标定板千万别用A4纸打印,热胀冷缩坑死人。建议用带温度补偿的陶瓷标定板,代码里要处理非线性畸变:

// 标定参数建议存json var calibration = JsonConvert.DeserializeObject<CalibData>(File.ReadAllText("calib.json")); // 带畸变校正的坐标转换 Point2f PixelToWorld(Point2f pixel) { var undistorted = calibration.CameraMatrix * pixel; return new Point2f( undistorted.X * calibration.PixelRatio + calibration.OffsetX, undistorted.Y * calibration.PixelRatio + calibration.OffsetY ); }

最后给控件加点交互才像样。按住Alt滚轮调整标尺线位置,右键菜单导出数据:

protected override void OnMouseWheel(MouseEventArgs e) { if (Control.ModifierKeys == Keys.Alt) { _measurementLine += e.Delta > 0 ? 1 : -1; Invalidate(); } base.OnMouseWheel(e); }

实测在1080p图像下,这套方案能稳定做到±0.05mm精度。注意OpenCvSharp比较吃内存,处理大图时记得用Using语句及时释放Mat对象。遇到卡顿时试试Nvidia的CUDA加速,不过那又是另一个坑了。

http://www.cnnetsun.cn/news/158567.html

相关文章:

  • NGBoost-shap方法回归任务,由斯坦福吴恩达团队提出,属于集成模型的一种2019年提出的
  • Langchain-Chatchat Kubernetes集群部署策略
  • Langchain-Chatchat日志监控与性能分析最佳实践
  • Langchain-Chatchat模型微调指南:适配垂直领域任务
  • 如何配置IPv6静态路由?解决企业网络难题
  • 【Linux网络基础】详解 TCP 面向连接 vs UDP 无连接
  • Langchain-Chatchat如何评估问答质量?指标体系构建
  • springboot在线教育系统(11528)
  • 测了多款AI自动生成PPT工具,真正能用的不到一半
  • springboot星之语明星周边产品销售网站的设计与实现(11529)
  • 毕设救星:Spring Boot + Neo4j 打造“医疗知识问答”——基于知识图谱的智能导诊平台
  • 华为网络设备基本配置命令
  • 志同道合交友网站毕业论文+PPT(附源代码+演示视频)
  • 【Java 25 LTS六大核心特性】
  • Langchain-Chatchat助力医疗文档智能检索与问答
  • Langchain-Chatchat如何实现文档相似度比对?查重与去重依据
  • java学习--String和StringBuffer互转
  • 如何用Langchain-Chatchat实现本地化AI智能问答?
  • Langchain-Chatchat如何处理多义词歧义?上下文感知消歧算法
  • Langchain-Chatchat如何实现文档访问统计?了解知识使用情况
  • Langchain-Chatchat与Argo CD持续交付集成:自动化部署流水线
  • Langchain-Chatchat与Consul服务发现集成:动态节点管理
  • Langchain-Chatchat与Airflow工作流集成:复杂ETL流程调度
  • 验证码实现
  • 2.1 CPU脚本性能优化简介
  • Langchain-Chatchat问答系统压测报告:万级QPS承载能力验证
  • Langchain-Chatchat支持自定义元数据字段:扩展文档属性信息
  • 双侧独立电驱动车辆转向控制:Matlab/Simulink建模之旅
  • 500kW三相光伏并网逆变器仿真模型探索
  • 基于Optislang的电机多目标优化:以电机气息磁通密度空间某一阶次为优化目标教程