【SLAM学习笔记3】ORB-SLAM2中的方向梯度直方图(HOG,Histogram of Gradient)

2023-11-07

文章目录


前言

前言这种东西已经写不动了,被代码按在地上摩擦,快起火了。
在研读源码期间,看到了旋转直方图,初次见的时候理解了,现在第二次在其他地方看到又忘了,特写此文记录学习。
如果要深入学习,还是需要阅读《Histogram of Oriented Gradients(方向梯度直方图)》论文。


一、基础知识

1. 梯度(gradient)

在向量微积分中,标量场的梯度是一个向量场,标量场中某一点上的梯度指向标量场增长最快的方向梯度的长度是最大的变化率

图像处理实现(详细见CSDN@gloomyfish):利用X方向与Y方向分别实现一阶微分,求取振幅,实现图像梯度效果。

2. 一阶微分

对于离散的图像来说,一阶微分的数学表达相当于两个相邻像素的差值,根据选择的梯度算子的不同,效果可能有所不同,但基本原理不变。

图像处理实现(详细见CSDN@gloomyfish):最常见的算子为Roberts算子,其它常见还有Sobel,Prewitt等算子。

3. 图像梯度计算(图像微分)的应用

图像微分(梯度计算)是图像边缘提取的重要的中间步骤,根据X、Y方向的梯度向量值,可以得到如下两个重要参数:振幅magnitude,角度theta
计算公式如下:

在这里插入图片描述
在这里插入图片描述

magnitude(振幅)表示边缘强度信息
theta(角度)预测边缘的方向走势。

假如对一幅数字图像,求出magnitude之后与原来每个像素点对应值相加,则图像边缘将被大大加强,轮廓更加明显,是一个很典型的sharp filter(锐化)的效果。

来源:CSDN@HySmiley

4. 卷积

通过一个卷积模板在待处理的图像上移动,对每个卷积模板覆盖的区域进行点乘,得到的值作为中心像素点的输出值。

常用于信号处理中,而图像数据可以看做是一种信号数据,故可以对图像进行卷积操作。


二、方向梯度直方图(旋转直方图)

1. HOG特征

方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子,其通过计算和统计图像局部区域的梯度方向直方图来构成特征。

HOG+SVM的思路常被用于行人检测的图像识别中,ORB-SLAM2中只涉及HOG。

(1)核心思想

在一幅图像中,局部目标的表象和形状(appearance and shape)能够被梯度或边缘的方向密度分布很好地描述。
本质:梯度的统计信息,而梯度主要存在于边缘的地方。

(2)实现方法

首先将图像分成小的连通区域,并称其为细胞单元(cell),然后采集细胞单元中各像素点的梯度的或边缘的方向直方图,最后把这些直方图组合起来就可以构成特征描述器。

(3)进一步优化

把这些局部直方图在图像在更大的范围内(称其为区间或block)进行对比度归一化(contrast-normalized)。
采用的方法是:先计算各直方图在这个区间(block)中的密度,然后根据这个密度对区间中的各个细胞单元做归一化。通过这个归一化后,能对光照变化和阴影获得更好的效果。

(4)优点:具有尺寸不变性和光照不变性

2. 具体实现步骤(参考论文并结合ORB-SLAM2总结)

(1)选择需进行特征处理的图像,并进行预处理

选择需进行处理的image(假设尺寸为64x128),然后进行灰度化和颜色空间的归一化。

归一化的目的:调节图像的对比度,降低图像局部的阴影和光照变化所造成的影响,同时可以抑制噪音的干扰。但是并不够,即性能提升效果较小。

(2)计算图像梯度

这个由于选择的梯度算子计算方式的不同,可能计算梯度的效果会不太一样,但基本原理是一样的。

在这里插入图片描述
**最常用的实现方法:**首先用[-1,0,1]梯度算子对原图像做卷积运算,得到x方向的梯度分量xGradient,然后用[1,0,-1]T梯度算子对原图像做卷积运算,得到y方向的梯度分量yGradient。最后用相应的算子计算公式计算该像素点的梯度大小和方向。
注:x方向上的分量不一定就是水平方向,同理,y也不一定就是竖直方向,例如Roberts算子计算时运用的是对角线。
最普通的计算梯度公式为:

在这里插入图片描述

(3)划分cell单元,为每个cell构建梯度方向直方图

