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

OpencvSharp 算子学习教案之 - Cv2.GetStructuringElement 重载1

OpencvSharp 算子学习教案之 - Cv2.GetStructuringElement 重载1

大家好,Opencv在很多工程项目中都会用到,而OpencvSharp则是以C#开发与实现的Opencv操作库,对.NET开发人员友好,但很多API的中文资料、应用场景及常见坑点等缺乏系统性归纳,因此这系列博客将给大家带来Cv2及Mat对象全系列算子学习教案,供大家参考学习。

Cv2.GetStructuringElement

  • 教案版本:V1.0
  • 面向对象:OpenCvSharp 初学者
  • 所属模块:imgproc
  • 源码位置:OpenCvSharp/Cv2/Cv2_imgproc.cs:96

摘要:GetStructuringElement 会生成用于腐蚀、膨胀和形态学变换的结构元素。本文用 Rect、Cross、Ellipse 三种形状对比,帮助初学者先看懂 shape 和 ksize 如何决定矩阵外形,再把这个概念和后续的形态学运算联系起来。

1. 函数名称(带参数签名)

publicstaticMatGetStructuringElement(MorphShapesshape,Sizeksize)

2. 函数用途

Cv2.GetStructuringElement的作用,是生成一个结构元素矩阵。

这个函数最常见的用途有:

  1. 作为erode的 kernel。
  2. 作为dilate的 kernel。
  3. 作为morphologyEx的 kernel。
  4. 在教学中直观观察不同形状的邻域支持范围。

它返回的不是图像处理结果,而是一个会参与后续形态学运算的二值矩阵。

3. 函数公式

结构元素可以理解成一个二值支持矩阵:

