创建训练人脸库的特征脸空间——主成分分析(PCA)方法
(1)创建所有训练样本组成的M×N矩阵trainFaceMat。其中,M为样本个数,N为一个训练样本图像所有像素按列相连的像素值
(M = 人数[我们提供的数据包含了30个人的人脸数据] * count [5-7] ,也就是说我们有30个人的数据,每个人选出5-7张图片作为训练的数据。现在确定一下数据,假设我们每个人选取7张照片,那么M就等于30 * 7,代表了我们需要用210张图片作为训练数据)(我们让计算机认识每一个人,而每一个人我们给计算机看7张照片,这样可以加深计算机对每个人的印象,那么除了大家选取出来的7张照片以外,每个人脸数据都还有多余的照片没有使用,那么这些没让计算机看过的照片,就可以在计算机认识了每一个人之后用来考验计算机是否真的已经能够正确识别图像中的人是谁)
(N = 像素点的个数,比如一张图片的大小是60 * 50, 那么N就等于300, 一个N代表这一张人脸的数据)
(2)计算训练样本的平均值矩阵meanFaceMat,该矩阵为1×N矩阵
(1 * N就代表目前算出来的平均值矩阵是 一张 人脸的数据,这张平均脸其实就是把上面的M * N的矩阵平均化,把这M张照片的每一个位置对应的数值加起来,然后再除以M。可以理解为把一个M * N的二维数组的每一列都加起来,变成一个1 * N的数组,然后这个数组的每一位都除以M,最后得到一个1 * N的平均值脸)(平均脸的作用就是为了找到一张跟所有人都很像的脸,这个地方就有点找公因数的感觉了)
(3)计算规格化后的训练样本矩阵normTrainFaceMat,矩阵大小为M×N。计算公式为:
normTrainFaceMat(i,:)= trainFaceMat(i,:)-meanFaceMat
1
(这一步的公式包含了python的一点语言,这里的意思是用我们一开始得到的M*N的矩阵减去我们的平均脸,即计算出我每个人的数据跟这个平均脸的差异,我们把计算结果成为差值矩阵)
(4)计算normTrainFaceMat的协方差矩阵的特征值和特征向量。python中的计算公式为:
covariance = np.cov(normTrainFaceMat) #根据差值矩阵计算得出协方差矩阵
eigenvalue, featurevector = np.linalg.eig(covariance) #求得特征值和特征向量
1
2
其中,矩阵featurevector 的列向量为特征向量,eigenvalue为特征值组成的对角阵。
没有什么算法,大家直接调用numpy提供的函数就可以得到计算结果。
(5)获取特征值按降序排序对应原矩阵的下标,python中的计算公式为:
sorted_Index = np.argsort(eigenvalue)
1
其中,sorted_Index为排序后的特征值在原序列中的索引,这个只是个下标,并不是具体排序后的特征值。
(6)由于特征向量与特征值是相互对应的,我们可以直接根据刚刚得到的特征值排序后对应原序列中的索引来得到排序后的特征向量,公式如下:
topk_evecs = featurevector[:, sorted_Index[:-k - 1:-1]]
1
这是一个由前k个特征向量组成的矩阵,一个特征向量可以理解为一个特征,我们取最具有代表性的k个特征来构成我们的特征空间。选取前k个特征向量的过程我们叫做降维,降维的目的是为了抛弃那些对我们计算影响不大的值,减少计算量,只选前k个而不选排名靠后的原因就是因为后面的数据对我们的影响不大,可以抛弃。K可以取150左右。
(7)获得训练样本的特征脸空间:
eigenface = normTrainFaceMat' * eig_vec
1
注意这个地方的normTrainFaceMat是转置了的,它的右上角有个撇,在numpy中要使用transpose()方法,对其转置,而“ * ”号代表点乘,在numpy中使用dot()函数计算
得到的矩阵eigenface大小为N×m,每一列是一个长度为N的特征脸,共m列。
----------------------------(到这一步,我们就得到了所谓的公因数)--------------------------
(8)训练样本在特征脸空间的投影:
eigen_train_sample = np.dot(normTrainFaceMat, eigenface);
1
上面解释过dot函数是什么,它就代表了两个矩阵之间的点乘
得到eigen_train_sample为投影样本矩阵,大小为M×m,每一行为一个训练样本图像在特征脸空间的投影。由于m<<N,经过投影可获得更能描述训练样本图像特征的描述。
—(到目前为止,我们计算出了特征脸空间,也计算出了训练数据在特征空间中的投影)—
Ps:接下来,我们只需要把要识别的图片,也计算出它的差值矩阵,并且把差值矩阵在特征脸空间上的投影计算出来,这个投影即代表了我们之前提到的公因数的倍数。我们可以把待识别图片的投影与训练数据中每个人的图片的投影通过“距离公式”计算出“距离”,通过观察待识别图片与训练数据中哪个人的投影距离最近,那么待识别图片上的人就是谁。比如我们有编号1-30的训练数据的投影,我们的待识别图片为A,我们计算出A在特征脸空间上的投影与编号1-30的每一个投影的的距离,假设现在计算出A与1号的距离最近,那么我们就可以认为A就是1号。