深入浅出理解HOG特征---梯度方向直方图

梯度方向直方图
原文路径:https://www.learnopencv.com/histogram-of-oriented-gradients/

最近在搞车牌识别的时候,训练样本去识别车牌的时候用到HOG特征。国外一篇文章让我受益良多

什么是特征描述符?
特征描述符是指通过提取有用的信息并抛弃无关的信息来表示这一张图片或者一张图片的一部分

典型地,特征描述符将大小宽度x高度x 3(通道)的图像转换为特征向量数组,长度n。例如:在HOG特征描述器的情况下,输入图像大小为64×128×3,输出特征向量长度为3780。


中间有一个循环装箱的过程
划分为8x8大小的图像补丁块处理,装到9个箱子(其中8x8、9 这些参数都是不固定的,但是是推荐的)
移动步伐:8个像素
width:64 /8 == 8 份
Height:128 /8 ==16份
用一个16x16的窗口来处理,可以包含4个8X8的图像补丁,那么处理一次会有得到4*9个箱子数据。循环处理
最后能循环 7*15=105次
105*36=3780个箱子数据,存储的是每个像素的梯度大小和梯度方向

记住,HOG特征描述符能够用其他的尺寸大小来计算,但是在下面的具体例子里为了让你更加容易理解相关概念,选择使用图像宽高:64×128,图像补丁 8x8 窗口 16X16 移动步长 8个像素

首先来了解什么是“有用的信息”、什么是“无关的信息”?我们需要明确知道“有用”是指对什么有用。
特征向量对查看图像是没有用的,但是,对于图像识别和目标检测这些任务是非常有用的。将这些算法生成的特征向量引入到支持向量机(SVM)等图像分类算法中,可以取得不错的效果。

但是,哪一种“特征”对分类任务才是真正有用的呢?让我们用一个例子来讨论这一点。 假设我们要建立一个物体检测仪,用来检测衬衫和大衣的纽扣。按钮是圆形的(在图像中可能看起来是椭圆的),通常有几个洞用于缝纫。 你可以在一个按钮的图像上运行一个边缘检测器,只需简单地观察边缘图像就可以很容易地判断它是否是一个按钮。在这种情况下,边缘信息是“有用的”,而颜色信息不是。 此外,该功能还需要有鉴别能力。例如,从图像中提取的良好特征应该能够分辨按钮和其他圆形物体,如硬币和汽车轮胎的区别。

在HOG特征描述器中,梯度方向(梯度)的分布(直方图)作为特征。 图像的梯度(x和y导数)是有用的,因为梯度的大小在边缘和拐角处(突然强度变化的区域)很大,而且我们知道边和角在物体形状上的信息比平面区域要多得多。

怎么去计算方向梯度直方图?
在这一节中,我们将深入研究计算HOG特征描述符的细节。为了说明每一步,我们将使用一个图像块。

步骤1:预处理

如前所述的HOG特征描述符用于行人检测,是在64×128片图像计算。当然,图像可能是任意大小的。通常在多个尺度上分析多个图像位置,唯一的限制是被分析的补丁具有固定的长宽比(纵横比)。在我们的例子中,补丁需要有一个长宽比为1:2。例如,他们可以100×200, 128×256,或1000×2000而不是101×205。

为了说明这一点,下面展示了一个大尺寸的720×475图像。我们计算我们的HOG特征描述符选择一块大小100×200。这个补丁被裁剪的图像并调整其大小以64×128。现在已经准备好计算这个图像补丁的HOG描述符了。

这里写图片描述

还有一个预处理步骤就是“伽玛校正”,但性能提升非常小,所以这里跳过该步骤。

步骤2:计算图像梯度

要计算一个HOG描述符,我们首先需要计算水平和垂直梯度;毕竟,我们要计算梯度直方图。通过用以下内核过滤图像很容易做到这一点。
这里写图片描述

我们可以在opencv中使用内核大小为1的Sobel算子实现同样的结果。

    // Read imageMat img = imread("F:/data/car/test1.jpg");img.convertTo(img, CV_32F, 1 / 255.0);// Calculate gradients gx, gyMat gx, gy;//对X梯度绝对值Sobel(img, gx, CV_32F, 1, 0, 1);//对Y梯度绝对值Sobel(img, gy, CV_32F, 0, 1, 1);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

接下来,我们可以用下面的公式找到梯度的大小和方向

这里写图片描述

如果你是使用opencv,计算梯度的大小和方向可以使用函数carttopolar,如下所示。

    Mat mag, angle;//mag 坡度梯度 大小//mag就是大小 //angle就是方向cartToPolar(gx, gy, mag, angle, 1);
  • 1
  • 2
  • 3
  • 4
  • 5