设定细胞单元cell的尺寸大小(由x个像素构成),确定直方图储存cell梯度信息的bin的数目。
例如,假设细胞单元cell为8x8个像素构成,采用9个bin的直方图来统计这些8x8个像素的梯度信息。
一个 8×8 的图像块包含 8x8x3 = 192 个像素值。该补丁的梯度包含每个像素的 2 个值(幅度和方向),总计为 8x8x2=128 个数字。将cell的梯度方向360度分成9个方向块。
如图所示:例如:如果这个像素的梯度方向是20-40度,直方图第2个bin的计数就加一,这样,对cell内每个像素用梯度方向在直方图中进行加权投影(映射到固定的角度范围),就可以得到这个cell的梯度方向直方图了,就是该cell对应的9维特征向量(因为有9个bin)。
在这里插入图片描述
cell可以是圆形、矩形、星形等不同形状的。

如何分配每个cell中的bin值权重,见opencv官网:histogram-of-oriented-gradients

(4)将cell组合成更大的块(block),块内归一化,构建直方图

由于局部光照的变化以及前景-背景对比度的变化,使得梯度强度的变化范围非常大。这就需要对梯度强度做归一化。归一化能够进一步地对光照、阴影和边缘进行压缩。
采用方法:把各个细胞单元组合成大的、空间上连通的区间(blocks)。一个block内所有cell的特征向量串联起来便得到该block的HOG特征。这些区间是互有重叠的,这就意味着:每一个单元格的特征会以不同的结果多次出现在最后的特征向量中。我们将归一化之后的块描述符(向量)就称之为HOG描述符。

如将4个上述8x8的cell拼凑成一个16x16的block,一个block有4个91的直方图,故block组合成了一个361的向量(HOG特征)。然后做归一化,将block窗口移动8个像素遍历图像的所有像素点,在这个窗口上计算36*1向量的归一化。


(5)计算Oriented-Gradients特征向量的直方图

在整幅image上,有 7 个水平位置和 15 个垂直位置,总共 7 x 15 = 105 个16x16的block可以移动(扫描)的位置。
每个 16×16 块由一个 36×1 向量表示。因此,当我们将它们全部连接成一个增益向量时,我们获得了一个 36×105 = 3780维的向量。
所以一幅64x128的图像,总共有3780个特征,即其HOG特征的维度为3780。

所以这一幅图像的HOG特征就这么求出来了。

其实这个64x128在论文中只是一张图中的一小块,论文中计算了这一小块的HOG特征。

三、ORB-SLAM2使用的地方(210821更,持续更新)

1. 单目初始化

源代码路径:void Tracking::MonocularInitialization()中的SearchForInitialization()
作用:在单目初始化中进行参考帧(第一帧)和当前帧(第二帧)的匹配中,筛选“非关键”的匹配特征点。

2. 关键帧跟踪

源代码路径:bool Tracking::TrackReferenceKeyFrame()中的SearchByBoW()
作用:当前普通帧对关键帧跟踪过程中,根据方向剔除误匹配的点。


