【持续更新篇】SLAM视觉特征点汇总+ORB特征点+VINS前端
Harris角点
opencv函数
cornerHarris提取输入图像的Harris角点
检测原理
检测思想:使用一个固定窗口在图像上进行任意方向的滑动,对比滑动前后的窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有较大灰度变化,则认为该窗口中存在角点。
E(u,v)=∑(x,y)∈Ww(x,y)[I(x+u,y+v)−I(x,y)]2E(u, v)=\sum_{(x, y) \in W} w(x, y)[I(x+u, y+v)-I(x, y)]^{2}E(u,v)=∑(x,y)∈Ww(x,y)[I(x+u,y+v)−I(x,y)]2
当窗口滑动时,滑动前后对应的窗口中的像素点灰度变化为E(u,v)E(u, v)E(u,v)
对E(u,v)E(u, v)E(u,v)进行泰勒展开,对公式进行化简,最终得到:
E(u,v)=[uv]M[uv]E(u, v)=\left[\begin{array}{ll}u & v\end{array}\right] M\left[\begin{array}{l}u \\ v\end{array}\right]E(u,v)=[uv]M[uv]
其中M为:
M=∑(x,y)∈Ww(x,y)[Ix2IxIyIxIyIy2]M = \sum_{(x, y) \in W} w(x, y)\left[\begin{array}{cc}I_{x}^{2} & I_{x} I y \\I_{x} I_{y} & I_{y}^{2}\end{array}\right]M=∑(x,y)∈Ww(x,y)[Ix2IxIyIxIyIy2]
IxI_xIx为图像在x方向的梯度,y方向同理。
如果M没有梯度变化较大的点,则当前没有角点或边缘点。如果M只在一个方向上有梯度变化很大的点,则当前可能只有边缘点。若M在xy方向上均变换很大,则当前框内有角点。
角点相应得分:
R=det(M)−k(trace(M))2R=\operatorname{det}(M)-k(\operatorname{trace}(M))^{2}R=det(M)−k(trace(M))2
其中
det(M)=λ1λ2\operatorname{det}(M)=\lambda_{1} \lambda_{2}det(M)=λ1λ2
trace(M)=λ1+λ2\operatorname{trace}(M)=\lambda_{1}+\lambda_{2}trace(M)=λ1+λ2
kkk在0.04到0.06之间。λ1λ2\lambda_{1} \lambda_{2}λ1λ2为MMM的两个特征值。
Harris角点性质
- 增大K值可以降低角点检测的灵敏度,减少被检测角点的数量
- Harris角点对亮度和对比度变化不灵敏
- Harris角点具有旋转不变性
- Harris角点不具有尺度不变性
FAST角点
opencv函数
fast = cv.FastFeatureDetector_create(threshold,nonmaxSuppression)
kp = fast.detect(Img, None)
cv.drawKeypoints (image,keypoints,outputimage,color,flags)
检测原理
取图像中的检测点,以该点为圆心的周围邻域内像素点判断检测点是否为角点。如果圆上有连续N个点的亮度大于或者小于阈值(如选取检测点的亮度的120%或80%),则认为该检测点为特征点。根据N的取值分为FAST-9,FAST-12等。
FAST加速方法
在FAST-12中可以检测圆上第1、5、9、13的像素的亮度,如果这四个像素中有三个同时大于或小于阈值,则该检测点才有可能是特征点,否则直接排除。
非极大值抑制
FAST角点会出现扎堆的现象,因此在第一遍检查过后还要使用非极大值抑制,在一定区域内仅保留响应极大值的角点,避免角点集中的问题。
FAST特征点性质
FAST特征点不具有方向信息和尺度信息。所以ORB在FAST基础上添加了图像金字塔解决尺度问题,添加灰度质心法解决特征的旋转问题。
SIFT特征点
src = cv.imread("123.png")
cv.namedWindow("input", cv.WINDOW_AUTOSIZE)
cv.imshow("input", src)
sift = cv.xfeatures2d.SIFT_create()
kps = sift.detect(src)
result = cv.drawKeypoints(src, kps, None, (0, 0, 255), cv.DrawMatchesFlags_DEFAULT)
cv.imshow("sift-detector", result)
SIFT原理
大致来说就是将图像进行多次下采样,构建出图像金字塔。
但是每层金字塔不止一张图像,而是类似于下面的一组图像。
原理是使用一个变化尺度的高斯函数与原图像进行卷积:
L(x,y,σ)=G(x,y,σ)∗I(x,y)L(x, y, \sigma)=G(x, y, \sigma) * I(x, y)L(x,y,σ)=G(x,y,σ)∗I(x,y)
其中高斯函数为:
G(x,y,σ)=12πσ2e−(x−m/2)2+(y−n/2)22σ2G(x, y, \sigma)=\frac{1}{2 \pi \sigma^{2}} e^{-\frac{(x-m / 2)^{2}+(y-n / 2)^{2}}{2 \sigma^{2}}}G(x,y,σ)=2πσ21e−2σ2(x−m/2)2+(y−n/2)2
然后
画叉的特征点需要和本层的8个点外加上下两层的9个点共26个点比较,若为最大值或最小值,则认为该点是初步判断的一个特征点。
关键点剔除工作
因为我们得到的特征点可能并不是真正的极值点,因此我们将得到离散空间点进行拟合,求出真正的极值点。
我们将检测得到的特征点反复的向计算出的极值点的方向进行偏移(实际是导数为0的方向),排除掉超出设定的迭代次数依然不能收敛的特征点和超出图像边界的特征点。同时也要排除数值小于某个经验值的特征点(如小于0.03或0.04),因为这种数值小的点容易收到噪声的干扰。
这步完成后,我们还需要去掉边缘点。我们初步检测出来的特征点有很多都是在边缘处,因为边缘点有较大的响应,但是这种响应也只发生在一个方向,因此采用了类似于Harris角点的检测方法,求出该检测点在两个方向的Hession矩阵,计算Hession矩阵的特征值,如果两个特征值的和的平方除以两特征值的积小于设定的阈值(如1.2),则认为该点并不是边缘点,保留。
主方向分配
简单点说就是求出特征点的所有邻域梯度的方向,然后统计一下,哪种方向最大则认为该特征点的梯度方向,再选一个大于主梯度80%的方向作为辅方向,增加鲁棒性。
描述子
在关键点的44的窗口中计算分别计算八个方向的梯度作为该特征点的描述子,维度为44*8=128维
检测匹配方法
Kd平衡二叉树,查找与目标图像的特征点最邻近的原图像特征点和次邻近的原图像特征点
SIFT特征点性质
- 检测非常稳定,应用广泛
- 计算量大,很难做到实时
SURF特征点
opencv函数
img = cv.imread('photo.png',0)
surf = cv.xfeatures2d.SURF_create(400)
kp, des = surf.detectAndCompute(img,None)
len(kp)
检测原理(类比SIFT)
Hessian矩阵近似
给定图像中一点,可以确定如下的Hessian矩阵:
H(x,y,σ)=(LxxLxyLxyLyy)H(x, y, \sigma)=\left(\begin{array}{ll} L_{x x} & L_{x y} \\ L_{x y} & L_{y y} \end{array}\right)H(x,y,σ)=(LxxLxyLxyLyy)
其中σ\sigmaσ为尺度大小
计算Hessian矩阵的行列式值DoH为:
detH=LxxLyy−Lxy2\operatorname{det} H=L_{x x} L_{y y}-L_{x y}^{2}detH=LxxLyy−Lxy2
因为此处是对Hessian矩阵进行处理,所以会自动过滤掉边缘点。
检测时选择不同大小的σ\sigmaσ生成不同的高斯卷积模版,同样生成图像金字塔,然后在不同位置空间和尺度空间搜索DoH的峰值(同样是26个点),并进行非极大值抑制,得到图像的极值点。
实际运用中对高斯滤波和行列式的计算进行了简化
与SIFT特征点不同的
- SURF并没有通过降采样的方式得到不同尺寸大小的图像建立金字塔,而是借助于不同的σ\sigmaσ构造金字塔。
- 特征点的主方向SIFT在方形邻域窗口内统计梯度方向直方图,而SURF在圆形区域内计算各个扇形范围内的方向,取响应累加和最大的扇形方向。
- 特征描述子,SIFT将关键点附近的邻域划分成4*4的区域,统计每个子区域的梯度方向直方图,统计成128维特征向量。SURF将20乘20像素点的邻域划分成4乘4个子块,计算每个子块的Haar小波响应,并统计4个特征量,得到4乘4乘4=64维度的特征向量。
BRIEF描述子
描述子原理
BRIEF是一种二进制的描述子,其描述向量是0和1表示的二进制串。0和1表示特征点邻域内两个像素(p和q)灰度值的大小:如果p比q大则选择1,反正就取0。在特征点的周围选择128对这样的p和q的像素对,就得到了128维由0,1组成的向量。
BRIEF使用随机选点的比较,速度很快,而且使用二进制串表示最终生成的描述子向量,在存储以及用于匹配的比较时都是非常方便的,其和FAST的搭配起来可以组成非常快速的特征点提取和描述算法。
ORB特征点提取opencv特征点与匹配
源代码来源
import cv2 as cvdef ORB_Feature(img1, img2):# 初始化ORBorb = cv.ORB_create()# 寻找关键点kp1 = orb.detect(img1)kp2 = orb.detect(img2)# 计算描述符kp1, des1 = orb.compute(img1, kp1)kp2, des2 = orb.compute(img2, kp2)# 画出关键点outimg1 = cv.drawKeypoints(img1, keypoints=kp1, outImage=None)outimg2 = cv.drawKeypoints(img2, keypoints=kp2, outImage=None)# 显示关键点# import numpy as np# outimg3 = np.hstack([outimg1, outimg2])# cv.imshow("Key Points", outimg3)# cv.waitKey(0)# 初始化 BFMatcherbf = cv.BFMatcher(cv.NORM_HAMMING)# 对描述子进行匹配matches = bf.match(des1, des2)# 计算最大距离和最小距离min_distance = matches[0].distancemax_distance = matches[0].distancefor x in matches:if x.distance < min_distance:min_distance = x.distanceif x.distance > max_distance:max_distance = x.distance# 筛选匹配点'''当描述子之间的距离大于两倍的最小距离时,认为匹配有误。但有时候最小距离会非常小,所以设置一个经验值30作为下限。'''good_match = []for x in matches:if x.distance <= max(2 * min_distance, 30):good_match.append(x)# 绘制匹配结果draw_match(img1, img2, kp1, kp2, good_match)def draw_match(img1, img2, kp1, kp2, match):outimage = cv.drawMatches(img1, kp1, img2, kp2, match, outImg=None)cv.imshow("Match Result", outimage)cv.waitKey(0)if __name__ == '__main__':# 读取图片image1 = cv.imread('1.png')image2 = cv.imread('2.png')ORB_Feature(image1, image2)
VINS前端光流法
vins-mono前端流程
光流追踪:基于灰度不变假设,以上一帧的特征点坐标为起点,在当前帧的同样的坐标下以一定范围找到与上一帧特征点附近区域灰度值相近的区域。
图像金字塔:vins中把上一层图像金字塔追踪的结果作为下一帧图像金字塔追踪的初值。保证了像素精度又保证了追踪结果在还原时的准确度。
相关文章:

