编程获取图像中的圆半径

news2024/11/18 1:24:00

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

即将推出EmguCV的教程,请大家还稍作等待。

之前网友咨询如何获得图像中圆形的半径,其中有两个十字作为标定,十字之间距离为100mm。如下图:

说实在的,单靠VB.net很难获得相关圆形信息,为了弥补这部分知识,下定决心学习了EmguCV。以下是具体代码:https://blog.csdn.net/UruseiBest

        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)


        '获得所有轮廓 https://blog.csdn.net/UruseiBest
        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

        '绘制轮廓 https://blog.csdn.net/UruseiBest
        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)

        '得到两个相交点 https://blog.csdn.net/UruseiBest
        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)
        '获得外接圆形 https://blog.csdn.net/UruseiBest
        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

        '图像中的圆半径 https://blog.csdn.net/UruseiBest
        Dim radius As Double
        radius = (perimeter / Math.PI) / 2

        '实际圆半径
        Dim realradius2 As Double
        realradius2 = proportion * radius

        MessageBox.Show("最小外接圆来计算实际圆半径:" & realradius1 & ControlChars.CrLf &
                        "基于轮廓周长来计算实际圆半径:" & realradius2)

这个网友当时提出来问题的时候,我还没有办法解决,不过经过不断学习,目前已经学习了不少相关知识,至少可以获得圆半径了,还是略微感到欣慰。 

关于EmguCV的知识,下一步整理出来。

由于.net平台下C#和vb.NET很相似,本文也可以为C#爱好者提供参考。

学习更多vb.net知识,请参看vb.net 教程 目录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1011907.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何实现一个简单的深度优先搜索(DFS)算法?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 实现深度优先搜索⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前…

Qt Quick 之 QML 与 C++ 混合编程详解

Qt Quick 之 QML 与 C 混合编程详解 一、Qt Quick 之 QML 与 C 混合编程详解在 QML 中使用 C 类和对象实现可以导出的 C 类Q_INVOKABLE 宏Q_ENUMSQ_PROPERTY注册一个 QML 中可用的类型注册 QML 类型在 QML 中导入 C 注册的类型完整的 colorMaker 实例导出一个 C 对象为 QML 的属…

伴随矩阵与可逆矩阵

目录 伴随矩阵的概念与公式 可逆矩阵的概念与定理 逆矩阵的运算性质 伴随矩阵的概念与公式 伴随矩阵是一个与给定矩阵相关的矩阵&#xff0c;它的元素是给定矩阵的代数余子式。 给定一个nn的方阵A&#xff0c;其元素为aij&#xff0c;则A的伴随矩阵adj(A)是一个nn的方阵&…

EDI 许可证申请对网站有哪些要求?

EDI 许可证申请对网站有哪些要求&#xff1f; 1、电商类平台&#xff1b; 2、二手交易类平台&#xff1b; 3、外卖类平台&#xff1b; 4、票务交易类平台&#xff1b; 5、智能数据处理平台。 ​网站如果是上述类型&#xff0c;那就要办理EDI许可证&#xff0c;但EDI许可证…

北航投资携核心医疗获2023年度十佳投资案例

近日&#xff0c;全球PE论坛联合财新数据发布了2022-2023年度中国PE/VC行业评选结果&#xff0c;北航投资携核心医疗荣获2022-2023年度中国PE/VC十佳投资案例大奖。 经过7年的发展&#xff0c;北航投资的各项业务正密集地进入收获期&#xff0c;业务增长飞轮持续加速&#xff0…

vue拖拽插件 - Sortable

官网地址&#xff1a;Sortable.js中文网 使用方法&#xff1a; 1. npm安装 npm install sortablejs --save 2. 在组件中引入插件 import Sortable from "sortablejs"; 3. 给要拖动的table加上id用来获取dom&#xff0c;记得加row-key&#xff0c;不然会有显示问题 …

苹果“FindMy”APP

“FindMy”是一项 Apple 服务&#xff0c;可以定位设备。在 iOS 13 之前&#xff0c;Apple将该服务拆分为单独的应用程序&#xff1a;“查找我的 iPhone”&#xff08;或 iPad 或 Mac&#xff09;和“查找我的朋友”。该服务适用于iPhone、iPad、Mac、Apple Watch、AirPods、Ai…

麒麟v10安装Redis(ARM架构)

下载Redis安装包 华为开源镜像站_软件开发服务_华为云 上面的选择一个下载 或者用命令下载 wget https://repo.huaweicloud.com/kunpeng/yum/el/7/aarch64/Packages/bigdata/redis-5.0.5-1.el7.aarch64.rpm 检查是否已经安装Redis rpm -qa | grep redis将包卸载掉 rpm -e -…

