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

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.4 霍夫变换

霍夫变换(Hough Transform)是一种在图像中检测几何形状的常用方法,最初用于检测直线,后来也扩展到检测其他形状,如圆、椭圆等。霍夫变换的核心思想是将图像空间中的特征点映射到参数空间中,并通过在参数空间中寻找峰值来检测形状。

霍夫变换的优点是对于图像中的形状检测具有较好的鲁棒性,对于存在噪声和遮挡的情况仍能有效检测。然而,它的计算复杂度较高,对于大型图像或复杂形状的检测可能会消耗较多的计算资源。

在Emgu.CV中,霍夫变换相关的函数有CvInvoke.HoughLinesP用于检测直线线段,CvInvoke.HoughLines用于直线检测,CvInvoke.HoughCircles用于圆检测等。这些函数可以方便地在图像中进行霍夫变换来检测不同形状的目标。

6.4.1 HoughLines 

CvInvoke.HoughLines方法用于在图像中检测直线。该函数会返回检测到的直线的参数。该方法声明如下:

Public Shared Sub HoughLines(image As Emgu.CV.IInputArray, lines As Emgu.CV.IOutputArray, rho As Double, theta As Double, threshold As Integer, Optional srn As Double = 0, Optional stn As Double = 0)

参数说明:

  1. Image:输入源图像(一般为8位单通道二值图像)。
  2. lines:经过霍夫变换后检测线条的输出矢量。这里传入VectorOfPointF类型变量。返回的每一条线由两个元素的矢量(ρ, θ)表示, 其中ρ是离坐标原点的距离, θ是弧度线条旋转角度(0表示垂直线, n / 2度表示水平线)。
  3. rho:以像素为单位的距离精度, 可以认为是直线搜索时的步进尺寸的单位半径。
  4. theta:以弧度为单位的角度精度, 可以认为是直线搜索时的步进尺寸的角度单位,常设为 Math.PI / 180。
  5. threshold:直线检测的阈值,只有当检测到的点数大于该阈值时才认为是直线。
  6. srn:控制距离分辨率。将距离分辨率除以srn+1,从而减小距离分辨率。其默认值为0。该参数的值越大,累加器空间的距离分辨率就越低,检测到的直线数量也会相应地减少。
  7. stn:控制角度分辨率。将角度分辨率除以stn+1,从而减小角度分辨率。其默认值为0。该参数的值越大,累加器空间的角度分辨率就越低,检测到的直线数量也会相应地减少。

