EmguCV学习笔记 VB.Net 6.6 图像的矩

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。

教程VB.net版本请访问: EmguCV学习笔记 VB.Net 目录-CSDN博客

教程C#版本请访问: EmguCV学习笔记 C# 目录-CSDN博客

笔者的博客网址:https://blog.csdn.net/uruseibest

教程配套文件及相关说明以及如何获得pdf教程和代码,请移步: EmguCV学习笔记

学习VB.Net知识,请移步: vb.net 教程 目录_vb中如何用datagridview-CSDN博客

学习C#知识,请移步: C# 教程 目录_c#教程目录-CSDN博客

6.6 图像的矩

在图像处理中,矩(moment)是一种用于描述图像形状和空间分布特征的特征描述子。图像的矩可以用于描述图像的重心、面积、方向、边界等特征,从而用于图像处理任务,如图像分割、边缘检测、形状识别等。

1、零阶矩(M00):表示图像上所有非0的像素值的和,也就是目标区域面积。

2、一阶矩(M01和M10):分别为图像关于x轴和y轴的矩,可以用来确定目标区域的质心。质心坐标可表示为:X0=M10/M00,Y0=M01/M00。

3、二阶矩(M20、M02和M11):二阶矩可以用来计算图像的方向和轮廓。其中,M20和M02分别表示目标区域在水平和垂直方向上的伸展均衡度,M20大于0表示目标区域下部的水平伸展度比上部大,小于0表示上部的水平伸展度比下部大;M02大于0表示图像右边的垂直伸展比左边大,小于0则正相反。M11表示目标区域的倾斜度,M11大于0表示图像向左上倾斜,小于0表示图像向右上倾斜。通过组合它们可以确定几个重要的特性,例如主轴比和方向、离心率、圆形度等等。

4、三阶矩(M30、M03):三阶矩可以用来描述图像的偏态特征,常用的三阶矩包括M30和M03。其中,M30表示图像x轴方向的偏态,M30大于0表示重心偏左,小于0表示重心偏右;M03表示图像y轴方向的偏态,M03大于0表示重心向上偏移小于0表示重心向下偏移。

5、四阶矩(M40、M04、M22):四阶矩可以用来描述图像的峰态特征,常用的四阶矩包括M40、M04和M22。其中,M40和M04分别表示图像x轴和y轴方向的峰态,用于计算图像的平峰或尖峰程度;M22表示图像的斜峰程度。当峰度系数为0时,表示高斯分布;当峰度系数小于0时,表示平坦的少峰分布;当峰度系数大于0时,表示狭窄的多峰分布。

上述图像矩只为普通矩,其值随目标区域的旋转、平移、尺度变化而改变,在实际应用中,为了提高图像矩的适用能力,需要将普通矩转换为具有旋转、平移和尺度不变性的Hu矩。

6.6.1 矩 Moments

CvInvoke.Moments方法用于计算给定图像的几何矩。它的声明如下:

Public Shared Function Moments(arr As Emgu.CV.IInputArray, Optional binaryImage As Boolean = False) As Emgu.CV.Moments

参数说明:

  1. arr:要计算几何矩的图像。
  2. binaryImage:可选参数,表示图像是否为二值图像,默认为False。

返回值:

返回一个Moments类型的对象,表示计算得到的几何矩。

【代码位置:frmChapter6】Button22_Click

'矩 Moments

Private Sub Button22_Click(sender As Object, e As EventArgs) Handles Button22.Click

Dim msrc As New Mat("C:\learnEmgucv\shape.jpg", ImreadModes.AnyColor)

ImageBox1.Image = msrc

Dim gray As New Mat

CvInvoke.CvtColor(msrc, gray, ColorConversion.Bgr2Gray)

Dim mb As New Mat

CvInvoke.Threshold(gray, mb, 220, 255, ThresholdType.BinaryInv)

ImageBox2.Image = mb

Dim contours As New VectorOfVectorOfPoint