【持续更新篇】SLAM视觉特征点汇总+ORB特征点+VINS前端
Harris角点 opencv函数 cornerHarris提取输入图像的Harris角点 检测原理 检测思想:使用一个固定窗口在图像上进行任意方向的滑动,对比滑动前后的窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有较大灰度变化…...

【C语言】初阶指针(指针及其类型以及野指针)
简单不先于复杂,而是在复杂之后。 目录 1. 指针是什么? 2. 指针和指针类型 2.1 指针-整数 2.2 指针的解引用 3. 野指针 3.1 野指针成因 3.2 如何规避野指针 1. 指针是什么? 指针理解的两个要点: 1. 指针是内存中最小…...

UDS统一诊断服务【六】访问时序参数0X83服务
文章目录前言一、访问时序参数服务介绍二、数据格式2.1 请求报文2.2 子功能2.3 响应三、举例前言 本文介绍UDS统一诊断服务的访问时序参数0X83服务,希望能对你有所帮助 一、访问时序参数服务介绍 这个服务我目前在项目中没怎么用到过,先来看看ISO14229…...

Linux应用编程(文件属性与目录)
本章将会讨论如下主题内容。 ⚫ Linux 系统的文件类型; ⚫ stat 系统调用; ⚫ 文件各种属性介绍:文件属主、访问权限、时间戳; ⚫ 符号链接与硬链接; ⚫ 目录; ⚫ 删除文件与文件重命名。 一、Linux 系统中…...

