夜雨聆风学习资料网

ARTICLE · 1231169

机器视觉工程师软件开发入门04- C#OpenCVSharp形态学案例

机器视觉工程师软件开发入门04- C#OpenCVSharp形态学案例
还是之前03的代码,只是添加了新的知识。
using System;using OpenCvSharp;namespace VisionDay3{    internal class Program    {        staticvoidMain(string[] args)        {            string inputPath = @"Z:\JD\test.jpg";            string outputPath = @"Z:\JD\test_output.jpg";            // 1. 读图            Mat src = Cv2.ImRead(inputPath, ImreadModes.Color);            if (src.Empty())            {                Console.WriteLine("图片读取失败,请检查路径!");                Console.ReadLine(); // 防止黑窗口一闪而过                return; // 必须加上这句,否则后面会崩溃            }            // 2. 转灰度            Mat gray = new Mat();            Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);            // 3. 二值化            Mat binary = new Mat();            Cv2.Threshold(gray, binary, 127, 255, ThresholdTypes.Binary);            Cv2.ImWrite(outputPath, binary); // 保存原始二值图            byte pixelValue = binary.At<byte>(10, 10);            Console.WriteLine("二值化后的像素值: " + pixelValue);            // 4. 形态学开运算(去噪点)            Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3));            Mat clean_binary = new Mat();            Cv2.MorphologyEx(binary, clean_binary, MorphTypes.Open, kernel);            Cv2.ImWrite(@"Z:\JD\test_clean.jpg", clean_binary); // 保存去噪后的二值图            // 5. 在去噪后的图上找轮廓            Point[][] contours;            HierarchyIndex[] hierarchy;            Cv2.FindContours(clean_binary, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple);            // 6. 把轮廓画在原图上            Mat result = src.Clone();            Cv2.DrawContours(result, contours, -1, Scalar.Green, 3);            Cv2.ImWrite(@"Z:\JD\test_contours.jpg", result); // 保存带框的图            Console.WriteLine($"轮廓检测完成,结果 {contours.Length} 个轮廓");            Console.ReadLine();        }    }}

 形态学开运算

Cv2.MorphologyEx(binary, clean_binary, MorphTypes.Open, kernel);
开运算的作用:开运算 = 先腐蚀后膨胀。它的主要作用是消除细小的白色噪点,同时保持大物体的面积不变。这在工业视觉中非常常用,比如去除金属反光造成的孤立白点。

形态学本质上是用一个小“探针”在图像上滑动,根据形状关系修改像素。
它不直接改颜色,而是改结构:哪些白点该留、哪些该删、哪些断线该连起来。

核心:结构元素 Kernel

Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3));

核越大,作用越强;核越小,影响越局部。

两个基础操作:腐蚀和膨胀

腐蚀 Erosion:让白色区域“变瘦”

只有当 kernel 完全落在白色区域内时,中心点才保留为白色。
效果:

  • 去掉孤立小白点
  • 削弱毛刺
  • 分离粘连物体
  • 但物体会变小

膨胀 Dilate:让白色区域“变胖”

只要 kernel 碰到任意白色像素,中心点就变成白色。
效果:

  • 填充小黑洞
  • 连接断裂区域
  • 加粗轮廓
  • 但可能把噪声也放大

它们互为对偶操作。

组合操作:开运算和闭运算

单独腐蚀或膨胀容易把物体本身也破坏掉,所以工程里更多用组合。

开运算 Open = 先腐蚀,后膨胀

Cv2.MorphologyEx(binary, clean_binary, MorphTypes.Open, kernel);

作用:

  • 去除比 kernel 更小的白色噪点
  • 平滑外轮廓
  • 基本不改变大物体尺寸

你这段代码里用它,就是在二值图上去掉细小白点,让后续 FindContours 更干净。

闭运算 Close = 先膨胀,后腐蚀

作用:

  • 填充物体内部小黑洞
  • 连接断裂轮廓
  • 修复阈值分割后产生的缺口

比如零件边缘因为反光断了一小段,闭运算可以把它连起来。

其他常用形态学操作

操作
计算方式
用途
形态学梯度
膨胀 − 腐蚀
提取边缘轮廓
顶帽 Top-hat
原图 − 开运算
突出比背景亮的小细节
黑帽 Black-hat
闭运算 − 原图
突出比背景暗的凹陷/划痕

工业视觉里怎么用

形态学通常放在 二值化之后、轮廓提取之前:

  1. 灰度化
  2. 去噪/增强
  3. 二值化
  4. 形态学清理
  5. 找轮廓 / 测尺寸 / 判缺陷

比如 PCB 检测里,开运算可以滤掉焊锡飞溅的小白点;闭运算可以补全断裂走线;顶帽可以增强反光焊点;黑帽可以凸显划痕。

调参建议

  • 先去噪:先用 开运算 去掉小白点。
  • 再补洞:如果物体内部有黑缝,再用 闭运算。
  • Kernel 尽量小:从 3×3、5×5 开始试,太大容易把真实特征吃掉。
  • 不要盲目多次迭代:迭代次数越多,物体变形越明显。
  • 形态学不能替代好光照和好阈值:如果二值图本身已经糊了,形态学只能补救,不能根治。

以下是项目参考图和效果

csharp

                               test-原图

编

相关学习资料