fhog详解
fhog是在hog基础上进行的优化。
假设F是一个大小为 w ∗ h w*h w∗h 图像的像素级特征映射, k > 0 k>0 k>0是定义的 c e l l cell cell 的大小。通过像素级特征映射的空间聚合来得到基于 c e l l cell cell 的特征映射 C C C,记为: C ( i , j ) C(i,j) C(i,j)。其中 { 0 ≤ i ≤ [ ( w − 1 ) / k ] } \{0\leq i\leq[(w-1)/k]\} {0≤i≤[(w−1)/k]}, { 0 ≤ j ≤ [ ( h − 1 ) / k ] } \{0\leq j\leq[(h-1)/k]\} {0≤j≤[(h−1)/k]}
这种聚合可以使特征具有对微小形变的不变性,并可以减少特征映射尺寸。
最简单的聚合特征的方法是将像素 ( x , y ) (x,y) (x,y)映射到一个 c e l l cell cell 中( [ x / k ] , [ y / k ] [x/k], [y/k] [x/k],[y/k]),比如 k = 4 , x = 20 , y = 60 , x k = 5 , y k = 12 k=4,x=20,y=60,\frac{x}{k}=5,\frac{y}{k}=12 k=4,x=20,y=60,kx=5,ky=12,则像素 ( x , y ) (x,y) (x,y) 映射到 c e l l ( 5 , 12 ) cell(5,12) cell(5,12) 当中。
像素梯度幅值的统计办法
以下图为例,图像左图是一个 3 × 3 3\times 3 3×3 个cell,假设每个cell是由 4 × 4 4\times 4 4×4 个像素组成。假设每个像素梯度幅值为 r ( i , j ) r(i,j) r(i,j)。但是论文中这个像素的梯度幅值,并不是直接等于这个像素位置计算出来的幅值,而是在相邻的四个cell对应位置按照影响按权重计算得来。此处的理解可以参考:opencv 学习笔记-入门(21)之三线性插值-hog(二)。比如下图,统计中间深棕色cell的网格状阴影像素梯度时,要就算它周围相邻cell对应位置上梯度,并做加权处理,才是此处的梯度。同理,斜纹阴影的四个像素的梯度幅值也是如此计算。
假如当前cell要计算的像素特征梯度为
r
(
i
+
0
,
j
+
1
)
r(i+0,j+1)
r(i+0,j+1) ,加号前面的值是该像素所在cell的坐标,简记为
r
i
,
j
r_{i,j}
ri,j,周围相邻的四个cell对应位置像素梯度值记为
r
i
−
1
,
j
−
1
r_{i-1,j-1}
ri−1,j−1,
r
i
−
1
,
j
r_{i-1,j}
ri−1,j,
r
i
,
j
−
1
r_{i,j-1}
ri,j−1。加权后,最后的像素梯度特征为:
w
1
⋅
r
i
−
1
,
j
−
1
+
w
2
⋅
r
i
−
1
,
j
−
w
2
⋅
r
i
,
j
−
1
−
w
2
⋅
r
i
,
j
w_1\cdot r_{i-1,j-1}+w_2\cdot r_{i-1,j}-w_2\cdot r_{i,j-1}-w_2\cdot r_{i,j}
w1⋅ri−1,j−1+w2⋅ri−1,j−w2⋅ri,j−1−w2⋅ri,j。
.png)]
填充cell特征向量
根据梯度幅角,填充cell特征向量。假设将 [ 0 − π ] [0-\pi] [0−π] 区间分成9份,区间间隔 20°。每个cell有9维方向不敏感的维度值,再将 [ 0 − 2 π ] [0-2\pi] [0−2π] 分成18份,区间间隔还是20°,分下来,每个cell又有18维方向敏感的维度值。这两者加起来,共有27个维度。设 cell 标记为 C ( i , j ) C(i,j) C(i,j) ,是一个9+27维特征向量,如上图。
1.3 Normalization and Truncation
梯度对偏置改变具有不变性,这种不变性是通过归一化获得的。
作者使用了四种不同的归一化因子,记为:
N
δ
,
r
(
i
,
j
)
N_{\delta ,r}(i,j)
Nδ,r(i,j) 其中
δ
,
r
ϵ
{
−
1
,
1
}
\delta ,r \quad\epsilon\begin{Bmatrix} -1,1\end{Bmatrix}
δ,rϵ{−1,1},定义如下:
N
δ
,
r
(
i
,
j
)
=
(
∣
∣
C
(
i
,
j
)
∣
∣
2
+
∣
∣
C
(
i
+
δ
,
j
)
∣
∣
2
+
∣
∣
C
(
i
,
j
+
γ
)
∣
∣
2
+
∣
∣
C
(
i
+
δ
,
j
+
γ
)
∣
∣
2
)
1
2
N_{\delta ,r}(i,j)=(||C(i,j)||^2+||C(i+\delta,j)||^2+||C(i,j+\gamma)||^2+||C(i+\delta,j+\gamma)||^2)^{\frac{1}{2}}
Nδ,r(i,j)=(∣∣C(i,j)∣∣2+∣∣C(i+δ,j)∣∣2+∣∣C(i,j+γ)∣∣2+∣∣C(i+δ,j+γ)∣∣2)21
每个因子都包含一个block的四个cell的能量:
[
N
−
1
,
−
1
(
i
,
j
)
,
N
+
1
,
−
1
(
i
,
j
)
,
N
+
1
,
+
1
(
i
,
j
)
,
N
−
1
,
+
1
(
i
,
j
)
]
[N_{-1 ,-1}(i,j), N_{+1 ,-1}(i,j),N_{+1 ,+1}(i,j),N_{-1 ,+1}(i,j)]
[N−1,−1(i,j),N+1,−1(i,j),N+1,+1(i,j),N−1,+1(i,j)]
四个列向量,分别对应上图的(1)~(4)中彩色cell部分。
[
N
−
1
,
−
1
(
i
,
j
)
=
(
∣
∣
C
(
i
,
j
)
∣
∣
2
+
∣
∣
C
(
i
−
1
,
j
)
∣
∣
2
+
∣
∣
C
(
i
−
1
,
j
−
1
)
∣
∣
2
+
∣
∣
C
(
i
,
j
−
1
)
∣
∣
2
)
1
/
2
N
+
1
,
−
1
(
i
,
j
)
=
(
∣
∣
C
(
i
,
j
)
∣
∣
2
+
∣
∣
C
(
i
+
1
,
j
)
∣
∣
2
+
∣
∣
C
(
i
+
1
,
j
−
1
)
∣
∣
2
+
∣
∣
C
(
i
,
j
−
1
)
∣
∣
2
)
1
/
2
N
+
1
,
+
1
(
i
,
j
)
=
(
∣
∣
C
(
i
,
j
)
∣
∣
2
+
∣
∣
C
(
i
+
1
,
j
)
∣
∣
2
+
∣
∣
C
(
i
+
1
,
j
+
1
)
∣
∣
2
+
∣
∣
C
(
i
,
j
+
1
)
∣
∣
2
)
1
/
2
N
−
1
,
+
1
(
i
,
j
)
=
(
∣
∣
C
(
i
,
j
)
∣
∣
2
+
∣
∣
C
(
i
−
1
,
j
)
∣
∣
2
+
∣
∣
C
(
i
−
1
,
j
+
1
)
∣
∣
2
+
∣
∣
C
(
i
,
j
+
1
)
∣
∣
2
)
1
/
2
]
\begin{bmatrix}N_{-1 ,-1}(i,j)=(||C(i,j)||^2+||C(i-1,j)||^2+||C(i-1,j-1)||^2+||C(i,j-1)||^2)^{1/2}\\N_{+1 ,-1}(i,j)=(||C(i,j)||^2+||C(i+1,j)||^2+||C(i+1,j-1)||^2+||C(i,j-1)||^2)^{1/2}\\N_{+1 ,+1}(i,j)=(||C(i,j)||^2+||C(i+1,j)||^2+||C(i+1,j+1)||^2+||C(i,j+1)||^2)^{1/2}\\N_{-1 ,+1}(i,j)=(||C(i,j)||^2+||C(i-1,j)||^2+||C(i-1,j+1)||^2+||C(i,j+1)||^2)^{1/2}\end{bmatrix}
⎣⎢⎢⎡N−1,−1(i,j)=(∣∣C(i,j)∣∣2+∣∣C(i−1,j)∣∣2+∣∣C(i−1,j−1)∣∣2+∣∣C(i,j−1)∣∣2)1/2N+1,−1(i,j)=(∣∣C(i,j)∣∣2+∣∣C(i+1,j)∣∣2+∣∣C(i+1,j−1)∣∣2+∣∣C(i,j−1)∣∣2)1/2N+1,+1(i,j)=(∣∣C(i,j)∣∣2+∣∣C(i+1,j)∣∣2+∣∣C(i+1,j+1)∣∣2+∣∣C(i,j+1)∣∣2)1/2N−1,+1(i,j)=(∣∣C(i,j)∣∣2+∣∣C(i−1,j)∣∣2+∣∣C(i−1,j+1)∣∣2+∣∣C(i,j+1)∣∣2)1/2⎦⎥⎥⎤
T
α
(
υ
)
T_{\alpha }(\upsilon )
Tα(υ) 表示向量
υ
\upsilon
υ 被
α
\alpha
α 截断之后形成的向量(把
v
v
v 中大于
α
\alpha
α 的值都设为 $\alpha $)。将 Cell 级别的特征归一化并截断后,串联起来就得到HOG特征。
H
(
i
,
j
)
=
[
T
α
(
C
(
i
,
j
)
/
N
−
1
,
−
1
(
i
,
j
)
)
T
α
(
C
(
i
,
j
)
/
N
+
1
,
−
1
(
i
,
j
)
)
T
α
(
C
(
i
,
j
)
/
N
+
1
,
+
1
(
i
,
j
)
)
T
α
(
C
(
i
,
j
)
/
N
−
1
,
+
1
(
i
,
j
)
)
]
H(i,j)=\begin{bmatrix} T_{\alpha}(C(i,j)/N_{-1,-1}(i,j))\\ T_{\alpha}(C(i,j)/N_{+1,-1}(i,j))\\ T_{\alpha}(C(i,j)/N_{+1,+1}(i,j))\\ T_{\alpha}(C(i,j)/N_{-1,+1}(i,j))\\ \end{bmatrix}
H(i,j)=⎣⎢⎢⎡Tα(C(i,j)/N−1,−1(i,j))Tα(C(i,j)/N+1,−1(i,j))Tα(C(i,j)/N+1,+1(i,j))Tα(C(i,j)/N−1,+1(i,j))⎦⎥⎥⎤
通常取
p
=
9
,
k
=
8
,
α
=
0.2
p=9,k=8,\alpha =0.2
p=9,k=8,α=0.2,最终得到一个36维的特征向量(这个
H
H
H 是一个
4
×
9
4\times 9
4×9 维的向量)。
什么叫被 α \alpha α 截断的向量?比如一个向量是 C = [ 1 , 2 , 0.5 , 0.1 ] C=[1,2,0.5,0.1] C=[1,2,0.5,0.1],那么 T α ( C ) = [ 0.2 , 0.2 , 0.2 , 0.1 ] T_{\alpha}(C)=[0.2,0.2,0.2,0.1] Tα(C)=[0.2,0.2,0.2,0.1]
H ( i , j ) H(i,j) H(i,j) 的形式如下(左图)所示,右图为将各列串联起来,形成一条长向量(36维)。
图像可以转化成如下图所示,正面窗格表示一个cell。整幅图像根据cell大小,分为 m × n m\times n m×n 个cell,图像维度为: m × n × 36 m\times n\times 36 m×n×36:
一幅图像,可以看成是 m × n m\times n m×n 个36维向量,整体向量维度还是很大,所以要通过PCA进行降维处理。
PCA的解释可以参考:【机器学习】降维——PCA(非常详细)
将36维数据组成的矩阵中,找到若干个(小于36维)向量可以表示这36维数据,而整体的损失还比较小。
这里,原论文的作者通过大量的图片试验,发现大概取前11(也有说12)特征向量,就可以表示所有的36维数据。
这个图就是将原有的36维数据,按PCA方法处理后,生成36个特征向量,按特征值从大到小排列的特征向量如下:
前面几个特征值大的特征向量,其形状有固定规律,都是由横条或者竖条组成。横条或竖条上的点,数值基本相近,因此作者提出用性质相近的点求和后,作为特征向量的一维,因此生成了横向和4个,纵向和9个,共13个数,这13个数排成一列,组成了新的向量。作者认为,这样生成的13维向量,可以代表特征值最大的前几个特征向量,进而可以表示整个数据。所以数据由36维降到了13维,如下图所示
假设这个36维向量为
X
=
[
x
1
,
⋯
,
x
3
6
]
T
X=[x_1,\cdots,x_36]^T
X=[x1,⋯,x36]T,转成13维向量方式如下:
[
1
⋯
1
0
⋯
0
0
⋯
0
0
⋯
0
0
⋯
0
1
⋯
1
0
⋯
0
0
⋯
0
0
⋯
0
0
⋯
0
1
⋯
1
0
⋯
0
0
⋯
0
0
⋯
0
0
⋯
0
1
⋯
1
1
⋯
0
1
⋯
0
1
⋯
0
1
⋯
0
⋯
0
⋯
1
0
⋯
1
0
⋯
1
0
⋯
1
]
13
×
36
[
x
1
x
2
x
3
x
4
⋯
x
36
]
36
×
1
=
[
y
1
⋯
y
13
]
13
×
1
\begin{bmatrix}1& \cdots&1&0&\cdots&0&0&\cdots&0&0&\cdots&0\\0& \cdots&0&1&\cdots&1&0&\cdots&0&0&\cdots&0\\0& \cdots&0&0&\cdots&0&1&\cdots&1&0&\cdots&0\\0& \cdots&0&0&\cdots&0&0&\cdots&0&1&\cdots&1\\1& \cdots&0&1&\cdots&0&1&\cdots&0&1&\cdots&0\\&&&&\cdots\\0& \cdots&1&0&\cdots&1&0&\cdots&1&0&\cdots&1\\\end{bmatrix}_{13\times 36}\begin{bmatrix}x_1\\x_2\\x_3\\x_4\\\cdots\\x_{36}\\\end{bmatrix}_{36\times 1}=\begin{bmatrix}y_1\\\cdots\\y_{13}\\\end{bmatrix}_{13\times 1}
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡100010⋯⋯⋯⋯⋯⋯100001010010⋯⋯⋯⋯⋯⋯⋯010001001010⋯⋯⋯⋯⋯⋯001001000110⋯⋯⋯⋯⋯⋯000101⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤13×36⎣⎢⎢⎢⎢⎢⎢⎡x1x2x3x4⋯x36⎦⎥⎥⎥⎥⎥⎥⎤36×1=⎣⎡y1⋯y13⎦⎤13×1
总的过程可以参考这张图:
fhog特征融合入相关滤波之中
这段是参考 FHOG
无论是训练还是检测都用到核相关矩阵,所以hog特征的融合主要是在这个过程中进行的。
④ 然后在用和相关矩阵的计算公式进行计算 :我们把特征记为X[36],Y[36],是一个36维的容器,每个维度都是mn的矩阵。
① 首先分别对每个维度进行傅里叶变换,得到xf[36]和yf[36].
② xx的计算:计算xf在每一维的二范数除以(mn)。然后累加起来,就是xx。yy也是一样,这一步得到的都是一个实数。
③ xy的计算:计算xf[i]和yf[i]的共轭在频域的点积(element-wise),这样得到的是36个mn的复数矩阵,分别对每个矩阵都进行傅里叶逆变换得到xy[36],是36个mn的实数矩阵,分别也要除以(mn),然后把36个矩阵对应点求和得到一个矩阵记作xy,是一个mn的实数矩阵。
上面两个除以的m*n都是在处理公式中的numel(x).即总的像素点数。
④ 然后在用和相关矩阵的计算公式进行计算 :
k
=
e
x
p
(
−
1
δ
2
m
a
x
(
0
,
(
x
x
+
y
y
−
2
x
y
)
/
维
数
)
)
k=exp(-\frac{1}{\delta^2}max(0,(xx+yy-2xy)/维数))
k=exp(−δ21max(0,(xx+yy−2xy)/维数))
这段的C++代码如下:
cv::Mat KCF::GaussianCorrelation(std::vector<cv::Mat> xf, std::vector<cv::Mat> yf) {
int N = xf[0].size().area(); //这就是一个面积,也就是总的像素数
double xx = 0, yy = 0;
std::vector<cv::Mat> xyf_vector(xf.size());
cv::Mat xy(xf[0].size(), CV_32FC1, Scalar(0.0)), xyf, xy_temp;
for (unsigned int i = 0; i < xf.size(); ++i) //特征维数
{
xx += cv::norm(xf[i]) * cv::norm(xf[i]) / N; //这里算的是二范数,是一个double。并除以N
yy += cv::norm(yf[i]) * cv::norm(yf[i]) / N;
cv::mulSpectrums(xf[i], yf[i], xyf, 0, true); //傅里叶域点乘
cv::idft(xyf, xy_temp, cv::DFT_SCALE | cv::DFT_REAL_OUTPUT); // Applying IDFT,这里也除以N了,DFT_SCALE就是标志
xy += xy_temp;
} //把所有层的特征都加起来,实际上是在复数域加起来
float numel_xf = N * xf.size();
cv::Mat k, kf;
exp((-1 / (kernel_sigma_ * kernel_sigma_)) * max(0.0, (xx + yy - 2 * xy) / numel_xf), k);
//计算核相关矩阵
k.convertTo(k, CV_32FC1);
cv::dft(k, kf, DFT_COMPLEX_OUTPUT); //转换到频域
return kf;
}