EmguCV学习笔记 VB.Net 7.1 角点检测

news2024/11/15 21:55:45

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

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博客

 

7.1 角点检测

角点是特征点的一种,是指在图像中具有尖锐变化的像素点,例如像素值最大或最小的点、线段的顶点、两直线的交点等,它通常具有一些特征,如灰度值变化较大、梯度变化较大、边缘交汇处等。在计算机视觉领域中,角点通常被用作特征点的一种,用于目标检测、图像配准、三维重建等任务中。

7.1.1 ConvertScaleAbs

CvInvoke.ConvertScaleAbs用于对图像进行线性变换并将结果转换为无符号的8位整型图像。它可以将图像中的像素值进行缩放和偏移,常用于图像增强、特征提取等任务中。该方法的声明如下:

Public Shared Sub ConvertScaleAbs(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, scale As Double, shift As Double)

参数说明:

  1. src:要进行线性变换的源图像。
  2. dst:变换后的目标图像。
  3. scale:变换中的缩放比例。
  4. shift:变换中的偏移量。

注意:ConvertScaleAbs方法只能将结果转换为无符号的8位整型图像,如果需要转换为其他类型的图像(比如CV32F、Cv16U等),可以使用CvInvoke.ConvertScale方法。

【代码位置:frmChapter7】Button1_Click

    'ConvertScaleAbs

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

        Dim msrc As New Mat("c:\lessons\lena.jpg", ImreadModes.Color)

        ImageBox1.Image = msrc

        Dim mdst As New Mat

        CvInvoke.ConvertScaleAbs(msrc, mdst, 1.5, 10)

        ImageBox2.Image = mdst

End Sub

输出结果如下图所示:

图7-1 图像线性变换结果

可以看出,ConvertScaleAbs实际有两个作用:1、对图像像素点进行线性变换;2、对于非CV8U的图像,转为CV8U。

7.1.2 Normalize

CvInvoke.Normalize用于对图像进行归一化处理。它可以将图像中的像素值按照一定的规则进行缩放,使得像素值的范围在指定的范围内,常用于图像增强、特征提取等任务中。该方法的声明如下:

Public Shared Sub Normalize(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, Optional alpha As Double = 1, Optional beta As Double = 0, Optional normType As Emgu.CV.CvEnum.NormType = 4, Optional dType As Emgu.CV.CvEnum.DepthType = -1, Optional mask As Emgu.CV.IInputArray = Nothing)

参数说明:

  1. src:要进行归一化处理的源图像。
  2. dst:归一化处理后的图像。
  3. alpha:下限范围。
  4. beta:上限范围,只在normType =NormType.MinMax时起作用。。
  5. normType:归一化处理中的算法类型,这是一个NormType枚举类型,可以选择NormType.MinMax、NormType.L1、NormType.L2等。当设置为MinMax时,Normalize()会把原矩阵中的值范围从最小值-最大值,按比例变换到alpha-beta的范围。
  6. dType:归一化处理后的目标图像的深度类型。
  7. mask:可选参数,表示要进行归一化处理的像素点的掩码图像,只有掩码图像中像素值为非零的像素点才会进行归一化处理。

【代码位置:frmChapter7】Button2_Click

    'Normalize

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

        Dim msrc As New Mat("c:\lessons\lena.jpg", ImreadModes.Color)

        ImageBox1.Image = msrc

        Dim mdst As New Mat

        CvInvoke.Normalize(msrc, mdst, 50, 200, NormType.MinMax)

        ImageBox2.Image = mdst

End Sub

输出结果如下图所示:

图7-2 图像归一化处理

7.1.3 CornerHarris

Harris角点检测算法是一种经典的角点检测算法,由Chris Harris和Mike Stephens在1988年提出。该算法通过计算图像中每个像素的响应函数值,来确定图像中的角点位置。

在使用EmguCV进行图像处理时,CvInvoke.CornerHarris方法用于检测图像中的角点。该方法基于Harris角点检测算法,可以识别出图像中的角点位置,其声明如下:

