• PCA人脸识别


    人脸数据来自http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html

    实现代码和效果如下。由于图片数量有限(40*10),将原有图片顺序打乱进行检测。

    可见马氏距离效果最佳。

    [以下公式和文字来自John Hany的博文 http://johnhany.net/2016/05/from-qr-decomposition-to-pca-to-face-recognition/]

    PCA(Principal Component Analysis,主成分分析)

    PCA是一种很常用的根据变量协方差对数据进行降维、压缩的方法。它的精髓在于尽量用最少数量的维度,尽可能精确地描述数据。

    将PCA用于人脸识别的过程如下:

    基于QR分解的PCA算法步骤如下:

    进一步,进行人脸识别的过程如下:

    距离度量d:

     1 #coding:utf8
     2 import cv2
     3 import numpy as np
     4 import matplotlib.pyplot as plt
     5 
     6 def load_img():
     7     img=[]
     8     for i in range(40):
     9         for j in range(10):
    10             path='att_faces\s'+str(i+1)+'\'+str(j+1)+'.pgm'
    11             a=cv2.imread(path,0)
    12             a=a.flatten()/255.0
    13             img.append(a)
    14     return img
    15 
    16 def dis(A,B,dis_type=0,s=None):
    17     if dis_type==1:  # 欧式距离
    18         return np.sum(np.square(A-B))
    19     elif dis_type==2:  # 马式距离
    20         f=np.sqrt(abs(np.dot(np.dot((A-B),s.I),(A-B).T)))  # h增大时右侧会出现负值,防止溢出可以s/np.linalg.norm(s)
    21         return f.tolist()[0][0]
    22     else:  # 曼哈顿距离
    23         return np.sum(abs(A-B))
    24 
    25 def pca(data,h,dis_type=0):
    26     q,r=np.linalg.qr(data.T)
    27     u,s,v=np.linalg.svd(r.T)
    28     fi=np.dot(q,(v[:h]).T)
    29     y=np.dot(fi.T,data.T)
    30     ym=[np.mean(np.reshape(x,(40,10)),axis=1) for x in y]
    31     ym=np.reshape(ym,(h,40))
    32     c=[]
    33     if dis_type==2:# 计算马氏距离的额外处理"
    34         yr=[np.reshape(x,(40,10)) for x in y]
    35         yr=[[np.array(yr)[j][k] for j in  range(h)]for k in range(40)]
    36         for k in yr:
    37             k=np.reshape(k,(h,10))
    38             e=np.cov(k)
    39             c.append(e)
    40     return fi,ym,c
    41 
    42 def validate(fi,ym,test,label,dis_type=0,c=None):
    43     ty=np.dot(fi.T,test.T)
    44     correctnum=0
    45     testnum=len(test)
    46     for i in range(testnum):
    47         if dis_type==2:
    48             n=len(ym.T)
    49             dd=[dis(ty.T[i],ym.T[n_],dis_type,np.mat(c[n_])) for n_ in range(n)]
    50         else:
    51             dd=[dis(ty.T[i],yy,dis_type) for yy in ym.T]
    52         if np.argsort(dd)[0]+1==label[i]:
    53             correctnum+=1
    54     rate = float(correctnum) / testnum
    55     print "Correctnum = %d, Sumnum = %d" % (correctnum, testnum), "Accuracy:%.2f" % (rate)
    56     return rate
    57 
    58 if __name__ == '__main__':
    59     img=load_img()
    60     test=img
    61     label=[a+1 for a in range(40) for j in range(10)]
    62     index=range(400)
    63     np.random.shuffle(index)
    64     label_=[label[i] for i in index]
    65     test_=np.mat([test[i] for i in index])
    66     x_=[2**i for i in range(9)]
    67     d_=['Manhattan Distance','Euclidean Metric', 'Mahalanobis Distance']
    68     for j in range(3):
    69         y_=[]
    70         plt.figure()
    71         for i in range(9):
    72             fi,ym,c=pca(np.mat(img),h=x_[i],dis_type=j)
    73             y_.append(validate(fi,ym,test_,label_,dis_type=j,c=c))
    74         plt.ylim([0,1.0])
    75         plt.plot(x_,y_)
    76         plt.scatter(x_,y_)
    77         plt.xlabel('h')
    78         plt.ylabel('Accuracy')
    79         plt.title(d_[j])
    80     plt.show()

  • 相关阅读:
    拖拽系列二、利用JS面向对象OOP思想实现拖拽封装
    拖拽系列一、JavaScript实现简单的拖拽效果
    CSS3中三角形及三角形组合图实现
    计算机内存管理介绍
    [Leetcode]双项队列解决滑动窗口最大值难题
    [Leetcode]827.使用回溯+标记解决最大人工岛问题
    计算机启动过程
    [Leetcode]895.最大频率栈
    GDB查看内存(x 命令)
    理解递归
  • 原文地址:https://www.cnblogs.com/qw12/p/6090710.html
Copyright © 2020-2023  润新知