1. 程式人生 > >PCA的人臉識別(含matlab程式碼)

PCA的人臉識別(含matlab程式碼)

在讀完Baback Moghaddam大神的論文之後,我們來講下具體的程式碼實現。我們以人臉的識別為例子,講述下具體的實現。

(1)首先我們需要有人臉的資料集,在這裡對應每個人只有一個照片在資料集中,例子中,人臉圖片的數目是9,每張圖片的size是40*40,我們講每張圖片reshape一下,改成1*1600的矩陣,所以 我們的人臉資料集是一個 9 * 1600的矩陣。每一行代表一個人臉,共九個。[這裡說明下,由於這九張人臉影象不是0-255,而test影象是0-255的,所以為了統一,我們標準化下這九張影象,即把每個點的畫素值 對映到0-255]。


(2)我們有一個全影象,上面有九個人的臉,我們需要做的就是,找到九個人臉的位置。


(3)對於(1)中的人臉資料集做PCA[直接使用matlab中的princomp函式],得到


coeff(1600*1600) 是對應的特徵向量,每一列代表一個特徵向量,latent代表特徵值。在這裡我們取N =  9,M = 6[這裡我們為了方便計算,並沒有將N 取成1600,而是先降階一次,令P = coeff(:,1:9)].

並計算F = mean(faces) [size 大小是 1*1600],得到資料集的平均臉。

(4)新建一個矩陣vector,將test中的每個可能的候選位置,以及對應位置的子影象x,並把這個子影象reshape成1*1600,存放在這個矩陣中,由於test影象的大小是160*160, 所以這個新矩陣的size應該是(121*121,1600),

(5)計算x~ = x - x_, 這裡的x是矩陣vector中的每一行,x_就是(3)中計算出的平均臉

(6)計算x~在新的特徵空間中的座標 ,由於matlab princomp函式的差異,y = x~ * P[size大小是14641 * 9],

(7)新建一個馬氏距離矩陣distance[size 14641 * 1],並利用博文中的公式,計算出d(x), 由於這裡我們取N = 9,M = 6,所以 ρ = (1/3) * (sum(latent(7:9,1))).


距離影象如圖所示,我們可以發現有九個點的值是最小的[即最黑,因為極值點周圍的偏差的點也是很黑的,例如如果我們找到了定位點O,那麼與之相鄰的點P,這兩個點的匹配出來的馬氏距離應該都很小,當然O更小,但是問題來了,如果另一幅人臉的定位點是M,而如果P的定位點的馬氏距離比M 小,那麼我們就會發現我們並不能找到M 點,如果通過選取第二小的方式來找到M,因為P 比M 小]

(8)對應的解決方法是,我們找到第一小的點O之後,記錄下O 點的位置,並將以O為中心點的子影象x(40*40)全部改成distance中的最大值,這樣在第二輪尋找中,與O 相鄰的P 就不會被計算,而能找到下一個人臉的位置了。如此9次之後,我們找到了9個臉位於test影象中的座標


(9)將9個座標在原影象上表示出來,得到


我們發現,9個點都被定位成功,我們再來看下這九個點對應的馬氏座標

我們發現,馬氏距離最小的點,也是第一個被找到的點,如第7張人臉的馬氏距離最小,因此 第七張圖也是最早被找到的。