Public Shared Sub CornerHarris(image As Emgu.CV.IInputArray, harrisResponse As Emgu.CV.IOutputArray, blockSize As Integer, Optional apertureSize As Integer = 3, Optional k As Double = 0.04, Optional borderType As Emgu.CV.CvEnum.BorderType = 4)

参数说明:

  1. image:待检测的图像。必须是CV8U或者CV32F的单通道图像。
  2. harrisResponse:输出的角点响应图像,存放Harris评价系数的矩阵,这是一个CV32F的单通道图像,和image图像大小一致。
  3. blockSize:以当前像素为中心的邻域大小。通常是一个大于1的奇数。
  4. apertureSize:Sobel算子的大小。通常是一个大于1的奇数。
  5. k:Harris评价系数的权重系数,通常取值范围为0.04- 0.06。
  6. borderType:边界模式,用于处理图像边界情况。

【代码位置:frmChapter7】Button3_Click

    'CornerHarris

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

        Dim m As New Mat("c:\lessons\chess.jpg", ImreadModes.Color)

        '获得灰度图像

        Dim mgray As New Mat

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

        ImageBox1.Image = mgray

        '大小同mgray,存放评价系数的CV32F矩阵

        Dim mhr As New Mat

        '检测角点

        CvInvoke.CornerHarris(mgray, mhr, 2, 3, 0.04)

        '归一化处理,之后处理的是存放评价系数的CV32F矩阵

        Dim mn As New Mat

        CvInvoke.Normalize(mhr, mn, 0, 255, NormType.MinMax)

        '图像转为CV8U

        Dim mabs As New Mat

        CvInvoke.ConvertScaleAbs(mn, mabs, 1, 0)

        '二值化

        Dim madp As New Mat

        CvInvoke.Threshold(mabs, madp, 100, 255, ThresholdType.Binary)

        '由于之前二值化了,这里只需要获得非0值的点

        Dim ps As New VectorOfPoint

        CvInvoke.FindNonZero(madp, ps)

        '绘制出角点

        Dim mdst As New Mat

        mdst = m.Clone

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

            CvInvoke.Circle(mdst, ps(i), 20, New MCvScalar(0, 0, 255), -1)

        Next

        ImageBox2.Image = mdst

End Sub

输出结果如下图所示:

图7-3 棋盘上的角点

7.1.4 CornerSubPix

在数字图像处理领域中,亚像素级别(Subpixel Level)指的是比像素级别更细小的精度。像素级别指的是图像上的最小单位,通常是一个正方形的颜色区域。而亚像素级别则指的是像素内部的更细小的精度,例如像素内部的小数点位数。使用亚像素级别的精度可以提高图像处理的精度和准确度。例如,在角点检测任务中,使用亚像素级别的定位可以提高角点定位的精度,从而提高图像特征匹配的准确度。使用亚像素级别的精度需要借助于一些图像处理算法,例如插值算法、滤波算法等。

在使用EmguCV进行图像处理时,CvInvoke.CornerSubPix方法用于在亚像素级别上对角点进行精确化处理。该方法通过迭代优化提高角点的精度和准确性。该方法声明如下:

Public Shared Sub CornerSubPix(image As Emgu.CV.IInputArray, corners As Emgu.CV.IInputOutputArray, win As System.Drawing.Size, zeroZone As System.Drawing.Size, criteria As Emgu.CV.Structure.MCvTermCriteria)

参数说明:

  1. image:待处理的图像。
  2. corners:角点的位置数组,通常是通过CornerHarris等方法检测到的初始角点。这个参数既是输入也是输出。
  3. win:表示搜索窗口的大小。通常是一个大于1的奇数,表示在某个角点周围的邻域内进行亚像素级别的优化。
  4. zeroZone:表示搜索窗口中心的边界区域,通常是一个Size对象,用于将搜索窗口的中心排除在优化过程之外。
  5. criteria:表示优化过程的迭代终止准则,它是一个McvTermCriteria类,可以设置最大迭代次数和最小变化量的阈值。其中:
    1. maxIter:最大迭代次数,当迭代次数达到该值时,迭代终止。
    2. epsilon:迭代精度,当每一步迭代的变化量小于该值时,迭代终止。

