C# + OpenCV 基础 图片形态学计算

148 阅读5分钟

前言

在计算机视觉领域,形态学计算是一种强大的工具,用于处理和分析图像。通过形态学操作,可以提取图像的基本结构特征,如边界、骨架、连通分量等,从而为后续的图像处理任务奠定基础。

本文将介绍如何使用 C# 结合 OpenCVSharp 库进行基本的形态学计算。形态学计算主要包括膨胀(Dilation)、腐蚀(Erosion)、开运算(Opening)、闭运算(Closing)等操作。这些操作不仅可以帮助我们去除噪声、填补孔洞,还能增强图像中的特定特征。

通过本文的学习,掌握如何利用这些技术提升图像处理的效果,并应用到实际项目中。

正文

1、膨胀

膨胀操作则会扩展图像中的前景区域,通常用于连接相邻的目标或填补孔洞。

其原理与腐蚀类似,但作用相反。

/// <summary>
/// 膨胀
/// </summary>
/// <param name="mat">图片</param>
/// <param name="element">用于膨胀的结构内核;如果element=new Mat(),则使用3x3矩形结构化元素</param>
/// <param name="anchor">锚在元素中的位置。默认值(-1,-1)表示锚点位于元素中心</param>
/// <param name="iterations">应用膨胀的次数。[默认情况下为1]</param>
/// <param name="borderType">边缘像素的外推类型</param>
/// <param name="borderValue">在边缘为常量的情况下的边缘值</param>
/// <returns></returns>
public static Mat Dilate(Mat mat, InputArray? element, Point? anchor = null, int iterations = 1,
    BorderTypes borderType = BorderTypes.Constant, Scalar? borderValue = null)
{
    Mat dstMet = new Mat();

    // var element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(1, 1));
    // 膨胀Cv2.Dilate
    Cv2.Dilate(mat, dstMet, element, anchor, iterations, borderType, borderValue);
    return dstMet;
}

2、腐蚀

腐蚀操作会收缩图像中的前景区域(白色部分),通常用于去除小的噪声点或细化目标区域。

其原理是基于一个结构元素(Structuring Element),逐像素地扫描图像并根据结构元素的形状和大小对图像进行处理。

/// <summary>
/// 腐蚀
/// </summary>
/// <param name="mat">图片</param>
/// <param name="element">用于侵蚀的结构内核;如果element=new Mat(),则使用3x3矩形结构化元素</param>
/// <param name="anchor">锚在元素中的位置。默认值(-1,-1)表示锚点位于元素中心</param>
/// <param name="iterations">应用侵蚀的次数。[默认情况下为1]</param>
/// <param name="borderType">边缘像素的外推类型</param>
/// <param name="borderValue">在边缘为常量的情况下的边缘值</param>
/// <returns></returns>
public static Mat Erode(Mat mat, InputArray? element, Point? anchor = null, int iterations = 1,
    BorderTypes borderType = BorderTypes.Constant, Scalar? borderValue = null)
{
    Mat dstMet = new Mat();

    // var element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(1, 1));
    // 腐蚀Cv2.Erode
    Cv2.Erode(mat, dstMet, element, anchor, iterations, borderType, borderValue);
    return dstMet;
}

3、形态学运算

开运算:先腐蚀后膨胀,可清除小白点;图片会非常模糊;

闭运算:先膨胀后腐蚀,可清除小黑点;图片会非常模糊;

形态学梯度:膨胀图与腐蚀图之差,用于提取物体边缘;

顶帽:原图 减 开运算,用于分离比临近点亮一些的斑块,进行背景提取;

黑帽:闭运算 减 原图,用于分离比临近点暗一些的斑块;

击中与击不中:用击中结构去腐蚀原始图像得到击中集合,用击不中结构去腐蚀原始图像的补集得到击不中集合,取两者的交集(与运算)作为结果集;可用于寻找模版图片在原图片中的位置;

/// <summary>
/// 形态学运算
/// 开运算:先腐蚀后膨胀,可清除小白点;图片会非常模糊;
/// 闭运算:先膨胀后腐蚀,可清除小黑点;图片会非常模糊;
/// 形态学梯度:膨胀图与腐蚀图之差,用于提取物体边缘;
/// 顶帽:原图 减 开运算,用于分离比临近点亮一些的斑块,进行背景提取;
/// 黑帽:闭运算 减 原图,用于分离比临近点暗一些的斑块;
/// 击中与击不中:用击中结构去腐蚀原始图像得到击中集合,用击不中结构去腐蚀原始图像的补集得到击不中集合,取两者的交集(与运算)作为结果集;可用于寻找模版图片在原图片中的位置;
/// </summary>
/// <param name="mat">图片</param>
/// <param name="op">形态学运算的类型;腐蚀,膨胀,开运算,闭运算,形态学梯度,顶帽,黑帽,击中与击不中</param>
/// <param name="element">用于侵蚀的结构内核;如果element=new Mat(),则使用3x3矩形结构化元素</param>
/// <param name="anchor">锚在元素中的位置。默认值(-1,-1)表示锚点位于元素中心</param>
/// <param name="iterations">应用侵蚀和膨胀的次数[默认为1]</param>
/// <param name="borderType">边缘像素的外推类型</param>
/// <param name="borderValue">在边缘为常量的情况下的边缘值</param>
/// <returns></returns>
public static Mat MorphologyEx(Mat mat, MorphTypes op, InputArray? element,
    Point? anchor = null, int iterations = 1, BorderTypes borderType = BorderTypes.Constant, Scalar? borderValue = null)
{
    Mat dstMet = new Mat();

    //var op = MorphTypes.Gradient;
    //var element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(6, 6));
    // 进行形态学运算
    Cv2.MorphologyEx(mat, dstMet, op, element, anchor, iterations, borderType, borderValue);
    return dstMet;
}

总结

形态学计算在图像处理中扮演着至关重要的角色。它不仅能够帮助我们清理图像中的噪声,还能提取出有用的结构信息。

以下是形态学计算的一些主要应用场景:

去噪:通过腐蚀和膨胀操作,可以有效去除图像中的小斑点或噪声。

边界检测:形态学梯度操作可以帮助我们检测图像的边缘和轮廓。

填充空洞:闭运算可以用来填补物体内部的小孔洞。

分割对象:开运算可以帮助分离粘连在一起的对象。

通过上述基本形态学操作,我们可以解决许多实际问题。例如,在工业质检中,可以通过形态学操作来检测产品表面的缺陷;在医学影像处理中,可以利用形态学操作来分割和分析组织结构。这些应用不仅展示了形态学计算的强大功能,还突显了其在不同领域的广泛应用。

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:꧁༺执笔小白༺꧂

出处:cnblogs.com/qq2806933146xiaobai/p/18294611

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!