EmguCV学习笔记 VB.Net 6.S 特别示例

embedded/2024/9/23 7:41:40/

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

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知识,请移步: .net>vb.net 教程 目录_vb中如何用datagridview-CSDN博客

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

 

6.S 特别示例

6.S.1图像中的圆半径

本示例来自一名网友咨询如何获得图像中圆形的半径,其中有两个十字作为标记,十字之间距离为100mm。如下图:

图6-28 根据给出的定位标记求圆半径

【代码位置:frmChapter6_S1】Button1_Click、PointFToPoint

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

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

        Dim mgray As New Mat()

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

        Dim kernel As New Mat

        kernel = CvInvoke.GetStructuringElement(ElementShape.Cross, New Drawing.Size(3, 3), New Point(-1, -1))

        Dim merode As New Mat        '

        '这里使用了2次迭代

        CvInvoke.Dilate(mgray, merode, kernel, New Point(-1, -1), 1, BorderType.Constant, Nothing)

        CvInvoke.Threshold(merode, merode, 200, 255, ThresholdType.BinaryInv)

        ImageBox1.Image = merode

        '获得所有轮廓

        Dim contours As New VectorOfVectorOfPoint

        Dim hierarchy As New VectorOfRect

        CvInvoke.FindContours(merode, contours, hierarchy, RetrType.List, ChainApproxMethod.ChainApproxSimple)

        Dim m2 As New Mat(merode.Size, DepthType.Cv8U, 1)

        m2.SetTo(New MCvScalar(0))

        '圆轮廓

        Dim contourCircle As VectorOfPoint

        '圆轮廓的周长

        Dim perimeter As Double

        '绘制轮廓

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

            Dim carea As VectorOfPoint = contours(i)

            '获得轮廓面积

            Dim area As Double = CvInvoke.ContourArea(carea, False)

            '符合条件时,绘制轮廓,排除圆形,只保留十字线

            '本图中圆形面积为2449,直线面积为8,需要根据实际情况调整

            If area < 200 Then

                CvInvoke.DrawContours(m2, contours, i, New MCvScalar(255), 0.4)

            Else

                '得到圆形,图像中只有三个轮廓:2个交叉十字线段、1个圆形

                '这里简化操作,否则在多个轮廓情况下,应获取最大面积的轮廓判断为圆形

                contourCircle = contours(i)

                '获取轮廓周长

                perimeter = CvInvoke.ArcLength(contourCircle, True)

            End If

        Next

        ImageBox1.Image = m2

        '使用HoughLinesP方法检测图像中的直线,并将其绘制到图像

        '因为本图中十字线上的线段较短,所以这里阈值设置很小

        Dim lines As LineSegment2D() = CvInvoke.HoughLinesP(m2, 1, Math.PI / 180, 5, 5, 80)

        Dim m3 As New Mat(merode.Size, DepthType.Cv8U, 3)

        m3.SetTo(New MCvScalar(0, 0, 0))

        For Each line As LineSegment2D In lines

            CvInvoke.Line(m3, line.P1, line.P2, New MCvScalar(0, 255, 0), 2)

        Next

        ImageBox2.Image = m3

        '对直线进行分类,将其分为垂直和水平两类:

        Dim verticalLines As New List(Of LineSegment2D)

        Dim horizontalLines As New List(Of LineSegment2D)

        '计算每条直线的倾斜角度来进行分类,

        '将倾斜角度在60 - 120度之间的直线划分为垂直类,

        '将倾斜角度在30 - 150度之间的直线划分为水平类。

        For Each line As LineSegment2D In lines

            Dim angle As Double = Math.Atan2(line.P2.Y - line.P1.Y, line.P2.X - line.P1.X) * 180 / Math.PI

            If angle < 0 Then angle += 180

            If angle > 60 AndAlso angle < 120 Then

                verticalLines.Add(line)

            ElseIf angle > 150 OrElse angle < 30 Then

                horizontalLines.Add(line)

            End If

        Next

        '对垂直和水平直线进行匹配,并计算十字中心点的位置:

        Dim intersections As New List(Of PointF)

        '得到两个相交点

        For Each verticalLine As LineSegment2D In verticalLines

            For Each horizontalLine As LineSegment2D In horizontalLines

                '基于图像中两条直线真实相交,

                '如果垂直线的中点X坐标在水平线两端点X坐标之间

                '那么,这条垂直线段和这条水平线段相交

                Dim centerX As Single = (verticalLine.P1.X + verticalLine.P2.X) / 2

                If horizontalLine.P1.X < horizontalLine.P2.X Then

                    If centerX > horizontalLine.P1.X And centerX < horizontalLine.P2.X Then

                        Dim intersectionPoint As New PointF(

                            (horizontalLine.P1.X + horizontalLine.P2.X + verticalLine.P1.X + verticalLine.P2.X) / 4,

                            (horizontalLine.P1.Y + horizontalLine.P2.Y + verticalLine.P1.Y + verticalLine.P2.Y) / 4

                        )

                        intersections.Add(intersectionPoint)

                    End If

                Else

                    If centerX > horizontalLine.P2.X And centerX < horizontalLine.P1.X Then

                        Dim intersectionPoint As New PointF(

                            (horizontalLine.P1.X + horizontalLine.P2.X + verticalLine.P1.X + verticalLine.P2.X) / 4,

                            (horizontalLine.P1.Y + horizontalLine.P2.Y + verticalLine.P1.Y + verticalLine.P2.Y) / 4

                        )

                        intersections.Add(intersectionPoint)

                    End If

                End If

            Next

        Next

        If intersections.Count <> 2 Then

            MessageBox.Show("未能获得两个十字线的交叉点")

            Exit Sub

        End If

        CvInvoke.Line(msrc, PointFToPoint(intersections(0)), PointFToPoint(intersections(1)), New MCvScalar(0, 255, 0), 2)

        CvInvoke.Imshow("m3", msrc)

        '计算两个交点的距离

        Dim distance As Double = Math.Sqrt(

            (intersections(0).X - intersections(1).X) ^ 2 +

            (intersections(0).Y - intersections(1).Y) ^ 2

        )

        '实际中两交点距离为100毫米,计算相应比例

        Dim proportion As Double = 100 / distance

        '以下是基于最小外接圆来计算实际圆半径

        Dim cf As CircleF

        cf = CvInvoke.MinEnclosingCircle(contourCircle)

        '获得外接圆形

        CvInvoke.Circle(msrc, New Point(CInt(cf.Center.X), CInt(cf.Center.Y)), cf.Radius, New MCvScalar(0, 0, 255), 2)

        CvInvoke.Imshow("m4", msrc)

        '实际圆半径

        Dim realradius1 As Double

        realradius1 = proportion * cf.Radius

        '以下是基于轮廓周长来计算实际圆半径

        '实际圆周长

        Dim realperimeter As Double = perimeter * proportion

        '图像中的圆半径

        Dim radius As Double

        radius = (perimeter / Math.PI) / 2

        '实际圆半径

        Dim realradius2 As Double

        realradius2 = proportion * radius

        MessageBox.Show("最小外接圆来计算实际圆半径:" & realradius1 & ControlChars.CrLf &

                        "基于轮廓周长来计算实际圆半径:" & realradius2)

    End Sub