'这里不需要获得 hierarchy,设置为nothing

CvInvoke.FindContours(mb, contours, Nothing, RetrType.List, ChainApproxMethod.ChainApproxNone)

Dim mdst As New Mat

mdst = gray.Clone

CvInvoke.CvtColor(mdst, mdst, ColorConversion.Gray2Bgr)

For i As Integer = 0 To contours.Size - 1

'绘制轮廓

CvInvoke.DrawContours(mdst, contours, i, New MCvScalar(0, 0, 255), 2)

'获得轮廓的矩

Dim mo As New Moments

mo = CvInvoke.Moments(contours(i))

Dim m00 As Double = mo.M00

Dim m10 As Double = mo.M10

Dim m01 As Double = mo.M01

'M10和M00计算图像的x轴重心位置

Dim x As Double = m10 / m00

'M01和M00计算图像的y轴重心位置

Dim y As Double = m01 / m00

'标明轮廓的重心

CvInvoke.Circle(mdst, New Point(CInt(x), CInt(y)), 4, New MCvScalar(0, 255, 0), -1)

Next

ImageBox3.Image = mdst

End Sub

运行后如下图所示:

图6-23 获得每个轮廓的重心

6.6.2 Hu矩

Hu矩(Hu Moments)基于图像的矩的不变性特征,通过对图像的矩进行归一化和变换得到一组具有旋转、平移和尺度不变性的特征值,用于描述图像的形状特征。

Hu矩是一组七个矩,分别为:

  1. 第一不变矩:该不变矩表示图像的总体亮度或面积。它可以用于图像的亮度校准和图像的分割。通过比较不同图像的第一不变矩,可以判断它们的亮度或面积差异。

  2. 第二不变矩:该不变矩表示图像的形状对称性。它可以用于图像的轴对称性检测和形状匹配。通过比较不同图像的第二不变矩,可以判断它们的形状是否相似或对称。

  3. 第三不变矩:该不变矩表示图像的形状的偏斜程度。它可以用于图像的形状识别和形状匹配。通过比较不同图像的第三不变矩,可以判断它们的形状是否存在偏斜。

  4. 第四不变矩:该不变矩表示图像的形状的斜率。它可以用于图像的形状识别和形状匹配。通过比较不同图像的第四不变矩,可以判断它们的形状是否具有相似的斜率。

  5. 第五不变矩:该不变矩表示图像的形状的膨胀或收缩程度。它可以用于图像的形状识别和形状匹配。通过比较不同图像的第五不变矩,可以判断它们的形状是否存在膨胀或收缩。

  6. 第六不变矩:该不变矩表示图像的形状的旋转程度。它可以用于图像的形状识别和形状匹配。通过比较不同图像的第六不变矩,可以判断它们的形状是否存在旋转。

  7. 第七不变矩:该不变矩表示图像的形状的轮廓曲率。它可以用于图像的形状识别和形状匹配。通过比较不同图像的第七不变矩,可以判断它们的形状是否具有相似的轮廓曲率。

通过比较不同图像的Hu矩,可以确定它们的形状差异和相似性。这使得Hu矩在图像处理和计算机视觉领域的许多应用中都得到了广泛的应用,例如目标识别、目标跟踪、图像检索等。

在Emgu.CV中,CvInvoke.HuMoments方法用于计算给定图像的Hu矩。Hu矩是一种图像的形状描述子,用于表示图像的不变性特征。它的声明如下:

Public Shared Function HuMoments(m As Emgu.CV.Moments) As Double()

参数说明:

  1. m:要计算Hu矩的几何矩,类型为Moments,值来自于CvInvoke.Moments获得的结果。

返回值:

返回一个Double数组,表示计算得到的7个矩。

【代码位置:frmChapter6】Button23_Click

'Hu矩

Private Sub Button23_Click(sender As Object, e As EventArgs) Handles Button23.Click

Dim m As New Mat("C:\learnEmgucv\shape.jpg", ImreadModes.AnyColor)