下图显示了梯度

这里写图片描述

注意,图x梯度在垂直线方向延伸,图y-梯度在水平线方向延伸。图坡度梯度在强度上有急剧的变化。当图片区域光滑时,都没有延伸。我故意遗漏了显示渐变方向的图像,因为作为图像显示的方向不能传达太多信息。

注意看图像的变化
渐变图像去除了许多非必要的信息(例如恒定的彩色背景),但突出显示了轮廓。换句话说,你可以看到渐变图像,并且很容易地辨别出图片中有一个人。

图x梯度 注意水平方向基本没有延伸
图y梯度 注意垂直方向基本没有延伸

这里写图片描述

步骤3:计算在8×8细胞梯度直方图

在这一步中,图像被分为8×8细胞和梯度直方图计算每个8×8细胞。

这里写图片描述

我们将学习了解在一瞬间的直方图,但是在我们去之前就让我们先了解为什么我们把图像分为8×8细胞。使用特征描述符描述图像补丁的一个重要原因是它提供了一个紧凑的表示。8×8图像补丁包含8x8x3 = 192像素值。这个补丁梯度每像素包含2个值(大小和方向),那就变成8x8x2 = 128个数。通过这一部分的最后我们会看到这128个数字是用9-bin直方图(可存储为长度9的数组,通俗地说是分别装到9个箱子里)表示。不仅是表示更简洁,计算在补丁直方图具有更强的健壮性。个别的颜色梯度可能有噪音,但用一个8x8图像补丁来表示梯度直方图对噪声不敏感,换句话说,就是受噪音影响不大。

但是什么是8x8图像补丁?为什么不是32x32?这是我们通过特征缩放来寻找到的明确的选择。HOG最初用于检测行人。在一张行人照片缩放到64×128,使用8×8细胞足以捕捉有趣的功能(如面部、头部的等)。

让我们看一个8×8补丁在图像梯度的面貌

这里写图片描述

中间的图像信息量是非常大的。它显示了用箭头表示梯度的图像的贴片,箭头显示梯度的方向,其长度显示大小。注意箭头的方向如何指向强度的变化方向,其大小表示差异的大小。

在右边,我们看到原始的数字表示在8×8细胞有一个小的差异,那就是角度是0度和180度的梯度,而不是0到360度之间。这些被称为“无符号”渐变,因为梯度正值和它的负值用相同的数字表示。换句话说,梯度箭头和与之相对的180度箭头被认为是相同的。但是,为什么不使用0 - 360度呢?经验表明,无符号梯度比签名梯度更好地用于行人检测。HOG的一些实现将允许您指定是否使用带符号的渐变。

下一步是创建一个8×8细胞梯度直方图。直方图包含9个箱子对应角度0, 20, 40…160。

下图说明了这个过程。我们正在前面的图寻找在同8×8补丁梯度的幅值和方向。根据方向选择箱子,并根据大小选择投票(进入箱子的值)。让我们首先关注环绕在蓝色中的像素。它的角度(方向)为80度,大小为2。所以它放入到第五个箱子。用红色包围的像素的梯度方向为10度,大小为4。由于10度是0和20之间的一半,所以像素的也是均匀地分成两个箱子。

这里写图片描述

还有一个细节需要注意。如果角度大于160度,则在160到180之间,我们知道角度绕成0和180相等。因此,在下面的例子中,角度为165度的像素正比于0度的箱子和160度的箱子。
从160-180
180-165/165-160=3
所以0箱子分4/1,160箱子分4/3

在8×8细胞中所有像素的贡献加起来创造9-bin直方图。对于上面的补丁,它看起来像这样

这里写图片描述

在我们的表示中,y轴是0度。你可以看到直方图在0度和180度附近占很大比重。

这里写图片描述

步骤4:16x16步块归一化

在前面的步骤中,我们根据图像的梯度创建了一个直方图。图像的梯度对整体亮度是敏感的。如果通过将所有像素值除以2来使图像变暗,则渐变幅度将改变一半,因此直方图值将改变一半。理想情况下,我们希望描述符不受光照变化的影响。换句话说,我们希望使直方图正常化(归一化),这样它们不会受到光照变化的影响。
在解释直方图是如何规范化之前,让我们看看长度为3的向量是如何规范化的。
这里写图片描述