AGV小车、机械臂协同作业实战03-opentcs5.9 运行体验

openTCS的控制核心是kernel&#xff0c;其内部有三种算法&#xff0c;分别为Dispater、Router、Scheduler。 本文主要介绍如何利用openTCS的plant overview平台进行基本的操作&#xff0c;主要内容来源于该软件内自带的opentcs-users-guide手册。 启动客户端 openTCS-Kernel…

Python中RESTful API的常见问题

RESTful API&#xff08;Representational State Transfer&#xff09;是一种设计风格&#xff0c;用于构建可扩展的和易于维护的Web服务。Python作为一门流行的编程语言&#xff0c;提供了丰富的库和工具来构建和实现RESTful API。然而&#xff0c;在实践过程中&#xff0c;我…

Matlab 分析 rosbag

在机器人的开发中&#xff0c;通常会使用rosbag工具来分析机器人的一些性能指标是否符合要求&#xff0c;在Windows平台&#xff0c;使用matlab分析rosbag是一个不错的选择&#xff0c;这里给出简单的使用示例&#xff1a; 示例&#xff1a;读取rosbag中机器人的位置信息&…

模拟实现C语言--strcmp函数

模拟实现C语言–strcmp函数 文章目录 模拟实现C语言--strcmp函数一、strcmp函数是什么&#xff1f;二、使用示例三、模拟实现3.1 模拟实现方式一3.2 模拟实现方式二 一、strcmp函数是什么&#xff1f; 字符串比较函数&#xff1a;比较的是对应位置的ASCII值 int strcmp ( con…

saml协议中生成jks

JKS简介 JKS是Java Key Store的缩写&#xff0c;是 Java 语言开发的一种密钥库格式&#xff0c;它包含了证书和私钥&#xff0c;可以用来加密、认证和签署数字信息。 环境 $ uname -a Linux yanlp 3.10.0-1160.92.1.el7.x86_64 #1 SMP Tue Jun 20 11:48:01 UTC 2023 x86_64 …

基于Qt实现的可视化大屏监控

基于Qt实现的可视化大屏监控 先上图 基于Qt实现的可视化大屏监控 总有人质疑QWidget实现不了炫酷的界面&#xff0c;其实QWidget已经很强大了&#xff0c;虽然很多效果没有现成的框架&#xff0c;所以比不上html5或者安卓这种&#xff0c;但是也能实现很多不错的效果了&#…

文案生成-帮助我们应对文案创作过程中的痛点

在数字化时代&#xff0c;文案生成变得前所未有的重要。从广告营销到社交媒体发布&#xff0c;从网站内容到产品描述&#xff0c;文案无处不在&#xff0c;它们不仅仅是文字的组合&#xff0c;更是一种引导、影响和唤起共鸣的力量。然而&#xff0c;随着文案需求的不断增长&…

云计算——ACA学习 云计算分类

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 公众号&#xff1a;网络豆 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a; 网络豆的主页​​​​​ 目录 写在前面 前期回顾 本期介绍 一.云计算分类 1.公有云…

【Anaconda】管理你的环境和包

Anaconda 管理环境与包 管理环境管理包 管理环境 查看环境 conda env list激活环境 # enname 替换为要激活的环境名称 conda activate envname创建环境 # myenv 为创建的环境的名称 # python3.8 为指定环境中py版本为3.8 conda create --name myenv python3.8删除环境 # myenv …

【web开发】8、Django(3)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、管理员1.表结构2.layout.html文件下添加管理员账号的导航3.urls.py文件&#xff08;POST请求传递nid&#xff09;4.form.py文件(密码加密&#xff0c;确认密…

辉瑞与吉利德科学:制药巨头的新冠病毒之战

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 总结&#xff1a; &#xff08;1&#xff09;猛兽财经认为&#xff0c;华尔街低估了辉瑞&#xff08;PFE&#xff09;和吉利德科学&#xff08;GILD&#xff09;的前景&#xff0c;因为它们在开发新冠病毒疫苗和药物方面都…

安达发|APS软件系统的发展进化史

从古至今&#xff0c;生产计划一直是制造业的核心。无论是古代的手工作坊&#xff0c;还是现代的自动化工厂&#xff0c;都需要一种有效的方法来安排和调度生产活动。这就是我们今天要谈论的主题——高级排产软件&#xff08;APS&#xff09;的起源和发展。 1. 初识APS&#xf…