Dim gray As New Mat

CvInvoke.CvtColor(m, gray, ColorConversion.Bgr2Gray)

Dim b As New Mat

CvInvoke.Threshold(gray, b, 220, 255, ThresholdType.BinaryInv)

Dim contours As New VectorOfVectorOfPoint

'这里不需要获得 hierarchy,设置为nothing

CvInvoke.FindContours(b, contours, Nothing, RetrType.List, ChainApproxMethod.ChainApproxNone)

Dim m1 As New Mat

m1 = gray.Clone

CvInvoke.CvtColor(m1, m1, ColorConversion.Gray2Bgr)

For i As Integer = 0 To contours.Size - 1

'获得矩

Dim mo As New Moments

mo = CvInvoke.Moments(contours(i))

'获得Hu矩

Dim Hu() As Double

Hu = CvInvoke.HuMoments(mo)

'输出Hu矩的每个值

For j As Integer = 0 To Hu.Length - 1

Console.WriteLine("第 " & i & "个形状的Hu " & j & ":" & Hu(j))

Next

Next

End Sub

输出结果如下图所示:

图6-24 获得Hu矩

在实际开发中,理论上可以对比两个轮廓的Hu矩的差来判断相似度,但是实际由于获得的Hu矩的值很小,用来判断很不理想。读者可以自行试验。

6.6.3 形状匹配

CvInvoke.MatchShapes方法用于计算两个轮廓的形状相似性。MatchShapes可以获取两幅图像(或轮廓),并使用Hu矩查找它们之间的距离。使用该方法并不用计算Hu矩,只需要对图像进行二值化。它的声明如下:

Public Shared Function MatchShapes(contour1 As Emgu.CV.IInputArray, contour2 As Emgu.CV.IInputArray, method As Emgu.CV.CvEnum.ContoursMatchType, Optional parameter As Double = 0) As Double

参数说明:

  1. contour1:表示第一个轮廓,类型为VectorOfPoint。
  2. contour2:表示第二个轮廓,类型为VectorOfPoint。
  3. method:计算相似性的方法,类型为ContoursMatchType枚举。常用的方法包括CV_CONTOURS_MATCH_I1、CV_CONTOURS_MATCH_I2和CV_CONTOURS_MATCH_I3。
  4. parameter:计算相似性的参数,类型为Double。目前此参数似乎没什么意义。

返回值:

返回一个Double类型的值,表示两个轮廓的形状相似性程度。返回值越小,表示两个轮廓越相似。

【代码位置:frmChapter6】Button24_Click

'基于Hu矩的轮廓匹配

Private Sub Button24_Click(sender As Object, e As EventArgs) Handles Button24.Click

Dim msrc As New Mat("C:\learnEmgucv\shape.jpg", ImreadModes.Grayscale)

Dim b As New Mat

CvInvoke.Threshold(msrc, b, 220, 255, ThresholdType.BinaryInv)

ImageBox1.Image = b

Dim contours As New VectorOfVectorOfPoint

CvInvoke.FindContours(b, contours, Nothing, RetrType.List, ChainApproxMethod.ChainApproxNone)

Dim mdst1 As New Mat("C:\learnEmgucv\shape_1.jpg", ImreadModes.Grayscale)

Dim b1 As New Mat

CvInvoke.Threshold(mdst1, b1, 220, 255, ThresholdType.BinaryInv)

Dim contours1 As New VectorOfVectorOfPoint

CvInvoke.FindContours(b1, contours1, Nothing, RetrType.List, ChainApproxMethod.ChainApproxNone)

Dim contour1 As New VectorOfPoint

'为了简化说明,这里只有一个轮廓

contour1 = contours1(0)

Dim mm1 As New Mat

mm1 = msrc.Clone

mm1.SetTo(New MCvScalar(0))

Dim thecontour As New VectorOfPoint

For i As Integer = 0 To contours.Size - 1