第十四届蓝桥杯嵌入式详解
目录 第一部分 客观试题(15 分) 不定项选择(1.5 分/题) 第二部分 程序设计试题(85 分) 2.1 STM32CubeMX初始化配置 2.1.1 配置GPIO 2.1.2 配置ADC 2.1.3 配置RCC 2.1.4 配置定时器TIM 2.1.5 配置ADC1、AD…...

新建论文三线表模板,一键格式刷
论文三线表模板写在最前面①表设计,新建表格样式②三线表上下线③三线表标题线④设置表格居中⑤设置表头格式容易出错的步骤写在最前面 论文写完啦,准备调整格式 之前建模也是三线表,但只能基于该文档模板,所以重新设置一下。 如…...

攻防世界-web2(逆向加密算法)
打开链接是PHP源码 给了一串密文,并对这串密文进行了一系列操作加密,注释里说解密$miwen就是flag 在此我们先介绍一些PHP内置函数: strrev(string): 反转字符串 strlen(string): 返回字符串的长度 substr(string, start, length): 返回字符…...

C语言学习1--------Visual Studio集成开发环境的搭建
C语言学习1--------Visual Studio集成开发环境的搭建适合初学者适用集成开发环境下载 Visual Studio 2019安装 Visual Studio 2019安装工作负载为C自定义安装位置激活 Visual Studio适合初学者适用集成开发环境 建议初学者适用最新的——Visual Studio 2019为集成开发环境。 部…...