下面的代码表示最大迭代次数为30次,每一步迭代的变化量小于0.01时,迭代终止:

Dim criteria As New MCvTermCriteria(30, 0.01)

【代码位置:frmChapter7】Button4_Click、getMax、outputMatdata32F1C、PointFToPoint

'CornerSubPix

    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click

        Dim m As New Mat("c:\learnEmgucv\chess.jpg", ImreadModes.Color)

        '获得灰度图像

        Dim mgray As New Mat

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

        ImageBox1.Image = mgray

        '大小同mgray,存放评价系数的CV32F矩阵

        Dim mhr As New Mat

        '检测角点

        CvInvoke.CornerHarris(mgray, mhr, 2, 3, 0.04)

        Dim vopf As New VectorOfPointF

        vopf = outputMatdata32F1C(mhr)

        CvInvoke.CornerSubPix(mgray, vopf, New Drawing.Size(5, 5), New Drawing.Size(-1, -1), New MCvTermCriteria(100, 0.01))

        '绘制出角点

        Dim mdst As New Mat

        mdst = m.Clone

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

            CvInvoke.Circle(mdst, PointFToPoint(vopf(i)), 20, New MCvScalar(0, 0, 255), -1)

        Next

        ImageBox2.Image = mdst

    End Sub

    '获得矩阵中的最大值,用来后面计算阈值 '

    Private Function getMax(ByVal m As Mat) As Single

        Dim maxvalues() As Double

        Dim minvalues() As Double

        Dim maxposes() As Point

        Dim minposes() As Point

        '只能查找每个通道的最大值和最小值,而不是查找每个通道的所有最大值和最小值

        '最大值和最小值的位置,也只是返回最先的那个。

        m.MinMax(minvalues, maxvalues, minposes, maxposes)

        '返回矩阵中的最大值

        Return maxvalues(0)

    End Function

    '输出符合条件的点

    Private Function outputMatdata32F1C(ByVal m As Mat) As VectorOfPointF

        '设置阈值

        Dim threshold As Single

        threshold = 0.01 * getMax(m)

        '为了计算方便,将m转为Matrix

        '这里m32F,所以使用Single

        Dim matr As New Matrix(Of Single)(m.Size)

        'MatCopyTo方法

        m.CopyTo(matr)

        Dim corners As New VectorOfPointF

        Dim colcount As Integer = matr.Cols

        Dim rowcount As Integer = matr.Rows

        Dim lstPf As New List(Of PointF)

        For i As Integer = 0 To rowcount - 1

            For j As Integer = 0 To colcount - 1

                Dim outSingle As Single = matr(i, j)

                '存储大于阈值的点坐标

                If outSingle > threshold Then

                    lstPf.Add(New PointF(j, i))

                End If

            Next

        Next

        '获得VectorOfPointF

        corners.Push(lstPf.ToArray)

        Return corners

    End Function

    'PointFPoint方法

    Public Shared Function PointFToPoint(ByVal pf As PointF) As Point

        Return New Point(CInt(pf.X), CInt(pf.Y))

    End Function

输出结果如下图所示:

图7-4 棋盘上的角点