Dim returnvalue As Double

'计算相似性

returnvalue = CvInvoke.MatchShapes(contour1, contours(i), ContoursMatchType.I1)

'需要根据实际情况来设置值才能获得满意效果

If returnvalue < 0.02 Then

CvInvoke.DrawContours(mm1, contours, i, New MCvScalar(255), -1)

thecontour = contours(i)

End If

Next

ImageBox2.Image = mm1

'shape_2是shape_1旋转后的图像

Dim mdst2 As New Mat("C:\learnEmgucv\shape_2.jpg", ImreadModes.Grayscale)

Dim b2 As New Mat

CvInvoke.Threshold(mdst2, b2, 220, 255, ThresholdType.BinaryInv)

Dim contours2 As New VectorOfVectorOfPoint

CvInvoke.FindContours(b2, contours2, Nothing, RetrType.List, ChainApproxMethod.ChainApproxNone)

Dim contour2 As New VectorOfPoint

contour2 = contours2(0)

'Console.WriteLine("returnvalueB")

Dim mm2 As New Mat

mm2 = msrc.Clone

mm2.SetTo(New MCvScalar(0))

For i As Integer = 0 To contours.Size - 1

Dim returnvalue As Double

returnvalue = CvInvoke.MatchShapes(contour2, contours(i), ContoursMatchType.I3)

'采用与上面相同的值,匹配了其他轮廓

'需要更小的值,比如0.015才能过滤不匹配的轮廓

If returnvalue < 0.02 Then

CvInvoke.DrawContours(mm2, contours, i, New MCvScalar(255), -1)

End If

Next

ImageBox3.Image = mm2

End Sub

输出结果如下图所示:

图6-25 图像轮廓匹配

【代码位置:frmChapter6】Button25_Click

'基于Hu矩的轮廓匹配

Private Sub Button25_Click(sender As Object, e As EventArgs) Handles Button25.Click

Dim m As New Mat("C:\learnEmgucv\shape3.jpg", ImreadModes.Grayscale)

Dim b As New Mat

CvInvoke.Threshold(m, b, 220, 255, ThresholdType.BinaryInv)

ImageBox1.Image = b

Dim contours As New VectorOfVectorOfPoint

'只检测外轮廓

CvInvoke.FindContours(b, contours, Nothing, RetrType.External, ChainApproxMethod.ChainApproxNone)

'shape3图片中只包含5个图形,contours序号从0-4分别对应

'B 下A C 上右A 上左A

'这里使用上面的两个A与下面对比

Dim contour1 As New VectorOfPoint

Dim contour2 As New VectorOfPoint

'上面的两个不同字体的A

contour1 = contours(4)

contour2 = contours(3)

'下面的ABC轮廓

Dim contoursa As New VectorOfVectorOfPoint

contoursa.Push(contours(1))

contoursa.Push(contours(0))

contoursa.Push(contours(2))

Dim mm1 As New Mat

mm1 = m.Clone

mm1.SetTo(New MCvScalar(0))

Dim mm2 As New Mat

mm2 = m.Clone

mm2.SetTo(New MCvScalar(0))

For i As Integer = 0 To 2

Dim returnvalue1 As Double

returnvalue1 = CvInvoke.MatchShapes(contour1, contoursa(i), ContoursMatchType.I1)

Console.WriteLine(returnvalue1)

'输出结果:

'0.0931539845093758

'0.255313921042219

'0.881725801395845

If returnvalue1 < 0.1 Then

CvInvoke.DrawContours(mm1, contoursa, i, New MCvScalar(255), 2)

End If

Dim returnvalue2 As Double

returnvalue2 = CvInvoke.MatchShapes(contour2, contoursa(i), ContoursMatchType.I1)

Console.WriteLine(returnvalue2)

'输出结果:

'0.20659335409303

'0.509194144738261

'0.72275679628663

If returnvalue2 < 0.3 Then

