J3 \& h/ j! z# n) \9 V Histogram of Oriented Gradients(HOG)特征描述子原理解释以及在OpenCV中的使用Histogram of Oriented Gradients(HOG)特征描述子原理解释以及在OpenCV中的使用5 m8 A, A3 c* L% e* o
5 ]2 j# V$ q3 [; M k一、什么是特征描述子? 5 V" q. v P+ z0 Z( f! g% n; a; K3 Q
特征描述子是对一张图片或者一个图片块的一种表示,通过提取有用信息并扔掉多余的信息来简化图像。通常,特征描述子将一张大小为width×height×3 (通道数)的图片化成一个长度为n的特征向量/数组。以HOG特征为例,输入图像的大小是64×128×3,输出是一个长度为3780(假设)的特征向量。! c# P1 { ~: ^7 P3 Y
6 X" E. V) T$ W1 y
上面这些听起来不错,但是对于一张图片的信息,哪些是有用的哪些是冗余的呢?为了定义这个有用信息,我们需要知道它对什么有用。显然,特征向量对于我们看一张图像没什么用。但是,它对图像识别和目标检测这样的任务很有用。将由这些算法生成的特征向量作为支持向量机等分类算法的输入往往可以得到不错的结果。 6 R( \7 D' D2 t7 [( U7 i$ l 8 a, S4 G& ~, w) P但是,对于分类任务来说,哪类特征是有用的呢?让我们先用一个例子讨论一下。假设我们想设计一个目标检测器来检测衬衫或者外套上的纽扣。通常纽扣是圆的(可能在图片上会是椭圆)而且一般会有一些孔用于缝纫。你可以在一张纽扣的图片上执行边缘检测,仅仅通过观察边缘图像就可以判断它是不是一个纽扣。在这个例子中,边缘信息是有用的而颜色信息是无用的。此外,特征也需要有区分能力。例如,从某一张图片中提取的一个好的特征应具备区分纽扣和其他圆心物体(如硬币和车轮)的能力。% M' G6 O2 @0 a' c7 T) N A
, N0 E, K6 ^+ |/ j
对于HOG特征描述子,选用梯度方向的分布作为特征。一张图像的梯度(x和y方向的导数)很有用,因为在边缘和拐角(强度变化剧烈的区域)处的梯度幅值很大。而且我们知道边缘和拐角比其他平坦的区域包含更多关于物体形状的信息。& Y% j4 ^' q' ]3 @6 y+ f
" c" [1 a2 L4 V; R, z+ y6 j$ x在我们的表示结果中,y轴对应0°。你可以发现上面的直方图中有大量的权重(梯度大小的投票结果)在0°和180°附近,这从另外一个角度说明了在这个cell中大部分梯度方向要么朝上要么朝下。2 r1 f1 T% z3 \9 F
/ V) h4 z+ r* D1 Z
Step4:用cell组成一个block块,并对其进行归一化操作9 K" Q! i+ N" ]. B6 n& D8 Z
3 [- D. O& a: Z) b0 t由于局部光照的变化以及前景-背景对比度的变化,使得梯度强度的变化范围非常大。这就需要对梯度强度做归一化,归一化能够进一步地对光照、阴影和边缘进行压缩。理想情况下,我们想让特征描述子独立于光线变化,换句话说,我们想要“标准化”这个直方图使它不受光线变化的影响。 r h9 x3 T3 q
8 Z! v- k c- K4 ^ o现在我们知道如何标准化一个向量,你可能想到当计算HOG特征的时候你可以像之前标准化一个3×1向量一样去标准化9×1的直方图。这的确是个不错的想法,但是更好的做法是标准化一个更大的16×16的block。一个16×16的block包含4个直方图(每一个bin的大小为8 x 8),这4个直方图可以连接成一个36×1的向量,而且这个向量仍然可以像那个3×1的向量一样进行标准化。每次标准化后,整个窗口移动8(假设)个像素并再次计算得到一个36×1的标准化向量,就这样一直重复这个过程。9 o" O' m; ?" a
$ M- U, P, A4 _7 l% ~Step5:将所有block块的特征组合起来,形成HOG完整的特征描述向量 ) Z& i2 N& B" L+ ^! `' j 1 ] q' e9 G# X8 [' `最后一步就是将检测窗口中所有的block块进行HOG特征的收集,并将它们结合成最终的特征向量供分类使用。 + U0 D8 n# h9 J _# o! [1 _) f3 i $ d6 C# W4 s! y" W5 X2 c( j1 g那么这个大向量的维度是多少?我们来计算: ' A! K7 ~% c' \( ]; Y- r2 a8 G / `5 l& n% K" v- b对于64 x 128的图像而言,每8 x 8的像素组成一个cell,每2 x 2个cell组成一个块,因为每个cell有9个特征,所以每个块内有4*9=36个特征,以8个像素为步长。 ( @& X9 {& I) D- z* x' }! B8 a, ~+ b4 `# r
我们有多少个不同位置的16×16的block?一共有 (64-8)/8=7 个水平的位置和 (128-8)/8=15 个竖直的位置,所以总计7×15=105个。# o1 i9 _: I5 b' B
每一个16×16的block被表示成一个36×1的向量。因此,当我们把他们连接成一个大向量的时候会得到一个36×105=3780维度的向量。 ! p5 H) F& d( L1 `8 r H. k梯度直方图可视化 / v& B3 p2 t8 V6 ?" ?. @# Y5 k8 J, z& o. R# @+ S: H4 y' v
一个图像块梯度特征的可视化通常通过在所有8×8的cell里画出对应的标准化的9×1向量(直方图)。不幸的是,目前在OpenCV中并没有一个简单的API方法来可视化HOG特征。) i! E5 U) U/ i5 t3 Y b3 U* ^
- l6 [6 j" B: y& ~! i& x0 H0 X
三、使用OpenCV给出的API实现HOG" M1 ~' C( O4 _
- [( ?3 ]# h5 k; [6 T
这里我将在OpenCV栏目下介绍OpenCV中HOGDescriptor Struct Reference中的一些方法,如果需要请移步链接:https://blog.csdn.net/qq_40913465/article/details/106070151 ( X( B* z2 N' f+ a! a# n4 {4 H0 b5 V: N ~: s1 P& R; Z- ^! Q; w
最后感谢以下两片博客给出的参考: 6 n# _; x7 Y* ]% rhttps://baijiahao.baidu.com/s?id=1646997581304332534&wfr=spider&for=pc$ O! I; M& H- v# z2 d4 c
https://blog.csdn.net/sinat_34474705/article/details/80219617 / h+ p6 U) |/ n$ L1 _$ w$ A 0 V+ z. d% g3 D: n! B, `3 y2 Y" D - E% r# a! J' m1 ^/ {: B: |9 @8 r———————————————— ) X9 _! x7 D/ R5 v( l" K; P' @/ K版权声明:本文为CSDN博主「一只工程狮」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 ) [* o/ q# t7 K8 ?# `- X原文链接:https://blog.csdn.net/qq_40913465/article/details/1060650279 x) X+ d; Y% I+ J2 L9 z
( W& j f9 D) D$ i
s- }7 r6 L, Z" ]" }, R T8 T