import cv2
import numpy as np
import os
from sklearn import neighbors
import tkinter
from tkinter import filedialog
#讀取人臉資料庫
#準備訓練資料
'''def openfile():
r = filedialog.askopenfilename(title='選擇要識別的人臉', filetypes=[('face','*.jpg *.jpg'), ('all files', '*')])
print(r)
x_test=cv2.imread(r,0)
cv2.imshow('you',x_test)
cv2.waitkey(0)
return x_test
root = tkinter.tk()
btn1 = tkinter.button(root, text='choose face', command=openfile)
btn1.pack(side='left')
root.title('李存程')
root.mainloop()
'''def loadimages(data):
'''data:train content
images:[m,height,width]
m樣本數
height高
width寬
name:名字的集合
label:標籤
'''images =
labels =
names =
label=0
#讀取**所在的所有資料夾
for subdirname in os.listdir(data):
subjectpath = os.path.join(data,subdirname)
if os.path.isdir(subjectpath):
#乙個資料夾乙個人**
for filename in os.listdir(subjectpath):
imgpath = os.path.join(subjectpath,filename)
img = cv2.imread(imgpath,0) #or cv2.imread_grayscale
label = label+1
images = np.asarray(images) #將列表轉到陣列,一張對應陣列一行
labels =np.asarray(labels)
return images,labels,names
class face(object):
def __init__(self,dimnum=150,n_neighbors=3,dsize=(46,56)):
'''dimnum:pca降維後的維度
neighbor:knn引數
dsize:影象預處理的尺寸
'''self._dimnum = dimnum
self._dsize = dsize
self._mean = 0.0
self._knn = neighbors.kneighborsclassifier(n_neighbors)
def _pca(self,x):
'''pca降維
params:
x:trainset 形狀[m,n],m個樣本,n為特徵數
return 降維後的資料[m,k]和變換矩陣p=[k,n]
'''#原始資料是m行n列,訓練集每一行對應乙個樣本,pca中每一列乙個樣本
#變為[n,m]
x=x.t
#求特徵的均值
mean = np.reshape(np.mean(x,axis=1),(-1,1)) #axis=0求列的均值,axis=1求行的均值
self._mean = mean
#reshape(-1,1)#1表一列,-1行未知
#減去均值[n,m]-[n,1]
diff = x - mean
'''協方差計算
np.dot(diff,diff.t) [n,n]
np.dot(diff.t,diff) [m,m]
n>>m
'''cov = np.dot(diff.t,diff)/diff.shape[1]#shape[0]表示行數[1]表示列數
'''計算協方差舉證的特徵值和特徵向量
特徵值m個
特徵向量m個m維向量
'''ei**als,ei**ects = np.linalg.eig(cov)
'''左乘diff得到[n,n]矩陣的特徵向量[n,m]
'''ei**ects = np.dot(diff,ei**ects)
print("特徵向量的維度:",ei**ects.shape)
'''對特徵值從大到小排序
'''ei**alindex = np.argsort(ei**als)
ei**alindex = ei**alindex[::-1]
'''取特徵值大的前面k個
'''ei**alindex = ei**alindex[:self._dimnum]
'''將特徵向量歸一化
'''ei**ects = ei**ects/np.linalg.norm(ei**ects,axis=0)
'''變換矩陣[k,n]
'''transmat = (ei**ects.t)[ei**alindex,:]
'''計算經過變換矩陣變換後的資料[k,n]*[n,m] =[k,m]
'''lowmat = np.dot(transmat,diff)
lowmat = lowmat.t
print('降維後的矩陣維度:',lowmat.shape)
return lowmat,transmat
def _prepare(self,images):
'''的預處理,直方圖均衡化
[m,height,width] m樣本數 height高width寬
return 處理後的資料[m,n]
特徵數n=dsize[0]*dsize[1]
'''new_images =
for image in images:
re_img = cv2.resize(image,self._dsize)
#直方圖均衡化
hist_img = cv2.equalizehist(re_img)
#轉換為一行
hist_img = np.reshape(hist_img,(1,-1))
new_images = np.asarray(new_images)#列表變為陣列
return new_images
def fit(self,x_train,y_train):
'''knn
x_train訓練集資料,gray[m,height,width]m樣本數height高width寬
y_train訓練集標籤
[m]'''
#對預處理[m,n]
x_train = self._prepare(x_train)
x_train_pca,self._transmat = self._pca(x_train)
#begin train
self._knn.fit(x_train_pca,y_train)
def predict(self,x_test):
'''x_test測試gray
return
y_pred:測試標籤
'''if len(x_train.shape)==2:
x_test = self._prepare(x_test,axis=0)
#對資料預處理[m,n]
x_test = self._prepare(x_test)
#計算變換後的矩陣[m,k]
pca演算法實現人臉識別
用matlab實現的pca演算法,用於降維,適用於各種試驗,如人臉識別程式。使用方法 1 選擇訓練和測試的資料庫路徑 2 選擇測試影象的路徑 3 執行createdatabase 函式給訓練影象建立二維矩陣 4 執行 eigenfacecore 函式建立基本的空間 5 執行 recognition ...
基於PCA的人臉識別步驟
人臉識別是乙個有監督學習過程,首先利用訓練集構造乙個人臉模型,然後將測試集與訓練集進行匹配,找到與之對應的訓練集頭像。最容易的方式是直接利用歐式距離計算測試集的每一幅影象與訓練集的每一幅影象的距離,然後選擇距離最近的影象作為識別的結果。這種直接計算距離的方式直觀,但是有乙個非常大的缺陷 計算量太大。...
基於PCA的人臉識別步驟
人臉識別是乙個有監督學習過程,首先利用訓練集構造乙個人臉模型,然後將測試集與訓練集進行匹配,找到與之對應的訓練集頭像。最容易的方式是直接利用歐式距離計算測試集的每一幅影象與訓練集的每一幅影象的距離,然後選擇距離最近的影象作為識別的結果。這種直接計算距離的方式直觀,但是有乙個非常大的缺陷 計算量太大。...