CvInvoke.DrawContours(mm2, contoursa, i, New MCvScalar(255), 2)

End If

Next

ImageBox2.Image = mm1

ImageBox3.Image = mm2

End Sub

输出结果如下图所示:

图6-26 不同字体的A轮廓与ABC轮廓匹配

【代码位置:frmChapter6】Button26_Click

'基于Hu矩的轮廓匹配

Private Sub Button26_Click(sender As Object, e As EventArgs) Handles Button26.Click

Dim m As New Mat("C:\learnEmgucv\shape4.jpg", ImreadModes.Grayscale)

Dim b As New Mat

CvInvoke.Threshold(m, b, 220, 255, ThresholdType.BinaryInv)

ImageBox1.Image = b

Dim contours As New VectorOfVectorOfPoint

'只检测外轮廓

CvInvoke.FindContours(b, contours, Nothing, RetrType.External, ChainApproxMethod.ChainApproxNone)

'shape3图片中只包含5个图形,contours序号从0-4分别对应

'B 下A C 上右B 上左B

'这里使用上面的两个A与下面对比

Dim contour1 As New VectorOfPoint

Dim contour2 As New VectorOfPoint

contour1 = contours(4)

contour2 = contours(3)

Dim contoursa As New VectorOfVectorOfPoint

contoursa.Push(contours(1))

contoursa.Push(contours(0))

contoursa.Push(contours(2))

Dim mm1 As New Mat

mm1 = m.Clone

mm1.SetTo(New MCvScalar(0))

Dim mm2 As New Mat

mm2 = m.Clone

mm2.SetTo(New MCvScalar(0))

For i As Integer = 0 To 2

Dim returnvalue1 As Double

returnvalue1 = CvInvoke.MatchShapes(contour1, contoursa(i), ContoursMatchType.I1)

Console.WriteLine(returnvalue1)

'输出结果:

'0.34031067009289

'0.0422767968544905

'0.928506107053343

If returnvalue1 < 0.1 Then

CvInvoke.DrawContours(mm1, contoursa, i, New MCvScalar(255), 2)

End If

Dim returnvalue2 As Double

returnvalue2 = CvInvoke.MatchShapes(contour2, contoursa(i), ContoursMatchType.I1)

Console.WriteLine(returnvalue2)

'输出结果:

'0.340619810117041

'0.0423705106226118

'0.928412393285222

If returnvalue2 < 0.1 Then

CvInvoke.DrawContours(mm2, contoursa, i, New MCvScalar(255), 2)

End If

Next

ImageBox2.Image = mm1

ImageBox3.Image = mm2

End Sub

输出结果如下图所示:

图6-27 B轮廓与ABC轮廓匹配

相关推荐
广煜永不挂科20 分钟前
Devexpress.Dashboard的调用二义性
c#·express
lindsayshuo1 小时前
jetson orin系列开发版安装cuda的gpu版本的opencv
人工智能·opencv
向阳逐梦1 小时前
ROS机器视觉入门:从基础到人脸识别与目标检测
人工智能·目标检测·计算机视觉
Mr.Q1 小时前
OpenCV和Qt坐标系不一致问题
qt·opencv
zhy8103022 小时前
.net6 使用 FreeSpire.XLS 实现 excel 转 pdf - docker 部署
pdf·.net·excel
有Li2 小时前
跨视角差异-依赖网络用于体积医学图像分割|文献速递-生成式模型与transformer在医学影像中的应用
人工智能·计算机视觉
初九之潜龙勿用2 小时前
C#校验画布签名图片是否为空白
开发语言·ui·c#·.net
GOTXX3 小时前
基于Opencv的图像处理软件
图像处理·人工智能·深度学习·opencv·卷积神经网络
慧都小妮子3 小时前
Spire.PDF for .NET【页面设置】演示:打开 PDF 时自动显示书签或缩略图
java·pdf·.net
嵌入式大圣3 小时前
单片机结合OpenCV
单片机·嵌入式硬件·opencv