(2D-2D PCA)算法实现
import numpy as np
from PIL import Image
import time
from numpy.core.fromnumeric import size
from numpy.lib.function_base import append, cov
import copy
def PCAReg(train_samples, test_samples, rate):
print('----------------------PCA------------------------------')
time_0 = time.time()
M = len(train_samples)
for i in range(0,len(train_samples)):
train_samples[i] = train_samples[i].flatten()
for i in range(0,len(test_samples)):
test_samples[i] = test_samples[i].flatten()
train_samples_orgin = copy.deepcopy(train_samples)#必须备份一次
pic_shape = train_samples[0].shape
print(pic_shape)#(10304,)
# print(train_samples)
#中心化
mean_pic = np.zeros(pic_shape)
for p in train_samples:
mean_pic = mean_pic + p
mean_pic = mean_pic/float(len(train_samples))
# print(mean_pic)
for i in range(0,len(train_samples)):
train_samples[i] = train_samples[i] - mean_pic
M = len(train_samples)
print(train_samples[0].shape)#(10304,)
pic_all = train_samples[0]
for i in range(1,M):
#垂直拼接
pic_all = np.vstack( (pic_all,train_samples[i]) )
print(pic_all.shape)#(200, 10304)
# print(pic_all)
#计算协方差矩阵
cov_m = np.zeros((pic_all.shape[1],pic_all.shape[1]))
cov_m = np.dot(pic_all.T,pic_all)
# print('协方差矩阵为')
# print(cov_m)
print('协方差矩阵shape')
print(cov_m.shape)#(10304, 10304)
#求特征值与特征向量
cval, cvec = np.linalg.eig(cov_m)#耗时大,调试时不用
# cval = np.random.rand(5600)
# cvec = np.random.rand(5600,5600)
print(cval.shape)#(10304,)
print(cvec.shape)#(10304, 10304)
sorted_index = np.argsort(cval)
cval.sort()
cval_sorted = cval
cval_sorted = cval_sorted[::-1]
# print('特征值从大到小')
# print(cval_sorted)
#求特征向量的总和
sum_cval = 0
for c in cval:
sum_cval += c
dim_cnt = 0
cval_sum = 0#组成投影矩阵的特征向量的特征值总和
while cval_sum < rate * sum_cval:
cval_sum = cval_sum + cval_sorted[dim_cnt]
dim_cnt = dim_cnt + 1
print('特征值总和')
print(sum_cval)
print('选取的特征值总和')
print(cval_sum)
print('选取的特征值的个数')
print(dim_cnt)
#构造投影矩阵
# X = cvec[sorted_index[:-dim_cnt-1:-1],:]
X = cvec[:,sorted_index[:-dim_cnt-1:-1]]#尝试一下是不是列的问题
print('投影矩阵shape')
print(X.shape)#(110, 10304)
tra_loc = []
tst_loc = []
kk = 1
for p in train_samples_orgin:
img_loc = np.empty((dim_cnt,),dtype=float)#错在此处
# if kk == 1:
# print('np.dot(np.dot(p,X.T),X) .shape')
# print(np.dot(p,X.T).shape)
# kk=0
img_loc = np.dot(X.T,p).flatten()
tra_loc.append(img_loc)
tra_loc_np = tra_loc[0]
for i in range(1,len(tra_loc)):
tra_loc_np = np.vstack((tra_loc_np, tra_loc[i]))
# print('tra_loc_np.shape')
# print(tra_loc_np.shape)
for p in test_samples:
img_loc = np.empty((dim_cnt,),dtype=float)
img_loc = np.dot(X.T,p).flatten()
tst_loc.append(img_loc)
tst_loc_np = tst_loc[0]
for i in range(1,len(tst_loc)):
tst_loc_np = np.vstack((tst_loc_np,tst_loc[i]))
print('tra_loc_np的shape为')
print(tra_loc_np.shape)
print('tst_loc_np的shape为')
print(tst_loc_np.shape)
min_dist_sample = np.zeros((len(tst_loc_np),),dtype=int)
for i in range(0,len(tst_loc_np)):
min_dist = float('inf')
for j in range(0,len(tra_loc_np)):
dist = np.linalg.norm(tst_loc_np[i] - tra_loc_np[j])
if dist < min_dist:
min_dist = dist
min_dist_sample[i] = j
# print(min_dist_sample)
true_num = 0
for i in range(0,len(min_dist_sample)):
if(min_dist_sample[i]//5 == i//5):#坑爹,Python整除是//
true_num = true_num + 1
print('PCA人脸识别准确率为:' + str(true_num * 1.0/len(test_samples)) )
time_1 = time.time()
print('PCA人脸图像表示和识别共耗时: ' + str(time_1-time_0)+' 秒')
def PCA2DReg(train_samples, test_samples, rate):
print('----------------------2DPCA------------------------')
time_0 = time.time()
train_samples_orgin = copy.deepcopy(train_samples)
#图片矩阵大小m*n pic_shape = (n,m)
pic_shape = train_samples[0].shape
print('pic_shape:')
print(pic_shape)#(80, 70)
#求均值
mean_pic = np.zeros(pic_shape)
for p in train_samples:
mean_pic = mean_pic + p
mean_pic = mean_pic/float(len(train_samples))
#求协方差矩阵
#大小n*n
cov_m = np.zeros((pic_shape[1],pic_shape[1]),dtype=float)
for tra_s in train_samples:
#中心化
diff = tra_s - mean_pic
#求协方差矩阵
cov_m = cov_m + np.dot(diff.T,diff)
cval, cvec = np.linalg.eig(cov_m)
print('cvec.shape')
print(cvec.shape)
sorted_index = np.argsort(cval)
cval.sort()
cval_sorted = cval
cval_sorted = cval_sorted[::-1]
# print('特征值从大到小')
# print(cval_sorted)
#求特征向量的总和
sum_cval = 0
for c in cval:
sum_cval += c
dim_cnt = 0
cval_sum = 0#组成投影矩阵的特征向量的特征值总和
while cval_sum < rate * sum_cval:
cval_sum = cval_sum + cval_sorted[dim_cnt]
dim_cnt = dim_cnt + 1
print('特征值总和')
print(sum_cval)
print('选取的特征值总和')
print(cval_sum)
print('选取的特征值的个数')
print(dim_cnt)
#构造投影矩阵
X = cvec[:,sorted_index[:-dim_cnt-1 : -1]]
print('投影矩阵shape')
print(X.shape)#(70, 20)
tra_loc = []
tst_loc = []
for p in train_samples_orgin:
img_loc = np.empty((dim_cnt,),dtype=float)#错在此处
img_loc = np.dot(p,X).flatten()
tra_loc.append(img_loc)
tra_loc_np = tra_loc[0]
for i in range(1,len(tra_loc)):
tra_loc_np = np.vstack((tra_loc_np, tra_loc[i]))
# print('tra_loc_np.shape')
# print(tra_loc_np.shape)
for p in test_samples:
img_loc = np.empty((dim_cnt,),dtype=float)
img_loc = np.dot(p,X).flatten()
tst_loc.append(img_loc)
tst_loc_np = tst_loc[0]
for i in range(1,len(tst_loc)):
tst_loc_np = np.vstack((tst_loc_np,tst_loc[i]))
# print('tra_loc_np的shape为')
# print(tra_loc_np.shape)
# print('tst_loc_np的shape为')
# print(tst_loc_np.shape)
min_dist_sample = np.zeros((len(tst_loc_np),),dtype=int)
for i in range(0,len(tst_loc_np)):
min_dist = float('inf')
for j in range(0,len(tra_loc_np)):
dist = np.linalg.norm(tst_loc_np[i] - tra_loc_np[j])
if dist < min_dist:
min_dist = dist
min_dist_sample[i] = j
# print(min_dist_sample)
true_num = 0
for i in range(0,len(min_dist_sample)):
if(min_dist_sample[i]//5 == i//5):#坑爹,Python整除是//
true_num = true_num + 1
print('2DPCA人脸识别准确率为:' + str(true_num * 1.0/len(test_samples)) )
time_1 = time.time()
print('2DPCA人脸图像表示和识别共耗时: ' + str(time_1-time_0)+' 秒')
def PCA2DAlternativeReg(train_sampls,test_samples, rate):
print('----------------Alternative2DPCA--------------------')
time_0 = time.time()
train_samples_orgin = copy.deepcopy(train_samples)
#图片矩阵大小m*n pic_shape = (n,m)
pic_shape = train_samples[0].shape
print('pic_shape:')
print(pic_shape)#(80, 70)
#求均值
mean_pic = np.zeros(pic_shape)
for p in train_samples:
mean_pic = mean_pic + p
mean_pic = mean_pic/float(len(train_samples))
#求协方差矩阵
#大小n*n
cov_m = np.zeros((pic_shape[0],pic_shape[0]),dtype=float)
for tra_s in train_samples:
#中心化
diff = tra_s - mean_pic
#求协方差矩阵
cov_m = cov_m + np.dot(diff,diff.T)
cval, cvec = np.linalg.eig(cov_m)
print('cvec.shape')
print(cvec.shape)
sorted_index = np.argsort(cval)
cval.sort()
cval_sorted = cval
cval_sorted = cval_sorted[::-1]
# print('特征值从大到小')
# print(cval_sorted)
#求特征向量的总和
sum_cval = 0
for c in cval:
sum_cval += c
dim_cnt = 0
cval_sum = 0#组成投影矩阵的特征向量的特征值总和
while cval_sum < rate * sum_cval:
cval_sum = cval_sum + cval_sorted[dim_cnt]
dim_cnt = dim_cnt + 1
print('特征值总和')
print(sum_cval)
print('选取的特征值总和')
print(cval_sum)
print('选取的特征值的个数')
print(dim_cnt)
#构造投影矩阵
Z = cvec[:,sorted_index[:-dim_cnt-1 : -1]]
print('投影矩阵shape')
print(Z.shape)#(80, 21)
tra_loc = []
tst_loc = []
for p in train_samples_orgin:
img_loc = np.empty((dim_cnt,),dtype=float)#错在此处
img_loc = np.dot(Z.T,p).flatten()
# print('np.dot(np.dot(p.T,p),X) .shape')
# print(img_loc.shape)
tra_loc.append(img_loc)
tra_loc_np = tra_loc[0]
for i in range(1,len(tra_loc)):
tra_loc_np = np.vstack((tra_loc_np, tra_loc[i]))
# print('tra_loc_np.shape')
# print(tra_loc_np.shape)
for p in test_samples:
img_loc = np.empty((dim_cnt,),dtype=float)
img_loc = np.dot(Z.T,p).flatten()
tst_loc.append(img_loc)
tst_loc_np = tst_loc[0]
for i in range(1,len(tst_loc)):
tst_loc_np = np.vstack((tst_loc_np,tst_loc[i]))
# print('tra_loc_np的shape为')
# print(tra_loc_np.shape)
# print('tst_loc_np的shape为')
# print(tst_loc_np.shape)
min_dist_sample = np.zeros((len(tst_loc_np),),dtype=int)
for i in range(0,len(tst_loc_np)):
min_dist = float('inf')
for j in range(0,len(tra_loc_np)):
dist = np.linalg.norm(tst_loc_np[i] - tra_loc_np[j])
if dist < min_dist:
min_dist = dist
min_dist_sample[i] = j
# print(min_dist_sample)
true_num = 0
for i in range(0,len(min_dist_sample)):
if(min_dist_sample[i]//5 == i//5):#坑爹,Python整除是//
true_num = true_num + 1
print('Alternative2DPCA人脸识别准确率为:' + str(true_num * 1.0/len(test_samples)) )
time_1 = time.time()
print('Alternative2DPCA人脸图像表示和识别共耗时: ' + str(time_1-time_0)+' 秒')
def PCA2D2DReg(train_samples, test_samples, rate):
print('-------------------2D2DPCA--------------------')
time_0 = time.time()
train_samples_orgin = copy.deepcopy(train_samples)
#图片矩阵大小m*n pic_shape = (n,m)
pic_shape = train_samples[0].shape
print('pic_shape:')
print(pic_shape)#(80, 70)
#求均值
mean_pic = np.zeros(pic_shape)
for p in train_samples:
mean_pic = mean_pic + p
mean_pic = mean_pic/float(len(train_samples))
#求协方差矩阵
#大小n*n
cov_m_z = np.zeros((pic_shape[0],pic_shape[0]),dtype=float)
cov_m_x = np.zeros((pic_shape[1],pic_shape[1]),dtype=float)
for tra_s in train_samples:
#中心化
diff = tra_s - mean_pic
#求协方差矩阵
cov_m_z = cov_m_z + np.dot(diff,diff.T)
cov_m_x = cov_m_x + np.dot(diff.T,diff)
cval_z, cvec_z = np.linalg.eig(cov_m_z)
cval_x, cvec_x = np.linalg.eig(cov_m_x)
print('cvec_z.shape')
print(cvec_z.shape)
print('cvec_x.shape')
print(cvec_x.shape)
sorted_index_z = np.argsort(cval_z)
cval_z.sort()
cval_sorted_z = cval_z
cval_sorted_z = cval_sorted_z[::-1]
sorted_index_x = np.argsort(cval_x)
cval_x.sort()
cval_sorted_x = cval_x
cval_sorted_x = cval_sorted_x[::-1]
#求特征向量的总和
sum_cval_z = 0
sum_cval_x = 0
for c in cval_z:
sum_cval_z += c
for c in cval_x:
sum_cval_x += c
dim_cnt_z = 0
dim_cnt_x = 0
cval_sum_z = 0#组成投影矩阵的特征向量的特征值总和
cval_sum_x = 0
while cval_sum_z < 0.95 * sum_cval_z:
cval_sum_z = cval_sum_z + cval_sorted_z[dim_cnt_z]
dim_cnt_z = dim_cnt_z + 1
while cval_sum_x < rate * sum_cval_x:
cval_sum_x = cval_sum_x + cval_sorted_x[dim_cnt_x]
dim_cnt_x = dim_cnt_x + 1
#构造投影矩阵
Z = cvec_z[:,sorted_index_z[:-dim_cnt_z-1 : -1]]
X = cvec_x[:,sorted_index_x[:-dim_cnt_x-1 : -1]]
print('投影矩阵Z.shape')
print(Z.shape)#(80, 21)
print('投影矩阵X.shape')
print(X.shape)#(80, 21)
tra_loc = []
tst_loc = []
for p in train_samples_orgin:
img_loc = np.empty((dim_cnt_z,),dtype=float)#错在此处
img_loc = np.dot(np.dot(Z.T,p),X).flatten()
# print('np.dot(np.dot(p.T,p),X) .shape')
# print(img_loc.shape)
tra_loc.append(img_loc)
tra_loc_np = tra_loc[0]
for i in range(1,len(tra_loc)):
tra_loc_np = np.vstack((tra_loc_np, tra_loc[i]))
# print('tra_loc_np.shape')
# print(tra_loc_np.shape)
for p in test_samples:
img_loc = np.empty((dim_cnt_z,),dtype=float)
img_loc = np.dot(np.dot(Z.T,p),X).flatten()
tst_loc.append(img_loc)
tst_loc_np = tst_loc[0]
for i in range(1,len(tst_loc)):
tst_loc_np = np.vstack((tst_loc_np,tst_loc[i]))
min_dist_sample = np.zeros((len(tst_loc_np),),dtype=int)
for i in range(0,len(tst_loc_np)):
min_dist = float('inf')
for j in range(0,len(tra_loc_np)):
dist = np.linalg.norm(tst_loc_np[i] - tra_loc_np[j])
if dist < min_dist:
min_dist = dist
min_dist_sample[i] = j
# print(min_dist_sample)
true_num = 0
for i in range(0,len(min_dist_sample)):
if(min_dist_sample[i]//5 == i//5):#坑爹,Python整除是//
true_num = true_num + 1
print('2D2DPCA人脸识别准确率为:' + str(true_num * 1.0/len(test_samples)) )
time_1 = time.time()
print('2D2DPCA人脸图像表示和识别共耗时: ' + str(time_1-time_0)+' 秒')
train_samples = []
test_samples = []
for i in range(1,41):
for j in range(1,11):
# img = Image.open('C:\\ORLdatabase\\'+str(i*10+j-10)+'_'+str(i)+'.jpg')
img = Image.open('C:\\ORLdatabase\\s'+str(i)+'\\'+str(j)+'.pgm')
# print(img.size)#宽乘高,如1920*1080,与我们矩阵的顺序是反的
img_processed = np.empty((img.size[1],img.size[0]), dtype = float)
for m in range(img.size[1]):
for n in range(img.size[0]):
p = img.getpixel((n,m))
#归一化
img_processed[m,n] = p/255.0
if j < 6 :
train_samples.append(img_processed)
else:
test_samples.append(img_processed)
ta = copy.deepcopy(train_samples)
ts = copy.deepcopy(test_samples)
#由于python的机制问题,以下PCAReg要深拷贝一份,不然后续3个函数会出错
rate = 0.95#后续更改此值可以改变投影矩阵的大小
PCAReg(ta,ts,rate)#耗时极长,建议注释掉不运行
PCA2DReg(train_samples,test_samples,rate)
PCA2DAlternativeReg(train_samples,test_samples,rate)
PCA2D2DReg(train_samples, test_samples,rate)
浙公网安备 33010602011771号