腾讯云轻量应用服务器搭建网站教程(WordPress为例)
腾讯云轻量应用服务器搭建WordPress网站教程,先安装WordPress应用镜像,然后远程连接轻量应用服务器获取WP用户名和密码,域名DNS解析到轻量服务器IP地址,登陆WordPress后台管理全过程,腾讯云百科来详细说下腾讯云轻量服…...

mac上的PCB设计软件现状
Altium Designer是一款商业化的电路板设计软件,目前没有Mac版本。但是,MacOS上有一些类似Altium Designer的电路板设计软件,以下是一些常用的软件: Eagle:Eagle是一款商业化的电路板设计软件,具有强大的功能…...

【面试题】JavaScript 你常用的 函数有哪些呢? (12个)
大厂面试题分享 面试题库 前后端面试题库 (面试必备) 推荐:★★★★★ 地址:前端面试题库 web前端面试题库 VS java后端面试题库大全 本文收集了 12 个在日常开发中非常常用的函数,有些可能很复杂,有些可…...

Java集合——Set接口学习总结
一、HashSet实现类 1.常用方法 增加:add(E e)删除:remove(Object o)、clear()修改:查看:iterator()判断:contains(Object o)、isEmpty()常用遍历方式:Set<String> set new HashSet<String>()…...

2023最全的自动化测试入门基础知识(建议收藏)
1)首先,什么是自动化测试? 自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。通常,在设计了测试用例并通过评审之后,由测试人员根据测试用例中描述的过程一步步执行测试,得到实际结果与期望结果的比较。…...

【RabbitMQ】SpringBoot整合RabbitMQ、实现RabbitMQ五大工作模式(万字长文)
目录 一、准备 1、创建SpringBoot项目 2、添加配置信息 3、创建配置类 二、RabbitMQ的配置类里创建队列 三、RabbitMQ的配置类里创建交换机及绑定队列 四、SpringBoot整合RabbitMQ入门案例 1、生产者 2、消费者 四、SpringBoot里实现RabbitMQ五大工作模式 1、简单模式…...

ES6(函数扩展、数组扩展)
一、 函数扩展 1. 参数可以默认 ES5调用函数:如果给参数设置默认需要进行判断 ES6可以直接给参数设置默认 //ES5 function log(x, y) {//两种判断方法(传统分支判断、利用逻辑符)if (typeof y undefined) {y World;}//y y || World;cons…...

postman汉化教程
文章目录1. 下载对应版本的postman2.下载对应版本的汉化包2.1. github下载地址 : (9.12.2)2.2 百度网盘(9.12.2)3. 打开postman安装位置4. 压缩包解压到/resources目录下5. 重启postman即可汉化成中文了1. 下载对应版本的postman …...