【代码位置:frmChapter6】Button16_Click

   'HoughLines

    Private Sub Button16_Click(sender As Object, e As EventArgs) Handles Button16.Click

        Dim m1 As New Mat("C:\learnEmgucv\line.jpg", CvEnum.ImreadModes.AnyColor)

        '边缘检测

        Dim mid1 As New Mat

        CvInvoke.Canny(m1, mid1, 80, 255, 3)

        '二值化

        Dim mid2 As New Mat

        CvInvoke.Threshold(mid1, mid2, 125, 255, ThresholdType.Binary)

        ImageBox1.Image = mid2

        'HoughLines检测直线

        Dim outlines As New  VectorOfPointF

        CvInvoke.HoughLines(mid2, outlines, 1, Math.PI / 180, 250, 0, 0)

        Dim m2 As New Mat

        m2 = mid1.Clone()

        m2.SetTo(New MCvScalar(0))

        '计算每条直线的起始坐标,并绘制出来

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

            Dim line As PointF = outlines(i)

            Dim rho As Double = line.X

            Dim theta As Double = line.Y

            Dim a As Double = Math.Cos(theta)

            Dim b As Double = Math.Sin(theta)

            Dim x0 As Double = rho * a

            Dim y0 As Double = rho * b

            Dim pt1 As New Point

            pt1.X = Math.Round(x0 + m2.Cols * (-b))

            pt1.Y = Math.Round(y0 + m2.Rows * a

            Dim pt2 As New Point

            pt2.X = Math.Round(x0 - m2.Cols * (-b))

            pt2.Y = Math.Round(y0 - m2.Rows * a)

            '绘制直线

            CvInvoke.Line(m2, pt1, pt2, New MCvScalar(255), 2)

        Next

        ImageBox2.Image = m2

        '减少检测到的点数

        Dim outlines3 As New VectorOfPointF

        CvInvoke.HoughLines(mid2, outlines3, 1, Math.PI / 180, 120, 0, 0)

        Dim m3 As New Mat

        m3 = mid1.Clone()

        m3.SetTo(New MCvScalar(0))

        Dim length3 As Double = Math.Max(m3.Rows, m3.Cols)

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

            Dim line As PointF = outlines3(i)

            Dim rho As Double = line.X

            Dim theta As Double = line.Y

            Dim a As Double = Math.Cos(theta)

            Dim b As Double = Math.Sin(theta)

            Dim x0 As Double = rho * a

            Dim y0 As Double = rho * b

            Dim pt1 As New Point

            pt1.X = Math.Round(x0 + m2.Cols * (-b))

            pt1.Y = Math.Round(y0 + m2.Rows * a)

            Dim pt2 As New Point

            pt2.X = Math.Round(x0 - m2.Cols * (-b))

            pt2.Y = Math.Round(y0 - m2.Rows * a)

            CvInvoke.Line(m3, pt1, pt2, New MCvScalar(255), 2)

        Next

        ImageBox3.Image = m3

End Sub

运行后如下图所示:

图6-17 直线检测结果

6.4.2 HoughLinesP        

CvInvoke.HoughLinesP方法用于在图像中检测线段。该方法的两个声明如下:

Public Shared Sub HoughLinesP(image As Emgu.CV.IInputArray, lines As Emgu.CV.IOutputArray, rho As Double, theta As Double, threshold As Integer, Optional minLineLength As Double = 0, Optional maxGap As Double = 0)

Public Shared Function HoughLinesP(image As Emgu.CV.IInputArray, rho As Double, theta As Double, threshold As Integer, Optional minLineLength As Double = 0, Optional maxGap As Double = 0) As Emgu.CV.Structure.LineSegment2D()

参数解释:

  1. image:输入图像(Image(Of Gray, Byte)类型)。
  2. lines:经过霍夫变换后检测线条的输出矢量。VectorOfRect类型,每个成员是一个Rectangle类型,属性X 、Y、Width、Height分别表示第一个点的X、第一个点的Y,第二个点的X、第二个点的Y。
  3. rho:以像素为单位的距离精度。
  4. theta:以弧度为单位的角度精度。
  5. threshold:直线检测的阈值,只有当检测到的点数大于该阈值时才认为是直线。
  6. minLineLength:线段的最小长度,小于该长度的线段将被忽略。
  7. maxLineGap:线段之间的最大间隔,超过该间隔的线段将被认为是不同的线段。

返回值:

检测到的线段数组(LineSegment2D()类型)。

【代码位置:frmChapter6】Button17_Click

    'HoughLinesP

    Private Sub Button17_Click(sender As Object, e As EventArgs) Handles Button17.Click

        Dim m1 As New Mat("C:\learnEmgucv\line.jpg", CvEnum.ImreadModes.AnyColor)

        '边缘检测

        Dim mid1 As New Mat

        CvInvoke.Canny(m1, mid1, 80, 255, 3)

        '二值化

        Dim mid2 As New Mat

        CvInvoke.Threshold(mid1, mid2, 125, 255, ThresholdType.Binary)

        ImageBox1.Image = mid2

        Dim outlines() As LineSegment2D

        outlines = CvInvoke.HoughLinesP(mid2, 1, Math.PI / 180, 100, 0, 0)

        Dim m2 As New Mat

        m2 = mid1.Clone()

        m2.SetTo(New MCvScalar(0))

        '绘制检测出的线段

        For i As Integer = 0 To outlines.Length - 1

            CvInvoke.Line(m2, outlines(i).P1, outlines(i).P2, New MCvScalar(255), 2)

        Next

        ImageBox2.Image = m2

        Dim outlines2 As New VectorOfRect()

        CvInvoke.HoughLinesP(mid2, outlines2, 1, Math.PI / 180, 100 5 30)

        Dim m3 As New Mat

        m3 = mid1.Clone()

        m3.SetTo(New MCvScalar(0))

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

            CvInvoke.Line(m3, New Point(outlines2(i).X, outlines2(i).Y), New Point(outlines2(i).Width, outlines2(i).Height), New MCvScalar(255), 2)

        Next

        ImageBox3.Image = m3

End Sub

运行后如下图所示:

图6-18 线段检测结果

6.4.3 HoughCircles

CvInvoke.HoughCircles函数用于在图像中检测圆形,该方法声明如下:

Public Shared Function HoughCircles(image As Emgu.CV.IInputArray, method As Emgu.CV.CvEnum.HoughModes, dp As Double, minDist As Double, Optional param1 As Double = 100, Optional param2 As Double = 100, Optional minRadius As Integer = 0, Optional maxRadius As Integer = 0) As Emgu.CV.Structure.CircleF()

参数说明:

  1. image:8位单通道灰度源图像(或者传入的源图像是Image(Of Gray, Byte)类型)。
  2. method:霍夫变换的方法,可以选择HoughType.Gradient或HoughType.GradientAlt。
  3. dp:累加器图像的分辨率与输入图像的分辨率之比。例如,dp = 1,则累加器具有与输入图像相同的分辨率。如果dp = 2,则累加器的宽度和高度都是一半。
  4. minDist:检测到的圆心之间的最小距离,太小会多检,太大会漏检。
  5. param1:Canny边缘检测的高阈值。
  6. param2:圆心累加器阈值,只有当累加器图像中的值大于该阈值时才认为是圆心。相应的该阈值越小,可得到越多的圆。
  7. minRadius:达到检测要求的最小圆半径。
  8. maxRadius:达到检测要求的最大圆半径。

返回值:

检测到的圆形数组(CircleF()类型)。

【代码位置:frmChapter6】Button18_Click

    'HoughCircles

    Private Sub Button18_Click(sender As Object, e As EventArgs) Handles Button18.Click

        Dim m1 As New Mat("C:\learnEmgucv\aoyun.jpg", CvEnum.ImreadModes.Grayscale)

        ImageBox1.Image = m1

        Dim mid1 As New Mat

        CvInvoke.GaussianBlur(m1, mid1, New Drawing.Size(3, 3), 3)

        ImageBox2.Image = mid1

        Dim outcircle() As CircleF

        outcircle = CvInvoke.HoughCircles(mid1, HoughModes.Gradient, 2, 50, 140, 220, 5)

        Dim m2 As New Mat

        m2 = mid1.Clone()

        m2.SetTo(New MCvScalar(255))

        For i As Integer = 0 To outcircle.Length - 1

            CvInvoke.Circle(m2, New Point(Integer.Parse(outcircle(i).Center.X), Integer.Parse(outcircle(i).Center.Y)), outcircle(i).Radius, New MCvScalar(0), 2)

        Next

        ImageBox3.Image = m2

End Sub

运行后如下图所示:

图6-19 圆形检测结果

另外一个例子,代码同上,只是载入的图片不同:

【代码位置:frmChapter6】Button19_Click

……

     Dim m1 As New Mat("C:\learnEmgucv\Matchimg.jpg", CvEnum.ImreadModes.Grayscale)

……

运行后如下图所示:

图6-20 圆形检测结果

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部