手机网站宽度是多少,做产品推广哪个网站好,图虫摄影网官网,wordpress弹出搜索版权声明#xff1a;本文为博主原创文章#xff0c;转载请在显著位置标明本文出处以及作者网名#xff0c;未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。
教程VB.net版本请访问… 版权声明本文为博主原创文章转载请在显著位置标明本文出处以及作者网名未经作者允许不得用于商业目的。 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.2 轮廓处理
6.2.1 VectorOfPoint
VectorOfPoint是EmguCV中用于存储和操作点数可变的点集Point的类它可以用来存储任意数量的点。在前面的章节中介绍过VectorOf~这样的类型。这里单独介绍一下VectorOfPoint。
使用VectorOfPoint类可以方便地进行点集的存储和操作是在EmguCV中进行图像处理和分析的重要工具之一。在实际中VectorOfPoint可以理解为很多点的集合比如图像中的某个填充矩形它就是由很多点组合在一起的可以认为这个矩形就是一个VectorOfPoint。
VectorOfPoint类提供了一系列方法和属性用于对点集进行增删改查、排序、遍历等操作方便进行图像处理和分析。
1、创建VectorOfPoint对象
创建VectorOfPoint对象的方式如下
Dim vop As New VectorOfPoint
2、向VectorOfPoint对象中增加点
通过Push方法向VectorOfPoint对象中增加点这里需要传入点数组例如
vop.Push(New Point() {New Point(10, 20), New Point(30, 30)})
3、从VectorOfPoint对象中获取点
可以通过索引器或ToArray方法从VectorOfPoint对象中获取指定位置或所有位置的点例如
Dim p As Point vop(0)
Dim arrP() As Point vop.ToArray
4、修改VectorOfPoint对象中的点
非常遗憾的是没有提供直接修改的方法。
5、获取VectorOfPoint中的点的数量
可以通过Length属性获取VectorOfPoint中点的数量。
6、清除VectorOfPoint对象中的点
可以通过Clear方法实现。 其它VectorOf~开头的类型请参考VectorOfPoint。
6.2.2 VectorOfVectorOfPoint
VectorOfVectorOfPoint是EmguCV中用于存储和操作多个点集VectorOfPoint的类它也是一个泛型类可以用来存储任意数量的点集。该类提供了一系列方法和属性用于对点集进行增删改查、排序、遍历等操作方便进行图像处理和分析。
在实际中VectorOfVectorOfPoint可以理解为很多VectorOfPoint的集合比如图像中有矩形、圆形、多边形等它们分别是由很多点组合在一起的即这些图形自身是一个VectorOfPoint而VectorOfVectorOfPoint就包含可能是全部包含也可能是部分包含多个这样的VectorOfPoint。
VectorOfVectorOfPoint类的操作和VectorOfPoint类似这里不再累述。 其它VectorOfVectorOf~开头的类型请参考VectorOfVectorOfPoint。
6.2.3 轮廓查找FindContours
通过CvInvoke.FindContours方法可以在二值图像中查找轮廓该方法声明如下
Public Shared Sub FindContours(image As Emgu.CV.IInputOutputArray, contours As Emgu.CV.IOutputArray, hierarchy As Emgu.CV.IOutputArray, mode As Emgu.CV.CvEnum.RetrType, method As Emgu.CV.CvEnum.ChainApproxMethod, Optional offset As System.Drawing.Point Nothing)
参数说明
image需要进行轮廓查找的二值图像。contours存储轮廓的数组这是一个VectorOfVectorOfPoint类型。hierarchy存储轮廓的层级信息它是一个包含四个整数的数组其结构为
同层下一个轮廓索引-同层上一个轮廓索引-第一个子轮廓索引-父轮廓索引
通常使用VectorOfRect来存储这个层级结构信息以上结构信息对应Rect的
X-Y-Width-Height
mode轮廓查找的模式。这是一个RetrType枚举类型包含以下成员 List提取所有轮廓不建立层级关系。Ccomp提取所有轮廓并建立两层层级关系。External只提取最外层的轮廓。Tree提取所有的轮廓并建立完整的层级关系。method轮廓近似的方法。这是一个ChainApproxMethod枚举类型主要成员 ChainCode表示使用链码近似算法该算法使用像素点的坐标差异来表示轮廓的形状。计算复杂度较低。ChainApproxNone表示不使用近似算法直接使用所有像素点来表示轮廓的形状。计算复杂度较低。ChainApproxSimple表示使用简单的近似算法该算法使用线段连接像素点来近似轮廓的形状。计算复杂度较高。ChainApproxTc89L1表示使用Teh-Chin链码近似算法之一该算法可以更加准确地表示轮廓的形状。计算复杂度较高。ChainApproxTc89Kcos表示使用Teh-Chin链码近似算法之一该算法可以更加准确地表示轮廓的形状。计算复杂度较高。offset输入参数表示轮廓坐标的偏移量。
具体代码参看6.2.4 节【轮廓绘制DrawContours】 6.2.4 轮廓绘制DrawContours
在Emgu.CV中CvInvoke.DrawContours函数用于绘制轮廓。它的用法如下
Public Shared Sub DrawContours(image As Emgu.CV.IInputOutputArray, contours As Emgu.CV.IInputArrayOfArrays, contourIdx As Integer, color As Emgu.CV.Structure.MCvScalar, Optional thickness As Integer 1, Optional lineType As Emgu.CV.CvEnum.LineType 8, Optional hierarchy As Emgu.CV.IInputArray Nothing, Optional maxLevel As Integer 2147483647, Optional offset As System.Drawing.Point Nothing)
参数说明
contours要绘制的轮廓数组这是一个VectorOfVectorOfPoint类型。对应使用FindContours方法获得的contours。contourIdx要绘制的轮廓的索引。传入-1表示绘制所有的轮廓。color绘制轮廓的颜色。可以使用MCvScalar结构指定颜色值。thickness绘制轮廓的线条粗细。lineType绘制轮廓的线条类型。hierarchy轮廓的层级信息如果不需要使用层级信息可设置为Nothing。maxLevel绘制轮廓的最大层级默认值为Integer.MaxValue表示绘制所有层级的轮廓。offset绘制轮廓的坐标偏移量默认值为Nothing。
【代码位置frmChapter6】Button4_Click FindContours查找轮廓 Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click 直接载入灰度图像 Dim m1 As New Mat(C:\learnEmgucv\shape1.jpg, CvEnum.ImreadModes.Grayscale) ImageBox1.Image m1 二值化 Dim mid1 As New Mat CvInvoke.Threshold(m1, mid1, 150, 255, ThresholdType.BinaryInv) 最好使最外层为黑色。如果为白色那么会将最外层算为一个轮廓。所以这里使用 ThresholdType.BinaryInv ImageBox2.Image mid1 Dim contours As New VectorOfVectorOfPoint Dim hierarchy As New VectorOfRect 同层下一个轮廓索引-同层上一个轮廓索引-第一个子轮廓索引-父轮廓索引 CvInvoke.FindContours(mid1, contours, hierarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple) Dim m2 As New Mat m2 m1.Clone() m2.SetTo(New MCvScalar(0)) 绘制轮廓 For i As Integer 0 To contours.Size - 1 CvInvoke.DrawContours(m2, contours, i, New MCvScalar(255), 2) Next ImageBox3.Image m2 输出轮廓层级信息 For i As Integer 0 To hierarchy.Size - 1 Console.WriteLine(i - hierarchy(i).X - hierarchy(i).Y - hierarchy(i).Width - hierarchy(i).Height) Next
End Sub
运行后如下图所示 图6-4 绘制出的轮廓 图6-5 输出轮廓间关系 以下代码只绘制出最外层轮廓由于不需要层级关系所以hierarchy设置为nothingmode设置为External。
【代码位置frmChapter6】Button5_Click FindContours查找轮廓 Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click Dim m1 As New Mat(C:\learnEmgucv\shape1.jpg, CvEnum.ImreadModes.Grayscale) ImageBox1.Image m1 Dim mid1 As New Mat CvInvoke.Threshold(m1, mid1, 150, 255, ThresholdType.BinaryInv) ImageBox2.Image mid1 Dim contours As New VectorOfVectorOfPoint Dim hierarchy As New VectorOfRect 只提取最外层轮廓 CvInvoke.FindContours(mid1, contours, Nothing, RetrType.External, ChainApproxMethod.ChainApproxSimple) 在全黑的图像上绘制出轮廓 Dim m2 As New Mat m2 m1.Clone() m2.SetTo(New MCvScalar(0)) For i As Integer 0 To contours.Size - 1 CvInvoke.DrawContours(m2, contours, i, New MCvScalar(255), 2) Next ImageBox3.Image m2
End Sub
运行后如下图所示 图6-6 绘制出的轮廓 6.2.5 轮廓面积 ContourArea
CvInvoke.ContourArea方法用于计算轮廓的面积。它的声明如下
Public Shared Function ContourArea(contour As Emgu.CV.IInputArray, Optional oriented As Boolean False) As Double
参数说明
contour要计算面积的轮廓。这是一个VectorOfPoint类型。对应使用FindContours方法获得的contours所包含的成员。calculateArea指定轮廓是否有方向即面积是否为有向面积。如果为True则计算的是有向面积否则计算的是无向面积。有向面积是指轮廓线的外侧为正面内侧为负面因此有向面积可以为正数或负数无向面积则是指轮廓线所包含的平面区域的面积只能为正数。默认情况下该参数为 false即不考虑方向总是返回面积的绝对值。
【代码位置frmChapter6】Button6_Click 按照面积进行筛选输出 Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click Dim m1 As New Mat(C:\learnEmgucv\shape1.jpg, CvEnum.ImreadModes.Grayscale) ImageBox1.Image m1 二值化 Dim mid1 As New Mat CvInvoke.Threshold(m1, mid1, 150, 255, ThresholdType.BinaryInv) ImageBox2.Image mid1 Dim contours As New VectorOfVectorOfPoint Dim hierarchy As New VectorOfRect 查找轮廓 CvInvoke.FindContours(mid1, contours, hierarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple) Dim m2 As New Mat m2 m1.Clone() m2.SetTo(New MCvScalar(0)) For i As Integer 0 To contours.Size - 1 Dim carea As VectorOfPoint contours(i) 获得轮廓面积 Dim area As Double CvInvoke.ContourArea(carea, False) 符合条件时绘制轮廓 If area 10000 Then CvInvoke.DrawContours(m2, contours, i, New MCvScalar(255), -1) End If Next ImageBox3.Image m2
End Sub
运行后如下图所示 图6-7 输出面积小于10000的轮廓 6.2.6 轮廓周长 ArcLength
在Emgu.CV中CvInvoke.ArcLength函数用于计算轮廓的弧长周长。它的用法如下
Public Shared Function ArcLength(curve As Emgu.CV.IInputArray, isClosed As Boolean) As Double
参数说明
contour要计算周长的轮廓。这是一个VectorOfPoint类型。对应使用FindContours方法获得的contours所包含的成员。closed表示轮廓是否是闭合的。如果为True返回轮廓的曲线长度如果为False返回轮廓的周长。
【代码位置frmChapter6】Button7_Click 轮廓的面积和周长 Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click Dim m1 As New Mat(C:\learnEmgucv\shape1.jpg, CvEnum.ImreadModes.Grayscale) ImageBox1.Image m1 二值化并取反 Dim mid1 As New Mat CvInvoke.Threshold(m1, mid1, 150, 255, ThresholdType.BinaryInv) ImageBox2.Image mid1 Dim contours As New VectorOfVectorOfPoint Dim hierarchy As New VectorOfRect 查找轮廓 CvInvoke.FindContours(mid1, contours, hierarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple) Dim m2 As New Mat m2 m1.Clone() m2.SetTo(New MCvScalar(0)) For i As Integer 0 To contours.Size - 1 绘制轮廓 CvInvoke.DrawContours(m2, contours, i, New MCvScalar(255), 2) 获得面积 Dim area As Double CvInvoke.ContourArea(contours(i), False) 获得周长 Dim length As Double CvInvoke.ArcLength(contours(i), True) 输出面积和周长 Console.WriteLine(i - area - length) Next ImageBox3.Image m2
End Sub
运行后如下图所示 图6-8 输出轮廓的面积和周长