当前位置: 首页 > news >正文

EmguCV学习笔记 VB.Net 6.4 霍夫变换

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

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 圆形检测结果

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 2024 实训室建设:1+X 老年生活照护实训室
  • 实用工具:[TrafficMonitor]任务栏电脑性能监控安装指南
  • x-cmd mod | x scoop - Windows 开源包管理工具
  • 【自动驾驶】控制算法(三)轮胎侧偏与车辆动力学模型
  • Prettier+Vscode setting提高前端开发效率
  • 单片机使用cJSON的坑
  • Spring的bean的生命周期
  • 深度学习100问6-什么是向量降维
  • 游戏开发设计模式之命令模式
  • Mysql语句性能优化
  • 中国数据库的崛起:从本土化挑战到全球化机遇
  • PCIE-Precode
  • 双系统安装:一键解锁电脑新境界,Windows与Linux并肩作战!
  • 华为自研仓颉编程语言测试版上线,计划持续到10月21号
  • 【操作系统】11.什么是文件?
  • canvas 绘制双线技巧
  • Centos6.8 使用rpm安装mysql5.7
  • el-input获取焦点 input输入框为空时高亮 el-input值非法时
  • Javascript 原型链
  • JavaWeb(学习笔记二)
  • JDK9: 集成 Jshell 和 Maven 项目.
  • LeetCode算法系列_0891_子序列宽度之和
  • Linux中的硬链接与软链接
  • Protobuf3语言指南
  • python 学习笔记 - Queue Pipes,进程间通讯
  • Python利用正则抓取网页内容保存到本地
  • Ruby 2.x 源代码分析:扩展 概述
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 大数据与云计算学习:数据分析(二)
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 利用DataURL技术在网页上显示图片
  • 聊聊flink的TableFactory
  • 普通函数和构造函数的区别
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 微服务框架lagom
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • 在Mac OS X上安装 Ruby运行环境
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • #Linux(权限管理)
  • $LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (floyd+补集) poj 3275
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (二开)Flink 修改源码拓展 SQL 语法
  • (附源码)spring boot基于小程序酒店疫情系统 毕业设计 091931
  • (九十四)函数和二维数组
  • (三)Kafka 监控之 Streams 监控(Streams Monitoring)和其他