java day8
第8章 数据结构8.1 超越数组8.2 java数据结构8.2.1 Iterator8.2.2 位组8.2.3 链表8.2.4 遍历数据结构8.2.5 堆栈8.1 超越数组 java类库的java.util包中有一组数据结构,它们让您能够更灵活地组织和操纵数据。 8.2 java数据结构 8.2.1 Iterator 接口Iterator提供了…...

口令暴力破解--Telnet协议暴力破解、数据库暴力破解与远程桌面暴力破解
Telnet协议暴力破解 Telnet Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。要开始一个telnet会话,必须输入用户名和密码来登录服务器。而一般服务器不会对用户名…...

[译]什么是SourceMap
原文链接: https://web.dev/source-maps/使用 SourceMap 来提升 web 调试体验。今天,我们要讨论的是 SourceMap,这是现代 Web 开发中至关重要的工具,它能够显著地简化调试工作。在本文中,我们将探讨 SourceMap 的基础知识…...

saga模式、Seata saga模式详解
文章目录 一、前言二、SAGA模式0、saga论文摘要1、什么是长事务?2、saga的组成3、saga的两种执行场景1)forward recovery2)backward recovery4、saga log5、saga协调(saga实现方式)1)SAGA - Choreography 策略2)SAGA - Orchestration 策略3)如何选择三、Seata saga模式…...

java开发工程师碰到技术难题怎么办?我来聊聊我的做法
最近公司遇到了一个技术难题。这一周基本上都在加班解决这个问题,头发也掉了不少,但问题还没有解决。我写这篇文章,主要是想看看看我文章的同学们是否有类似的经验或者是自己的一些想法。让我们看一下这个问题的一个具体情况。 我们的公司是…...

高比例可再生能源电力系统的调峰成本量化与分摊模型(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

Hive安装与操作
目录 环境 数据 实验步骤与结果 (1)环境启动 (2)Hive基本操作 环境 Hadoop集群开发环境、mysql、Hive环境 数据 course.txt、sc.txt、student.txt 实验步骤与结果 (1)环境启动 ①执行命令…...

oracle centos7安装Oracle12(附oracle所有版本安装包)
环境: centos 7 Oracle12c jdk1.8 一.配置环境 (1)安装依赖 yum -y install binutils.x86_64 compat-libcap1.x86_64 gcc.x86_64 gcc-c++.x86_64 glibc.i686 glibc.x86_64 glibc-devel.i686 glibc-devel.x86_64 ksh compat-libstdc++-33 libaio.i686 libaio.x86_64 libaio-…...

ESP32学习二-更新Python版本(Ubuntu)
一、简介 在一些场景里边,因为Python的版本过低,导致一些环境无法安装。这里来介绍以下,如何升级自己已安装的Python版本。例如如下情况: 二、实操 1.查看本地版本 python --version 2.添加源 sudo add-apt-repository ppa:jona…...

【19】核心易中期刊推荐——人工智能 | 遥感信息处理
🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…...

MySQL运维10-MySQL数据的导入导出
文章目录0、概述1、mysqldump导出数据mysql导入数据1.1、使用mysqldump导出数据1.1.1、使用--tables导出指定表1.1.2、使用--tab选项将表定义文件和数据文件分开导出1.1.3、使用--fields-terminated-by选项定义数据分隔符1.1.4、使用--databases选项导出整个库或多个库1.1.5、使…...

全国计算机等级考试——二级JAVA完整大题题库【五十三道】
全国计算机等级考试二级 JAVA 题目内容 编写于2023.04.10 分为40道选择题和3道大题(大题是程序填空类型) 其中选择题只能进去做一次,一旦退出来则不可再进(注意!)。大题可以重复进入,重复做。…...

【算法题解】24. 模拟机器人行走
这是一道 中等难度 的题 https://leetcode.cn/problems/walking-robot-simulation/description/ 题目 机器人在一个无限大小的 XY 网格平面上行走,从点 (0, 0) 处开始出发,面向北方。该机器人可以接收以下三种类型的命令 commands : -2 &am…...

PyTorch 深度学习实战 |用 TensorFlow 训练神经网络
为了更好地理解神经网络如何解决现实世界中的问题,同时也为了熟悉 TensorFlow 的 API,本篇我们将会做一个有关如何训练神经网络的练习,并以此为例,训练一个类似的神经网络。我们即将看到的神经网络,是一个预训练好的用…...