输出结果如下图所示:

图6-29 求出的圆半径


http://www.ppmy.cn/embedded/102004.html

相关文章

【精选】基于python的影片数据爬取与数据分析

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

AutoGPT开源项目解读

AutoGPT开源项目解读 (qq.com) AutoGPT旨在创建一个自动化的自我改进系统&#xff0c;能够自主执行和学习各种任务 项目基本信息 首先阅读项目的README.md&#xff0c;下述代理和智能体两个名词可互换 项目简介&#xff1a;一个创建和运行智能体的工具&#xff0c;这些智能体…

分治,CF 1237C2 - Balanced Removals (Harder)

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 https://codeforces.com/problemset/problem/1237/C2 二、解题报告 1、思…

MybatisPlus的LambdaQueryWrapper用法

LambdaQueryWrapper<Tag> 是 MyBatis-Plus 框架中的一个功能强大的查询构造器&#xff0c;它用于构建 SQL 查询条件&#xff0c;特别是针对 Lambda 表达式的支持&#xff0c;使得代码更加简洁、类型安全。在这个例子中&#xff0c;LambdaQueryWrapper<Tag> 被用来构…

学习能力与研究能力

摘要: 学习就像搭金字塔, 研究就像挖井. 1. 什么是学习 学习 (study) 是获得技能、知识、方法的过程. 学习有两种模式: 一是直接获得前人总结的经验; 二是从数据中总结规律. 2. 什么是研究 研究 (research) 是对已有或新的问题进行探索, 获得新技能、新知识、新方法的过程.…

在 Spring Boot 中为 MyBatis 添加拦截器

在 Spring Boot 中为 MyBatis 添加拦截器以实现分表查询涉及几个步骤。以下是如何在 Spring Boot 应用中配置和使用 MyBatis 拦截器的指南&#xff0c;具体以分表查询为例&#xff1a; 创建拦截器 首先&#xff0c;定义一个自定义的 MyBatis 拦截器&#xff0c;实现 Intercept…

OpenCV图像拼接多频段融合源码重构

OpenCV图像拼接多频段融合源码重构 图像拼接是计算机视觉中的一个常见问题&#xff0c;OpenCV提供了十分完善的算法类库。作者使用OpenCV4.6.0进行图像拼接&#xff0c;其提供了包括曝光补偿、最佳缝合线检测以及多频段融合等图像拼接常用算法&#xff0c;测试发现多频段融合算…

Tomcat涡轮:企业级WEB动力引擎全解析

目录 一、WEB技术基础 1.1 HTTP协议和B/S结构 1.2 前端三大核心技术 二、WEB框架与资源访问 2.1 WEB资源和访问 2.2 后台应用架构 2.2.1 单体架构 2.2.2 微服务架构 2.2.3 单体架构和微服务比较 三、Tomcat的功能与安装 3.1 Tomcat简介 3.2 安装Tomcat ​编辑 3.…