例如:一个像素向量RGB【128,64,32】,向量的长度则为:sqrt{128^2 + 64^2 + 32^2} = 146.64
这也被称为向量的L2范数。将向量的每一个元素除以146.64得到归一化向量【0.87,0.43,0.22】,可以看到,归一化后的【256,128,32】将得到【0.87,0.43,0.22】可以看到归一化向量消除了规模。

现在我们知道了如何归一化一个矢量,你可能会认为在计算HOG特征时可以将9x1的直方图以上述的3×1矢量的方式归一化。可以是可以,但更好的办法是归一化一个更大尺寸的16×16块。16×16块用4个直方图可级联成一个36×1元矢量,使用3×1矢量归一化的方法。然后通过8像素的窗口移动(见动画)重复计算,归一化的36×1向量。

步骤5:计算HOG特征向量

计算整个图像补丁最终的特征向量,36×1载体连接成一个巨大的载体。这个向量的大小是多少?
原图截取100*200—>resize—>64*128
64/8=8
128/8=16
1、我们有多少个16×16块吗?有7个水平和15个垂直位置,总共7×15=105个块。
2、每16×16块由36×1矢量表示。所以当我们连接成一个巨大的载体,他们都得到了36×105 = 3780维向量。

定向梯度直方图的可视化

这里写图片描述

一个图像块的HOG特征描述符通常是通过在8×8组织的9×1归一化直方图可视化。见上图像。你会注意到,直方图的主导方向捕捉人的形状,特别是围绕躯干和腿。
不幸的是,没有简单的方法来可视化OpenCV的HOG描述符。

至此:翻译完成,英语水平有限,有错误的地方,希望不吝赐教。

转载自https://blog.csdn.net/wjb820728252/article/details/78395092

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

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

相关文章

陕西居民医保微信缴纳教程来了,太方便了

2022年居民医保交费步骤如下:1、进入微信,我的页面,点支付进入—点城市服务2、城市服务页面,顶部可切换所在城市,输入框搜索“陕西省社保”,选第一个 “陕西省社保缴纳”进入3、选城乡居民医疗保险&#xf…

SVM理论学习记忆

转载自https://blog.csdn.net/chaipp0607/article/details/73662441 SVM算法在在1995年正式发表,在针对中小型数据规模的分类任务上有着卓越的效果,同时有着完整的理论证明,在20世纪末的几年和21世纪初的10年完胜神经网络,吴恩达…

Python中jmespath解析提取json数据