Reference(宝藏链接,虽然都差不多):

  1. https://blog.csdn.net/m0_37264397/article/details/77824975(内容最多)
  2. https://www.leiphone.com/category/yanxishe/ZKsGd2JRKr766wEd.html(3打不开,看这个)
  3. https://learnopencv.com/histogram-of-oriented-gradients/(opencv官方文章)
  4. 《OpenCV4快速入门》
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【SLAM学习笔记3】ORB-SLAM2中的方向梯度直方图(HOG,Histogram of Gradient) 的相关文章

  • 使用 OpenCV 查找重叠/复杂的圆

    我想计算红圈半径 图2 我在使用 OpenCV 的 HoughCircles 找到这些圆圈时遇到了麻烦 如图所示 2 我只能使用 HoughCircles 找到中心以黑色显示的小圆圈 original fig 2 由于我知道红色圆圈的中心
  • 在opencv中保存帧而不压缩

    我正在尝试使用写 OpenCV 函数 我想保存帧 TIFF扩大 我遇到的问题是保存的图像被压缩 所以我无法使用它们 知道如何摆脱这种压缩吗 提前致谢 不要介意西奇说的话 TIFF 标志通过 LZW 压缩硬编码在 opencv 二进制文件中
  • opencv如何使用compareHist函数

    img cv2 imread mandrill png histg cv2 calcHist img 0 None 256 0 256 if len sys argv lt 2 print gt gt sys stderr Usage sy
  • 如何使图像呈现出陈旧、布满灰尘、颜色褪色的外观?

    我有旧画的图像 这些画很旧 布满灰尘 颜色褪色 如图所示here https i stack imgur com xuoEF jpg 如何赋予任何图像这种 旧 外观 我找不到任何过滤器或 openCV 函数来实现这种类型的外观 EDIT 我
  • 收据褪色部分可以恢复吗?

    我有一些包含一些扫描收据的文件 我需要使用 OCR 从中提取文本 由于收据上打印的文字在一段时间后会褪色 导致收据上的某些文字不清晰 影响OCR结果 褪色单词的一些示例 有什么方法可以恢复褪色的部分 以便提高 OCR 结果吗 我在OpenC
  • 使用 openCV 和 python 检测物体

    我正在尝试使用 OpenCV 和 Python 检测下图中的白点 我尝试使用函数 cv2 HoughCircles 但没有成功 我需要使用不同的方法吗 这是我的代码 import cv2 cv import numpy as np impo
  • 计算两个描述符之间的距离

    我正在尝试计算已计算的两个描述符之间的距离 欧几里得或汉明 问题是我不想使用匹配器 我只想计算两个描述符之间的距离 我正在使用 OpenCV 2 4 9 并且我的描述符存储在 Mat 类型中 Mat descriptors1 Mat des
  • opencv中矩阵的超快中值(与matlab一样快)

    我正在 openCV 中编写一些代码 想要找到一个非常大的矩阵数组 单通道灰度 浮点数 的中值 我尝试了几种方法 例如对数组进行排序 使用 std sort 和选择中间条目 但与 matlab 中的中值函数相比 它非常慢 准确地说 在 ma
  • 相机标定(OpenCV 2.3)-如何使用畸变参数?

    我有一组带有一些附加标记的刚体图像 我在这些标记之一中定义了一个原点坐标系 我想获得该坐标系与在相机原点定义的坐标系之间的旋转和平移 我尝试了一段时间 POSIT 以下this http goo gl cUYYt 但从未获得可接受的结果 直
  • 使用 opencv warpPerspective() 生成道路的自上而下视图

    我正在尝试实施逆透视映射计算与道路上另一辆车的距离 我知道在应用该函数之前我需要生成一个包含源点和目标点的变换矩阵warpPerspective 但我不知道如何计算目的地点 我在这个论坛和其他网站中搜索 但无法将第一张图片转换为第二张图片
  • 在 RGB 图像上绘制多类语义分割透明叠加

    我有语义分割掩码的结果 值在 0 1 之间 需要大津阈值来确定什么是积极的 我想直接在 RGB 图像上绘制 在 RGB 图像上每个预测类具有不同的随机颜色 我使用以下内容绘制了具有单一颜色的单个蒙版 是否有一个包或简单的策略可以为多类别做到
  • 来自 OpenCV 的外部参数

    我正在使用 OpenCV 来校准立体相机对 我拍摄了各种校准照片 并且使用 cv2 calibrateCamera 对内在参数进行了令人满意的拟合 然而 目前尚不清楚如何获取外部参数 该函数仅返回cameraMatrix 尽管它很有用 但实
  • Python:opencv warpPerspective 既不接受 2 个也不接受 3 个参数

    我发现单应矩阵如下特征匹配 单应性教程 https docs opencv org 3 4 1 d1 de0 tutorial py feature homography html using M mask cv2 findHomograp
  • 如何将 mat 转换为 array2d

    我为dlib http dlib net face landmark detection ex cpp html那里的面部地标代码使用 array2d 来获取图像 但我喜欢使用 Mat 读取图像并转换为 array2d 因为 dlib 仅支
  • 如何将输出视频保存到 OpenCV 中的文件中

    我想将输出视频保存到文件中而不是显示它并尝试使用 cvcaptureimage 但仍然无法获得结果 include
  • 如何在 OpenCV 中从 YUV 文件读取帧?

    如何在 OpenCV 中从 YUV 文件读取帧 我编写了一个非常简单的 python 代码来从二进制文件读取 YUV NV21 流 import cv2 import numpy as np class VideoCaptureYUV de
  • 使用 ffmpeg 或 OpenCV 处理原始图像

    看完之后维基百科页面 http en wikipedia org wiki Raw image format原始图像格式 是任何图像的数字负片 为了查看或打印 相机图像传感器的输出具有 进行处理 即转换为照片渲染 场景 然后以标准光栅图形格
  • 检查图像中是否有太薄的区域

    我正在尝试验证雕刻机的黑白图像 更多的是剪贴画图像 不是照片 我需要考虑的主要事情之一是区域的大小 或线条的宽度 因为机器无法处理太细的线条 所以我需要找到比给定阈值更细的区域 以此图为例 竖琴的琴弦可能太细而无法雕刻 我正在阅读有关 Ma
  • 仅获取图像中的外部轮廓

    我有这段代码 可以在图像中绘制轮廓 但我只需要外部轮廓 import cv2 import numpy as np camino C Users Usuario Documents Deteccion de Objetos 123 jpg
  • 创建 OpenCV 的 mouseCallback 函数的基于类的实现时遇到问题

    正如标题所示 我在基于类的 C 结构中实现 OpenCV 的 mouseCallback 函数时遇到了一些麻烦 请允许我解释一下 我定义了一个名为 BriskMatching 的类 在其中创建了一个名为 mouseCallback 的成员函

随机推荐