【代码位置:frmChapter7】Button5_Click

    '直接CornerHarrisCornerSubPix的比较

    Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click

        Dim m As New Mat("c:\learnEmgucv\lena.jpg", ImreadModes.Color)

        '获得灰度图像

        Dim mgray As New Mat

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

        '大小同mgray,存放评价系数的CV32F矩阵

        Dim mhr As New Mat

        '检测角点

        CvInvoke.CornerHarris(mgray, mhr, 2, 3, 0.04)

        '设定阈值

        Dim threshold As Single

        threshold = 0.01 * getMax(mhr)

        '二值化,分离不符合阈值的点

        Dim mtsd As New Mat

        CvInvoke.Threshold(mhr, mtsd, threshold, 255, ThresholdType.Binary)

        '获得非0值的点

        Dim ps As New VectorOfPoint

        CvInvoke.FindNonZero(mtsd, ps)

        '绘制出角点

        Dim mdst As New Mat

        mdst = m.Clone

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

            CvInvoke.Circle(mdst, ps(i), 2, New MCvScalar(0, 0, 255), -1)

        Next

        ImageBox1.Image = mdst

        Dim vopf As New VectorOfPointF

        vopf = outputMatdata32F1C(mhr)

        CvInvoke.CornerSubPix(mgray, vopf, New Drawing.Size(5, 5), New Drawing.Size(-1, -1), New MCvTermCriteria(100, 0.01))

        '绘制出角点

        Dim mdst2 As New Mat

        mdst2 = m.Clone

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

            CvInvoke.Circle(mdst2, PointFToPoint(vopf(i)), 2, New MCvScalar(0, 0, 255), -1)

        Next

        ImageBox2.Image = mdst2

End Sub

输出结果如下图所示:

图7-5 直接CornerHarris和CornerSubPix后的比较

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

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

相关文章

【React】跨域问题详解及解决方案

文章目录 一、什么是跨域问题?1. 同源策略的定义2. CORS 机制 二、在 React 项目中遇到的跨域问题常见的跨域错误信息 三、解决 React 中跨域问题的方法1. 在后端服务器上配置 CORS2. 在 React 项目中使用代理 (Proxy)2.1 使用 http-proxy-middleware 实现代理1. 安…

SAP主数据删除

项目场景: SAP项目上线初期,主数据批到相关的操作 操作描述 需要对供应商,客户,科目进行维护操作,比如这些数据创建错误,不想留一些垃圾数据在系统里面 解决方案: 事务代码:OBR2…

低侧与高侧电流检测对比

1 简介 在处理低至中等电流水平时,电阻电流检测广泛用于印刷电路板组件。使用这种技术,将一个已知的电阻 R分流器与负载串联,并测量电阻两端的电压以确定负载电流。如下图所示。 电流检测电阻器,也称为分流电阻器或简称为分流器&a…

Python TensorFlow实战篇

概述 本篇博客将详细介绍如何使用Python和TensorFlow解决实际问题,包括图像分类、序列预测以及模型部署等内容。我们将从以下几个方面进行深入探讨: 图像分类实战:使用卷积神经网络(CNN)进行图像分类。序列预测实战&…

模型 KT决策法

