文章目录
- 一、相关概念
- 1.什么叫形态学
- 2.形态学操作的目的
- 3.形态学都包含哪些操作
- 4.结构元素StructuringElement
- 二、腐蚀
- 1.什么叫腐蚀
- 2.腐蚀的作用
- 3.腐蚀的函数
- 三、演示
- 1.原始素材
- 2.代码
- 3.运行结果
一、相关概念
1.什么叫形态学
形态学,英文名称morphology,根据网络上专业的说法,它是一种基于形状的图像处理技术,通过结构元素与图像进行特定运算的方式来改变图像的形态和特征。结构元素是一种小型、预定义的形状,通常是矩形、圆形或者椭圆形。
形态学操作的对象,一般是 二值化后的灰度图,对于普通灰度图、彩色图像,一般不用形态学操作。
2.形态学操作的目的
形态学操作后,可以保留二值化图像主要特征,消除噪点、孤立点的影响,更容易的获取到目标区域。这个操作在图像处理里面非常重要,基本上50%的图像处理例子都会用到。
3.形态学都包含哪些操作
腐蚀、膨胀、开运算、闭运算、形态学梯度、顶帽、黑帽,击中与击不中,名字是不是听起来都挺特殊的,别着急,咱们一个一个的举例子。
4.结构元素StructuringElement
在正式讲各种形态学操作之前,还有一个名字要解释一下,就是结构元素(Structuring Element),也可以叫卷积核。可以理解为结构元素是由值为1的矩阵组成,假设是7 * 7 的结构元素,那就是以目标点P(x,y)为中心,对周边邻域7 * 7 大小的范围内进行计算,得到的结果就是输出图像P(x,y)点的值。
二、腐蚀
1.什么叫腐蚀
二值化图片以黑色为背景,白色为前景物体。腐蚀就是收缩前景物体的边缘。其原理是将一个结构元素在图像上滑动,如果结构元素对应的原图的所有像素值为1(或者255),那么中心元素就保持原来的值,否则变为零。
假设有一副图像如下图,灰色底色是背景,黄色底色是前景物体。
定义一个结构元素,大小是3 * 3,也就是这样的
如果对左侧绿底色的255那个点做腐蚀操作,根据结构元素大小,提取出的计算区域是
在这9个值中,存在等于0的点,因此输出图像中,这个绿底色255点的值就是0。如果对右边绿底色255进行腐蚀呢,它提取出的计算区域是
因为9个值都是255,因此这个点的腐蚀结果,还是255。
2.腐蚀的作用
腐蚀操作可以去除白色前景物体的边缘毛刺,也可以断开相连的白色前景。 各种形态学操作的作用要记清楚了。
3.腐蚀的函数
Emgu CV中,腐蚀的函数定义如下:
public static void Erode(
IInputArray src, // 输入图像
IOutputArray dst, // 输入图像
IInputArray element, // 结构元素大小
Point anchor, // 锚点位置,默认为中心new Point(-1, -1)
int iterations, // 腐蚀操作迭代次数
BorderType borderType, // 边界填充方式,一般取默认
MCvScalar borderValue // 边界值,使用时一般写成new MCvScalar()
)
三、演示
1.原始素材
原始素材定义为srcMat,是一张黑色背景,白色前景的图像。
2.代码
Emgu CV在背景图片中找到目标图片的黄色小球,代码如下:
Mat tempMat = srcMat.Clone();
Mat gray = new Mat();
Mat dstMat = new Mat();
int kernelX = Convert.ToInt16(TextBoxX.Text.Trim().ToString()); // structuring element结构元素 或者 kernel 内核的X值,水平方向
int kernelY = Convert.ToInt16(TextBoxY.Text.Trim().ToString()); // structuring element结构元素 或者 kernel 内核的X值,垂直方向
int iterations = Convert.ToInt16(TextBoxIterations.Text.Trim().ToString()); // 需要执行腐蚀的次数
// 要转成灰度图
CvInvoke.CvtColor(tempMat, gray, ColorConversion.Bgr2Gray);
// 定义结构元素,其中元素的形状是矩形,size大小由两个文本框决定,默认锚点new Point(-1,-1)是指在中心
Mat element = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new System.Drawing.Size(kernelX, kernelY), new System.Drawing.Point(-1, -1));
// 开始腐蚀,其中锚点位置new Point(-1, -1)代表中心
CvInvoke.Erode(gray, dstMat, element, new System.Drawing.Point(-1, -1), iterations, BorderType.Default, new MCvScalar());
CvInvoke.Imshow("Gray, " + gray.Size.ToString(), gray);
CvInvoke.Imshow("Erode, " + dstMat.Size.ToString(), dstMat);
注意哈,结构元素的内核要对水平方向和垂直方向分别定义。
3.运行结果
假设kernelX = 3,kernelY =3,iterations = 1, 其腐蚀结果如下所示:
白色区域是不是变细了,而且白色矩形的边缘毛刺,也被腐蚀掉了。假设kernelX = 9,kernelY =1,iterations = 1, 其腐蚀结果如下所示:
这次就是水平方向的前景形状还能保留,垂直方向的直线(或者曲线形状),很多都被腐蚀没了,为什么呢?就是因为结构元素,其X方向是9,也就是水平方向以目标点为中心,左右9个计算区域内,有值为0的就输出。水平方向计算区域大了,只有横向的白色区间越大,目标点是255的可能性才越大。而结构元素Y方向是1,也就是垂直方向计算区域只有目标点,目标点是255结果就输出255;目标点是0结果就输出0。假设kernelX = 1,kernelY =13,iterations = 1, 其腐蚀结果如下所示:
是不是水平方向的前景被腐蚀了很多,但垂直方向的前景基本保留了。这个原理需要仔细理解一下,先记住腐蚀操作的结论:
1、结构元素水平方向值越大,目标图像中竖向前景越容易被腐蚀。
2、结构元素垂直方向值越大,目标图像中水平前景越容易被腐蚀。
3、iterations(执行次数)越大,目标图像被腐蚀的越多。
原创不易,请勿抄袭。共同进步,相互学习。