K(x,y)={1,如果位置属于所选形状0,如果位置不属于所选形状 K(x, y) = \begin{cases} 1, & \text{如果位置属于所选形状} \\ 0, & \text{如果位置不属于所选形状} \end{cases}K(x,y)={1,0,如果位置属于所选形状如果位置不属于所选形状

在后续的腐蚀和膨胀里,OpenCV 会根据这个矩阵里非零元素的位置来决定参与计算的邻域。

4. 函数原理说明

这个函数会根据shapeksize生成一个矩阵。

  1. shape决定结构元素的轮廓。
  2. ksize决定结构元素占多大范围。
  3. 返回值通常是单通道矩阵,便于直接传给形态学函数。
  4. 如果后续做腐蚀或膨胀,这个矩阵就会变成真正的运算邻域。

在 OpenCvSharp 里,MorphShapes.RectMorphShapes.CrossMorphShapes.Ellipse是当前最常用的三种形状。

5. 参数含义解析

参数名类型必填含义
shapeMorphShapes结构元素形状
ksizeSize结构元素大小,宽和高都应为正数

补充说明:

  1. Rect是最基础的矩形结构元素。
  2. Cross适合看清横竖支撑点。
  3. Ellipse更接近圆形邻域。
  4. 返回值可以直接传给erodedilatemorphologyEx

6. 应用场景列表

场景名场景说明典型用途
场景A:基础结构元素观察三种 shape 的矩阵差异形态学入门
场景B:腐蚀运算准备先生成 kernel 再做 erode去噪和缩小目标
场景C:膨胀运算准备先生成 kernel 再做 dilate填补小孔和连接断裂
场景D:教学对比让初学者看懂邻域形状初学者入门

7. 函数使用示例

下面的 Console 程序演示Cv2.GetStructuringElement(MorphShapes shape, Size ksize)。示例会把 Rect、Cross、Ellipse 三种结构元素打印出来,并计算每个矩阵里有多少个非零元素。

usingSystem;usingSystem.Text;usingOpenCvSharp;internalstaticclassProgram{privatereadonlyrecordstructKernelCase(stringLabel,MorphShapesShape,SizeKSize,stringComment);privatestaticreadonlyKernelCase[]Cases={new("Rect 矩形核",MorphShapes.Rect,newSize(5,5),"最基础的矩形结构元素,适合先理解形态学邻域。"),new("Cross 十字核",MorphShapes.Cross,newSize(5,5),"只保留横竖方向的支撑点。"),new("Ellipse 椭圆核",MorphShapes.Ellipse,newSize(5,5),"更接近圆形邻域。"),};/// <summary>/// 程序入口。/// </summary>privatestaticvoidMain(){// 先把控制台编码切成 UTF-8,避免中文说明出现乱码。Console.OutputEncoding=Encoding.UTF8;// 运行演示,观察不同 shape 和 ksize 对结构元素矩阵的影响。RunDemo();}/// <summary>/// 演示结构元素的生成结果。/// </summary>privatestaticvoidRunDemo(){Console.WriteLine("场景A:GetStructuringElement(MorphShapes shape, Size ksize)");Console.WriteLine("GetStructuringElement 会返回一个可直接用于形态学运算的矩阵。\n");foreach(variteminCases){// 这里直接用 OpenCV 生成结构元素,然后把矩阵按 0/1 打印出来。usingvarkernel=Cv2.GetStructuringElement(item.Shape,item.KSize);Console.WriteLine($"[{item.Label}] shape={item.Shape}, ksize={item.KSize.Width}x{item.KSize.Height}");Console.WriteLine(item.Comment);Console.WriteLine($"非零元素数量:{Cv2.CountNonZero(kernel)}");Console.WriteLine(FormatKernel(kernel));Console.WriteLine();}Console.WriteLine("教学结论:shape 决定矩阵轮廓,ksize 决定矩阵范围。这个矩阵会被后续腐蚀和膨胀直接使用。\n");}/// <summary>/// 把结构元素矩阵格式化成易读文本。/// </summary>/// <param name="kernel">结构元素矩阵。</param>/// <returns>矩阵文本。</returns>privatestaticstringFormatKernel(Matkernel){varsb=newStringBuilder();for(varrow=0;row<kernel.Rows;row++){sb.Append("[");for(varcol=0;col<kernel.Cols;col++){sb.Append(kernel.At<byte>(row,col));if(col<kernel.Cols-1){sb.Append(", ");}}sb.AppendLine("]");}returnsb.ToString();}}

8. 注意事项

  1. ksize应该是正数尺寸。
  2. shape只建议使用RectCrossEllipse这三种常用枚举值。
  3. 返回值是结构元素,不是最终图像处理结果。
  4. 后续腐蚀和膨胀时,这个矩阵会决定邻域的形状。

9. 调优建议

  1. 先用Rect看懂结构元素是什么,再看CrossEllipse
  2. 如果你只是入门形态学,先从5x5这种短核开始。
  3. 想保留更多细节时,可以把结构元素做得小一些。
  4. 想让形态学效果更强时,可以逐步增大ksize

10. 运行说明

  1. 如果你在控制台工程里运行本文示例,直接把代码放进Program.cs即可。
  2. 如果你在本仓库里学习,请打开 WPF 控件Cv2.GetStructuringElement,切换到“场景A”,点击按钮后查看右侧文本框和预览图。
  3. WPF 示例会把三种结构元素放在一起对比,适合初学者建立直觉。

11. 常见错误排查

  1. ksize写成 0 或负数。
  2. 误以为返回值是滤波后的图像,而不是结构元素矩阵。
  3. 不知道RectCrossEllipse的差别。
  4. 生成了 kernel 却忘了把它传给erodedilatemorphologyEx
http://www.jsqmd.com/news/767815/

相关文章:

  • STM32F103C8T6硬件SPI驱动W25Q64 Flash全流程(附完整工程代码)
  • C#基础(持续更新中)
  • Python初学者项目练习9--对简单列表元素排序
  • 解决ZYNQ裸机网络扩展难题:为LWIP库添加自定义PHY驱动与SDK配置界面
  • Windows系统光标深度替换:INF方案实现macOS指针移植与优化
  • AI编码助手统一配置工具agent-dotfiles:告别重复配置,实现规则与技能一键同步
  • BrowserClaw:基于Puppeteer与Playwright的浏览器自动化与数据抓取实践
  • AI工具搭建自动化视频生成图像缩放
  • ChatGPT文档格式化指令:打造Google Docs无缝协作的AI写作规范
  • GRADFILTERING:基于梯度信噪比的指令调优数据筛选方法
  • 别再死记硬背async/await了!用Playwright+Python写自动化脚本,这3个坑我帮你踩过了
  • 千问 LeetCode 2127.参加会议的最多员工数 public int maximumInvitations(int[] favorite)
  • 解释器模式是行为型设计模式的一种,其核心思想是给定一个语言,定义它的文法的一种表示
  • STM32G431RBT6的HAL库避坑指南:蓝桥杯嵌入式那些CubeMX没告诉你的细节
  • 构建本地化音视频转录分析平台:Whisper+Ollama+Meilisearch实战
  • SolidGPT实战指南:基于语义搜索的代码与文档智能问答系统
  • 避坑指南:SAP固定资产配置里,记账码70和31千万别乱选!附SPRO完整路径
  • 想在Win10任务栏显示秒数?试试用StartAllBack配合注册表修改(附详细步骤)
  • 【Redis】Redis——过期键删除策略、内存淘汰8种策略、LRU/LFU实现
  • 秒级推演赋能复杂场景,镜像视界夯实工业数字根基
  • SpringBoot + Thymeleaf 实战:手把手教你从零搭建一个婚纱租赁网站(附完整源码)
  • PageIndex:基于RAG的网页智能知识库构建实战指南
  • HoRain云--超全PHP安装指南:Linux/Windows/macOS全攻略
  • MQTTX与AI助手实时交互:基于MCP与SSE的物联网协议桥接实践
  • 基于Dev Containers的标准化开发环境构建与实战指南
  • STM32定时器OPM单脉冲模式实战:从驱动蜂鸣器到生成精准PWM脉冲(以TIM4为例)
  • synchronized内存布局图(bit 精确位置)
  • Promptr:用自然语言指令自动化重构代码的AI工具实践指南
  • 在github上快速部署taotoken的python调用示例
  • 千问 LeetCode 2127.参加会议的最多员工数 Python3实现