系列文章 分享 模型,了解更多👉 模型_思维模型目录。系统分析,明智选择。 1 KT决策法的应用 1.1 餐饮连锁店菜单更新 一家餐饮连锁店计划更新菜单,以吸引更多顾客并提高销售额。使用 KT 决策法(Kepner-Tregoe&#x…

哪些领域最适合采用音视频私有化解决方案?

随着数字化时代的到来,音视频通信已成为各行各业不可或缺的一部分,从企业内部沟通到在线教育、远程医疗、金融交易等,无一不依赖于稳定、高效且安全的音视频技术。然而,不同的行业对音视频通信的需求各不相同,尤其在数…

【Denuvo加密】黑神话悟空为什么没有破解版?Denuvo加密技术的详细解析与代码示例

文章目录 1. 引言2. 加密技术概述3. D加密技术的工作原理4. D加密技术的实现5. D加密技术的实际应用6.实现原理7. 本篇小结 更多相关内容可查看 1. 引言 随着游戏产业的蓬勃发展,游戏数据的保护成为了重要议题。《黑神话:悟空》作为一款备受期待的游戏&…

大型商业中心的绿色转型之路

在全球可持续发展浪潮的推动下,大型商业中心正悄然蜕变,从能源消耗大户转变为绿色运营的先锋。在这个转型的舞台上,商场电气管理者们以创新的智慧与坚定的决心,绘制出一幅幅节能减排、低碳生活的美好蓝图。 面对大型商业中心复杂…

职业本科物联网与智能感知实训室解决方案

一、前言 在当今这个数字化、智能化飞速发展的时代,物联网(IoT)与智能感知技术已成为推动产业升级、促进经济社会发展的重要力量。为了适应这一趋势,培养具备物联网技术应用与智能感知系统设计能力的高素质技术技能型人才&#xf…

遗传算法与深度学习实战(8)——使用遗传算法解决旅行商问题

遗传算法与深度学习实战(8)——使用遗传算法解决旅行商问题 0. 前言1. 旅行商问题2. NP 问题3. 构建 TSP 求解器小结系列链接 0. 前言 旅行商问题 (Traveling Salesman Problem, TSP) 是一个经典的优化问题,其目标是找到一条最短的路径&…

280Hz显示器怎么选

280Hz显示器怎么选?今天就给大家带来6大品牌和型号的280Hz显示器一起对比对比! 1.280Hz显示器 - HKC G27H3显示器 当电竞遇上显示器,就像是超级英雄找到了他的战衣,完美搭配,所向披靡。今天,我们要聊的这款…

XSS LABS - Level 15 过关思路

关注这个靶场的其他相关笔记:XSS - LABS —— 靶场笔记合集-CSDN博客 0x01:过关流程 进入靶场,老流程,右击查看网页源码,看看有没有接收传参并回显的位置: 可以发现,src 接收的参数被回显了&am…

探索未来交互——Open LLM VTuber:一款基于AI大模型的二次元虚拟主播

随着人工智能技术的飞速发展,虚拟主播(VTuber)行业迎来了全新的变革。本文将介绍一个令人兴奋的开源项目——Open LLM VTuber,这是一个本地运行的、可高度定制的虚拟主播平台,它不仅支持多种语言模型(LLM)、自动语音识别(ASR)和文本转语音(TTS)后端,而且能够跨操作…

SingleChildScrollView使用

Flutter 中,SingleChildScrollView(类比Android中的ScrollView) 是一个可以滚动单个子控件的小部件。当子控件的大小超过视图时,用户可以滚动以查看所有内容。SingleChildScrollView 通常用于创建可滚动的表单、列表或任何需要垂直…

使用C++和PCL创建模拟点云

【版权声明】本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。 参考书籍:《人工智能点云处理及深度学习算法》 本文为专栏《Python三维点云实战宝典》系列文章,专栏介绍地址“【python三维深度学习】python…

深入解析 ASP.NET 的 ViewState 反序列化漏洞

1. ViewState 基本知识 1.1 什么是 ViewState ViewState 是 ASP.NET(Active Server Pages .NET)框架用来保持页面状态的一种机制。ASP.NET 是微软开发的用于动态网页服务器端开发的框架,ViewState 是其中用于维护和管理页面状态的一部分。…

netty编程之结合springboot一起使用

写在前面 源码 。 本文看下netty结合springboot如何使用。 1:netty server部分 server类(不要main,后续通过springboot来启动咯!): package com.dahuyou.netty.springboot.server;import io.netty.bootstrap.Serve…

设置视图的宽高

AndroidManifest.xml <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"><applicationandroid:allowBackup"true"android:icon"mipmap/ic_launcher…

JS 实现栈和队列

JS实现栈和队列 栈是先进后出 function Stack() {this.arr [];// push方法是把数据放入栈中this.push function (value) {this.arr.push(value);}// pop 是取数组的最后一个数据&#xff0c;从而实现先进后出this.pop function () {this.arr.pop();} }var stack new Stac…

Spring如何既返回实体同时下载文件

业务背景&#xff1a;下载文件的接口需要返回文件信息或者密码等信息&#xff0c;这时候就需要接口返回文件及相关实体信息&#xff1b; 在Spring中&#xff0c;如果你需要在同一个请求中既下载文件也返回一个实体信息&#xff0c;你需要特别注意HTTP协议本身并不直接支持这种操…