在做接口自动化,测试断言时,我们经常需要提取接口的的响应数据字段,以前用过jsonpath,有几篇相关文章,可以参考下(Python深层解析json数据之JsonPath、【Jmeter篇】后置处理器之正则提取器、Json提取器 、J…

SVM学习记录

第一个min:先在数据中找离决策边界距离最近的样本点 第二个max:寻找w和b使得刚才找到的点离决策边界最远的平面(平面方程:) 求解出后即可求出w和b。 例如: 如果等于0.根据上面的公式,得到w就为…

缺陷定位 | 测试发现了Bug,还要分析定位Bug?(一)

hello今天分享的内容,可能会有很多朋友持不同观点,或被很多同行朋友diss,不过没关系,即使被喷被diss,我依然会坚持我的观点,把最真实的干货分享给大家,希望得到支持。测试工程师在互联网行业里&…

opencv glob 内存溢出异常

先贴代码(非常简单的代码&#xff09; #include "opencv2/imgproc.hpp" #include "opencv2/highgui.hpp" #include "opencv2/ml.hpp" #include "opencv2/objdetect.hpp" #include <iostream> #include <time.h> using na…

白盒测试 | 用例设计方法之条件组合覆盖

往期关联文章回顾&#xff1a;白盒测试 | 用例设计方法之条件覆盖白盒测试 | 用例设计方法之判定覆盖白盒测试 | 用例设计方法之语句覆盖条件组合覆盖&#xff1a;列出所有判定条件中可能的取值组合&#xff0c;使得每个判定条件结果的所有可能组合至少出现一次程序流程图&…

npm安装教程

一、使用之前&#xff0c;我们先来掌握3个东西是用来干什么的。 npm: Nodejs下的包管理器。 webpack: 它主要的用途是通过CommonJS的语法把所有浏览器端需要发布的静态资源做相应的准备&#xff0c;比如资源的合并和打包。 vue-cli: 用户生成Vue工程模板。&#xff08;帮你快…

测试管理 | 测试经理定义和实施测试度量

往期关联文章回顾&#xff1a;瀑布、V、W、快速原型模型、增量、螺旋模型测试管理 | 4种优先级排序方法一定要掌握测试管理 | 基于风险的测试管理上有这样一句名言&#xff0c;进行度量的工作才会得到有效的执行。反之&#xff0c;因为很容易忽略那些不进行度量的工作&#xff…

Python核心场景自动化测试项目实战(二)

往期关联文章回顾&#xff1a;PytestAllureJenkins接口自动化项目实战&#xff08;一&#xff09;【Python篇】核心场景接口自动化方案&#xff08;一&#xff09;以前我们用pythonunittestHTMLTestRunnerjenkins结合实际项目写过一个核心场景自动化测试&#xff0c;也在实际工…

opencv图像切割1-KMeans方法

kMeans随机数据分类&#xff1a; #include<opencv2\opencv.hpp> #include<iostream> using namespace cv; using namespace std; int main1() {Mat img(500, 500, CV_8UC3);RNG rng(12345);Scalar colorTab[] {Scalar(0,0,255),Scalar(0,255,0),Scalar(255,0,0),…

mitmproxy抓包 | Python疑难测试场景mock

往期经典文章回顾&#xff1a;抓包工具mitmproxy环境配置使用&#xff08;一&#xff09;抓包工具mitmproxy | mitmweb基本用法&#xff08;二&#xff09;mitmproxy抓包 | Python实时生成接口自动化用例mitmproxy抓包 | Python实时生成接口自动化用例&#xff08;三&#xff0…

opencv图像分割2-GMM

GMM随机数分类&#xff1a; #include<opencv2\opencv.hpp> #include<iostream> using namespace cv; using namespace std; using namespace cv::ml; int main() {Mat imgMat::zeros(500, 500, CV_8UC3);RNG rng(12345);Scalar colorTab[] {Scalar(0,0,255),Scal…

mitmproxy抓包 | Python疑难测试场景mock实战(四)

往期经典文章回顾&#xff1a;抓包工具mitmproxy环境配置使用&#xff08;一&#xff09;抓包工具mitmproxy | mitmweb基本用法&#xff08;二&#xff09;mitmproxy抓包 | Python实时生成接口自动化用例mitmproxy抓包 | Python实时生成接口自动化用例&#xff08;三&#xff0…

mitmproxy抓包 | Python篡改请求参数实战(五)

抓包工具mitmproxy环境配置使用&#xff08;一&#xff09;抓包工具mitmproxy | mitmweb基本用法&#xff08;二&#xff09;mitmproxy抓包 | Python实时生成接口自动化用例&#xff08;三&#xff09;mitmproxy抓包 | Python实时生成接口自动化用例mitmproxy抓包 | Python疑难…

数据结构-链表1-顺序存储

DynamicArray.h #ifndef DYNAMIC_ARRAY_H #define DYNAMIC_ARRAY_H #define _CRT_SECURE_NO_WARNINGS #include<stdlib.h> #include<stdio.h> #include<string.h>//动态数组结构体 typedef struct DYNAMICARRAY {int* pAddr; //具体存放数据的地址int size…

全网都在用的超全【面试刷题小程序】,最新版激活教程

前几天&#xff0c;我的一个粉丝留言给我说&#xff0c;他在面试美团的自动化测试岗的时候&#xff0c;不幸挂掉了。越想越觉得可惜&#xff0c;回想面试经过&#xff0c;好好总结了几个点&#xff0c;发现面试没过的主要原因是在几个关键的问题没有给到面试官想要的答案。从而…

数据结构-链表2-链式存储

LinkList.h #ifndef LINKLIST_H #define LINKLIST_H #define _CRT_SECURE_NO_WARNINGS #include<stdlib.h> #include<stdio.h> #include<string.h>//链表结点 typedef struct LINKNODE {void* data; //无类型指针&#xff0c;指向任何类型的数据struct LIN…

字节内部自动化测试培训资料,明年涨薪用得上

今天是12月27日&#xff0c;2021年还剩下最后4天。昨晚我收到一位粉丝朋友的涨薪喜讯&#xff0c;他踩着2021的尾巴&#xff0c;成功跳进广州海珠的互联网巨头&#xff0c;涨薪幅度达284%。其实每年的年末&#xff0c;圈子里的朋友都特别忙&#xff0c;大家都在为来年跳槽做准备…

数据结构-链表3-循环链表

LinkList.h #ifndef LINKLIST_H #define LINKLIST_H #define _CRT_SECURE_NO_WARNINGS #include<stdlib.h> #include<stdio.h> #include<string.h>//链表小结点 typedef struct CIRCLELINKNODE {struct LinkNode *next; }CircleLinkNode;//链表结构体 type…