人脸识别(2)--fisherface

来源:互联网 发布:linux ant 环境变量 编辑:程序博客网 时间:2024/06/10 03:05

Fisherface与Eigenface思路差不多,都是从整体上对图像信息做主成分分析。

不同的是,Fisherface认为同一个人由于光照和角度带来的差异往往要大于不同人之间的差异,而Eigenface单纯的提取主成分可能得到的是一个类别不同光照条件的特征。
因此Fisherface试图最大化类间散度同时最小化类内散度。算法实现上则是首先PCA做初步筛选,然后以类间散度和类内散度为准则做LDA(Linear Discriminant Analysis,线性判别分析)。


线性判别分析(LDA)推导1

(1) 两类的情况

在线性代数中,矩阵的左乘 y=wTx 可以解释为 x 通过 w 映射到另一种空间表达 y,因此对于分类问题,关键就是找到合适的映射 w

对第i类 wi,其中心点为 μi=1Nixwix,其中 Ni 为该类的样本数。
假设存在映射 w,则中心点投影后为 μ˜i=1NixwiwTx=1NiwTμi

一个理想的映射 w 会使得投影后类间距离尽可能大,类内距离尽可能小。对两类情况,即下式中b(w)值越大越好,i(w)越小越好:
b(w)=|μ˜1μ˜2|=|wT(μ1μ2)|
i(w)=yw1(yμ˜1)2+yw2(yμ˜2)2
结合上面两个式子,当J(w)取极大值时对应最佳w:

J(w)=|μ˜1μ˜2|2s˜21+s˜22

其中 s˜2i=xwi(wTxwTμi)2=xwiwT(xμi)(xμi)Tw

si=xwi(xμi)(xμi)T
那么原始数据的类内散度为 Sw=S1+S2
投影后的类内散度S˜21+S˜22=wTSWw
考虑 J(w) 分子容易推得投影后的类间散度 (μ˜1μ˜2)2=wT(μ1μ2)(μ1μ2)Tw=wTSBw

由此,得到优化函数的最终表达:

J(w)=wTSBwwTSWw

可以用拉格朗日乘数法求解该式取极大值的w,将分母作为限定条件(令wTSWw=1
这样有 c(w)=wTSBwλ(wTSWw1)
对w求偏导,取0有 SBw=λSWw
上式两边同乘以 S1W 有: S1WSBw=λw
容易看到,欲求的w就是 S1WSB 的特征向量

(2) 多类的情况

与两类的过程一样,但类内散度和类间散度有一点差别。
类内散度:SW=ci=1Swi
     其中 Swi=xwi(xμi)(xμi)T为每个类的类内散度
类间散度:SB=ci=1Ni(μiμ)(μiμ)T
     其中 Ni 为第i类的样本数,μ=1NxwiNiμi为所有样本中心
由此,易得投影后的类内散度和类间散度:
{S˜W=wTSWwS˜B=wTSBw

注:S1WSB 的特征向量个数最多为C-1,即对N个人的数据集,最多可提取N-1个特征向量。


算法实现

OpenCV2.4以上版本封装了Fisherface的实现,这里有C++的官方例程
bytefish有详细的算法解释,并提供了matlab和python的实现

实验发现,对于训练的样本(FERET),测试结果精度就很高,OpenCV提供的接口无论是Eigenface还是Fisherface都能达到95%以上,但对于未被用于训练的样本,识别精度很低(bytefish在40%左右,OpenCV仅有8%)。说明Eigenface和Fisherface的泛化能力较差。

              OpenCV接口使用不同测试集的精度对比
    图1. OpenCV的Fisherface接口(a)使用未参加训练的样本分类精度;(b)使用参加训练的样本分类精度


0 0
原创粉丝点击