利用pca和knn實現人臉識別

2021-09-11 17:29:20 字數 4476 閱讀 6249

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的人臉識別步驟

人臉識別是乙個有監督學習過程,首先利用訓練集構造乙個人臉模型,然後將測試集與訓練集進行匹配,找到與之對應的訓練集頭像。最容易的方式是直接利用歐式距離計算測試集的每一幅影象與訓練集的每一幅影象的距離,然後選擇距離最近的影象作為識別的結果。這種直接計算距離的方式直觀,但是有乙個非常大的缺陷 計算量太大。...