做淘宝导航网站,小朋友做安全教育的网站,网页版微信会留下记录吗,网站域名备案在阿里云怎么做版权声明#xff1a;本文为博主原创文章#xff0c;转载请在显著位置标明本文出处以及作者网名#xff0c;未经作者允许不得用于商业目的。 教程VB.net版本请访问#xff1a;EmguCV学习笔记 VB.Net 目录-CSDN博客
教程C#版本请访问#xff1a;EmguCV学习笔记 C# 目录-CSD… 版权声明本文为博主原创文章转载请在显著位置标明本文出处以及作者网名未经作者允许不得用于商业目的。 教程VB.net版本请访问EmguCV学习笔记 VB.Net 目录-CSDN博客
教程C#版本请访问EmguCV学习笔记 C# 目录-CSDN博客
笔者的博客网址https://blog.csdn.net/uruseibest
教程配套文件及相关说明以及如何获得pdf教程和代码博客上的教程内容会和pdf教程一致教程中也会包含所有代码请移步EmguCV学习笔记 4.4 图像形态学
图像形态学是数字图像处理中的一种重要技术它主要用于对二值图像进行分析和处理。图像形态学可以用于图像去噪、边缘检测、形态分析等方面。EmguCV提供了一系列的图像形态学操作函数包括膨胀、腐蚀、开运算、闭运算等。
1. 膨胀 (Dilation)
膨胀是一种形态学操作其基本思想是用一个结构元素 (Structuring Element) 在图像上滑动将结构元素包含的像素值中的最大值作为当前像素值从而实现对图像边缘的扩张和增强。EmguCV中的膨胀函数为CvInvoke.Dilate。
2. 腐蚀 (Erosion)
腐蚀是一种形态学操作其基本思想是用一个结构元素在图像上滑动将结构元素包含的像素值中的最小值作为当前像素值从而实现对图像边缘的收缩和平滑。EmguCV中的腐蚀函数为CvInvoke.Erode。
3. 开运算 (Opening)
开运算是一种形态学操作其基本思想是先进行一次腐蚀操作再进行一次膨胀操作从而可以去除比较小的物体、断开细长的物体等。EmguCV中的开运算函数为CvInvoke.MorphologyEx其类型为MorphOp.Open。
4. 闭运算 (Closing)
闭运算是一种形态学操作其基本思想是先进行一次膨胀操作再进行一次腐蚀操作从而可以填充物体内的小孔、连接断开的物体等。EmguCV中的闭运算函数为CvInvoke.MorphologyEx其类型为MorphOp.Close。
图像形态学操作需要根据图像的特点和处理目的进行合理的选择和组合才能达到良好的效果。
注意图像形态学针对的是非黑色部分非0部分操作。 4.4.1 GetStructuringElement
通过CvInvoke.GetStructuringElement方法可以创建形态学操作的结构元素。该方法返回一个Mat对象。定义如下
Public Shared Function GetStructuringElement(shape As Emgu.CV.CvEnum.ElementShape, ksize As System.Drawing.Size, anchor As System.Drawing.Point) As Emgu.CV.Mat
参数说明
shape结构元素的形状可以是Rectangle矩形、Cross十字形、Ellipse椭圆形。size结构元素的大小。anchor结构元素的锚点位置用Point结构指定。可以使用 Nothing 或者(-1,-1)表示将锚点放置在结构元素的中心。
下面的代码创建了一个3x3的十字形结构元素
Dim element As Mat
element CvInvoke.GetStructuringElement(ElementShape.Cross, New Size(3, 3)) 4.4.2 Erode
Erode方法对图像进行腐蚀操作该方法声明如下
Public Shared Sub Erode(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, element As Emgu.CV.IInputArray, anchor As System.Drawing.Point, iterations As Integer, borderType As Emgu.CV.CvEnum.BorderType, borderValue As Emgu.CV.Structure.MCvScalar)
参数说明
element结构元素。anchor结构元素的锚点位置类型为Point。指定结构元素的锚点位置一般为结构元素的中心即-1-1。iterations腐蚀操作的迭代次数类型为Integer。默认为1表示进行一次腐蚀操作。Iterations操作的迭代次数类型为Integer。默认为1表示进行一次膨胀操作。borderType边界处理方式类型为BorderType详见4.2.1节【BorderType】。需要注意的是使用的BorderType类型不同生成结果不同。borderValue边界值类型为MCvScalar。当borderType为BorderType.Constant时可以指定边界的像素值。通常设置为Nothing。
【代码位置frmChapter4】Button12_Click、printMatByte Erode腐蚀 Private Sub Button12_Click(sender As Object, e As EventArgs) Handles Button12.Click 创建结构元素这里是一个3*3大小的十字形结构 Dim kernel As New Mat kernel CvInvoke.GetStructuringElement(ElementShape.Cross, New Drawing.Size(3, 3), New Point(-1, -1)) Dim bte1(,) As Byte bte1 { {0, 1, 1, 1, 1, 0, 0, 0, 0}, {1, 1, 1, 1, 1, 1, 1, 1, 0}, {1, 1, 1, 1, 1, 1, 1, 1, 0}, {1, 1, 1, 1, 1, 1, 1, 1, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 0, 0, 0, 1, 1, 1, 1, 0} } Dim matr1 As New Matrix(Of Byte)(bte1) Dim m1 As New Mat m1 matr1.Mat Dim merode As New Mat 这里使用了2次迭代 CvInvoke.Erode(m1, merode, kernel, New Point(-1, -1), 2, BorderType.Constant, Nothing) Call printMatByte(merode) End Sub 输出Mat的值 Private Sub printMatByte(ByVal m As Mat) Dim matr As New Matrix(Of Byte)(m.Rows, m.Cols, m.NumberOfChannels) m.CopyTo(matr) For i As Integer 0 To matr.Rows - 1 For j As Integer 0 To matr.Cols - 1 Console.Write(matr(i, j)) If j matr.Cols - 1 Then Console.Write(,) End If Next Console.WriteLine() Next
End Sub
下图演示了使用腐蚀进行2次迭代的结果 图4-12 进行二次腐蚀的情况 4.4.3 Dilate
Dilate方法对图像进行膨胀操作该方法声明如下
Public Shared Sub Dilate(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, element As Emgu.CV.IInputArray, anchor As System.Drawing.Point, iterations As Integer, borderType As Emgu.CV.CvEnum.BorderType, borderValue As Emgu.CV.Structure.MCvScalar)
参数请参看4.3.2节【Erode】中的介绍。
【代码位置frmChapter4】Button13_Click Dilate 膨胀 Private Sub Button13_Click(sender As Object, e As EventArgs) Handles Button13.Click 创建结构元素这里是一个3*3大小的十字形结构 Dim kernel As New Mat kernel CvInvoke.GetStructuringElement(ElementShape.Cross, New Drawing.Size(3, 3), New Point(-1, -1)) Dim bte2(,) As Byte bte2 { {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 1, 1, 0, 0}, {0, 0, 0, 0, 1, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0} } Dim matr2 As New Matrix(Of Byte)(bte2) Dim m2 As New Mat m2 matr2.Mat Dim mdilate As New Mat 这里使用了2次迭代进行膨胀 CvInvoke.Dilate(m2, mdilate, kernel, New Point(-1, -1), 2, BorderType.Constant, Nothing) Call printMatByte(mdilate)
End Sub
下图演示了使用腐蚀进行2次迭代的结果 图4-13 进行二次膨胀的情况
以下代码演示了使用腐蚀和膨胀来处理图像。
【代码位置frmChapter4】Button14_Click Erode和Dilate Private Sub Button14_Click(sender As Object, e As EventArgs) Handles Button14.Click Dim m As Mat CvInvoke.Imread(C:\lessons\lena.jpg, CvEnum.ImreadModes.Color) ImageBox1.Image m Dim mElement As New Mat mElement CvInvoke.GetStructuringElement(ElementShape.Cross, New Drawing.Size(3, 3), New Point(-1, -1)) 腐蚀 Dim mout1 As New Mat CvInvoke.Erode(m, mout1, mElement, New Point(-1, -1), 2, BorderType.Default, Nothing) ImageBox2.Image mout1 膨胀 Dim mout2 As New Mat CvInvoke.Dilate(m, mout2, mElement, New Point(-1, -1), 2, BorderType.Default, Nothing ImageBox3.Image mout2
End Sub
运行后如下图所示 图4-14 使用腐蚀和膨胀处理图像 4.4.4 MorphologyEx
为了实现更多图像形态学操作EmguCV提供了CvInvoke.MorphologyEx方法声明如下
Public Shared Sub MorphologyEx(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, operation As Emgu.CV.CvEnum.MorphOp, kernel As Emgu.CV.IInputArray, anchor As System.Drawing.Point, iterations As Integer, borderType As Emgu.CV.CvEnum.BorderType, borderValue As Emgu.CV.Structure.MCvScalar)
参数说明其余参数请参看4.3.2节【Erode】中的介绍
operation形态学操作类型类型为MorphOp包括以下几种形态学操作 Dilate膨胀操作Erode腐蚀操作。Open开运算先进行腐蚀再进行膨胀可以用于去除小的噪点和连接断开的区域。Close闭运算先进行膨胀再进行腐蚀可以用于填充小的空洞和分离连接的区域。Gradient梯度运算用膨胀图像减去腐蚀图像可以得到图像边缘。TopHat高帽运算用原始图像减去开运算后的图像可以提取图像中的亮点或小的细节信息。BlackHat低帽运算用闭运算后的图像减去原始图像可以提取图像中的暗点或背景信息。HitMiss击中击不中运算用于确定图像中是否存在指定的形状。它需要两个结构元素一个前景结构元素和一个背景结构元素。在输入图像上如果前景结构元素可以同时与前景像素和背景像素匹配那么该像素属于击中集合否则它属于击不中集合。通过对击中集合进行膨胀操作并减去原始击中集合得到最终结果。 以下代码演示了使用开运算来处理图像数据同时与腐蚀膨胀操作图像数据做对比。
【代码位置frmChapter4】Button15_Click MorphologyEx开运算先腐蚀再膨胀 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click Dim bte(,) As Byte bte { {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 1, 0, 0, 0, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 0, 0, 0, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 1, 0, 0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0} } Dim matr As New Matrix(Of Byte)(bte) Dim m As New Mat m matr.Mat 创建结构元素这里是一个3*3大小的十字形结构 Dim kernel As New Mat kernel CvInvoke.GetStructuringElement(ElementShape.Cross, New Drawing.Size(3, 3), New Point(-1, -1)) 进行开运算 Dim mMorphology As New Mat CvInvoke.MorphologyEx(m, mMorphology, MorphOp.Open, kernel, New Point(-1, -1), 1, BorderType.Constant, Nothing) Call printMatByte(mMorphology) Console.WriteLine() 先腐蚀 Dim merode As New Mat CvInvoke.Erode(m, merode, kernel, New Point(-1, -1), 1, BorderType.Constant, Nothing) Call printMatByte(merode) Console.WriteLine() 再膨胀 Dim mdilate As New Mat CvInvoke.Dilate(merode, mdilate, kernel, New Point(-1, -1), 1, BorderType.Constant, Nothing) Call printMatByte(mdilate)
End Sub
下图演示了使用开运算处理图像数据的结果 图4-15 开运算处理图像数据 以下代码演示了使用闭运算来处理图像数据同时与膨胀腐蚀操作图像数据做对比。
【代码位置frmChapter4】Button16_Click MorphologyEx闭运算先膨胀再腐蚀 Private Sub Button16_Click(sender As Object, e As EventArgs) Handles Button16.Click Dim bte(,) As Byte bte { {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 1, 1, 0, 1, 1, 1, 0}, {0, 1, 1, 1, 0, 1, 1, 1, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 0}, {0, 1, 1, 1, 0, 1, 1, 1, 0}, {0, 0, 0, 1, 1, 1, 0, 0, 0}, {0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0} } Dim matr As New Matrix(Of Byte)(bte) Dim m As New Mat m matr.Mat 创建结构元素这里是一个3*3大小的十字形结构 Dim kernel As New Mat kernel CvInvoke.GetStructuringElement(ElementShape.Cross, New Drawing.Size(3, 3), New Point(-1, -1)) 闭运算 Dim mMorphology As New Mat CvInvoke.MorphologyEx(m, mMorphology, MorphOp.Close, kernel, New Point(-1, -1), 1, BorderType.Constant, Nothing) Call printMatByte(mMorphology) Console.WriteLine() 先膨胀 Dim mdilate As New Mat CvInvoke.Dilate(m, mdilate, kernel, New Point(-1, -1), 1, BorderType.Constant, Nothing) Call printMatByte(mdilate) Console.WriteLine() 再腐蚀 Dim merode As New Mat CvInvoke.Erode(mdilate, merode, kernel, New Point(-1, -1), 1, BorderType.Constant, Nothing) Call printMatByte(merode)
End Sub
下图演示了使用闭运算处理图像数据的结果 图4-16 闭运算处理图像数据 以下代码演示了使用闭运算和开运算来处理图像。
【代码位置frmChapter4】Button17_Click MorphologyEx开运算和闭运算处理图像 Private Sub Button17_Click(sender As Object, e As EventArgs) Handles Button17.Click Dim m As Mat CvInvoke.Imread(C:\lessons\lena.jpg, CvEnum.ImreadModes.Color) ImageBox1.Image m Dim mElement As New Mat mElement CvInvoke.GetStructuringElement(ElementShape.Cross, New Drawing.Size(3, 3), New Point(-1, -1)) 开运算 Dim mout1 As New Mat CvInvoke.MorphologyEx(m, mout1, MorphOp.Open, mElement, New Point(-1, -1), 3, BorderType.Default, New MCvScalar(0, 0, 0)) ImageBox2.Image mout1 闭运算 Dim mout2 As New Mat CvInvoke.MorphologyEx(m, mout2, MorphOp.Close, mElement, New Point(-1, -1), 3, BorderType.Default, New MCvScalar(0, 0, 0)) ImageBox3.Image mout2
End Sub
运行后如下图所示 图4-17 开运算和闭运算处理图像