掌纹识别分析源代码
在进行掌纹识别前,我们需要对数据集进行简单的处理。
1.加载数据,代码如下:
#加载数据
def load_dataset():
X = [] # 特征
y = [] # 标签
for i in range(100):
for j in range(1,7):
path="E:\\palmbases\\"+"p_"+str(i)+"_"+str(j)+".bmp"
img = cv2.imread(path)
# 提取Gabor特征
#features = extract_gabor_features(img)
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
features = gray_img.flatten()
# 从文件名中提取类别标签
category = i
X.append(features)
y.append(category)
return X,y
2.划分数据集,这里先以4:2的比例进行分层抽样,代码如下:
#分层抽样划分数据集,每6张前4张做训练后俩张做测试
def data_split(x,y):
X_train=[]
X_test=[]
y_train=[]
y_test=[]
j=1#标记变量
for i in x:
if j<=4:
X_train.append(i)
j+=1
else:
X_test.append(i)
j+=1
if j==7:
j=1
j=1
for i in y:
if j<=4:
y_train.append(i)
j+=1
else:
y_test.append(i)
j+=1
if j==7:
j=1
return np.array(X_train),np.array(X_test),np.array(y_train),np.array(y_test)
3.不做处理,直接跑模型测试,这里选择svm模型,代码如下:
# 加载数据集
X, y = load_dataset()
#划分数据集
X_train, X_test, y_train, y_test=data_split(X,y)
# 初始化SVM分类器
clf = svm.SVC(kernel='rbf')
# 训练SVM模型
clf.fit(X_train, y_train)
# 在测试集上进行预测
y_pred = clf.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Test Accuracy: {accuracy}")
上面代码需要导入的包如下,也是下面代码所需要的:
import os
import cv2
import numpy as np
from sklearn import svm
from sklearn.decomposition import PCA
from sklearn.metrics import accuracy_score
最终svm跑出的准确率为0.96.
4.数据处理与训练
接下来我们试试对数据进行处理并训练看看结果。
(1)对数据进行降维,并利用循环遍历得出最佳维度,先观察以下数据的信息,代码如下:
X_train.shape
结果显示:(400, 16384)
降维函数如下:
def pca_transform(X_train,X_test, n_components):
# 使用PCA降维
pca = PCA(n_components=n_components)
train = pca.fit_transform(X_train)
test=pca.transform(X_test)
return train,test
根据上面结果看到维度高达16384维,下面是挑选最佳维度代码:
#获取最佳维度和准确率,利用svm计算
def pca_best(X_train,X_test):
acc=[]#各维度准确率集合
nlist=[]#各维度集合
a=10
acc1=0
for n in range(10,300,10):#先到300维看看,如果波动比较大再加
# 对训练数据和测试数据进行PCA降维
X_train_pca, X_test_pca = pca_transform(X_train,X_test,n)
# 初始化SVM分类器
clf = svm.SVC(kernel='rbf')
# 训练SVM模型
clf.fit(X_train_pca, y_train)
# 在测试集上进行预测
y_pred = clf.predict(X_test_pca)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
if accuracy==1:
return n,accuracy
acc.append(accuracy)
nlist.append(n)
#打印各维度对应的准确率,看看波动情况,如果准确率越来越平稳,则不用测试300维以后的维度,否之则不然
print("维度为:",n)
print("准确率为:",accuracy)
print("\n")
#获取最佳维度和准确率
for i in range(len(nlist)):
if acc1<acc[i]:
acc1=acc[i]
a=nlist[i]
return a,acc1
运行代码如下:
#前面已经划分好数据集
n,acc=pca_best(X_train,X_test)
print("最佳维度为:",n)
print("准确率为:",acc)
运行结果为:
最佳维度为: 70
准确率为: 0.985
(2)利用gabor滤波对数据进行处理
gabor滤波代码如下:
#建立gabor滤波器
def gabor_filter(img, frequency, theta):
kernel = cv2.getGaborKernel((21, 21), 5.0, theta, 10.0, 1.0, 0, ktype=cv2.CV_32F)
filtered_img = cv2.filter2D(img, cv2.CV_8UC3, kernel)
return filtered_img
#图像滤波
def extract_gabor_features(image):
#因为加载数据时已经进行过灰度转换了,所以下面一行注释掉
#gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_img=image
filtered_img = gabor_filter(gray_img, frequency=0.6, theta=1.0)
flattened_features = filtered_img.flatten()
return flattened_features
计算gabor后的准确率,代码如下:
def gabor_image(x):#将加载的数据集进行滤波
x_gabor=[]
for i in x:
features = extract_gabor_features(i)
x_gabor.append(features)
return x_gabor
#滤波
x_gabor=gabor_image(X)
#划分数据集
X_train, X_test, y_train, y_test=data_split(x_gabor,y)
# 初始化SVM分类器
clf = svm.SVC(kernel='rbf')
# 训练SVM模型
clf.fit(X_train, y_train)
# 在测试集上进行预测
y_pred = clf.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Test Accuracy: {accuracy}")
结果显示为:
Test Accuracy: 0.94
可以发现准确率相比没有滤波时下降了,我们参考下面论文:
D. Zhang, W. K. Kong, J. You, M. Wong. Online palmprint identification[J]. IEEETransactions on Pattern Analysis and Machine Intelligence,2003,25(9):1041-1050
知道了一些原因,并且可以尝试使用2D Gabor相位编码。这里暂时不做处理,我还不会。
下面使用其他算法来进行模型测试。
5.使用knn算法来进行分类识别
代码如下:
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
#加载数据代码(上面有)
#划分数据代码(上面有)
# 使用KNN算法进行训练和预测
knn = KNeighborsClassifier(n_neighbors=1) # 设置K值为1,可根据需求进行调整
knn.fit(X_train, y_train)
predictions = knn.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, predictions)
print("Accuracy:", accuracy)
加载数据和划分数据集的代码用之前的。
结果为:
Accuracy: 0.97
我们修改k值看看,这里因为训练集每个类最多只有4张图片,所以k最多设置为4,我们要用下面代码遍历看看结果:
def knn_test():
for n in range(1,5):
# 使用KNN算法进行训练和预测
knn = KNeighborsClassifier(n_neighbors=n)
knn.fit(X_train, y_train)
predictions = knn.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, predictions)
print("K值为:",n)
print("Accuracy:", accuracy)
print("\n")
knn_test()
结果为:
K值为: 1
Accuracy: 0.97
K值为: 2
Accuracy: 0.83
K值为: 3
Accuracy: 0.765
K值为: 4
Accuracy: 0.76
结果表示k为1时结果最高。
接下来我们对数据进行降维后再利用knn分类,并利用循环得出最佳维度(与之前降维代码类似):
#获取最佳维度和准确率,利用knn计算
def pca_best(X_train,X_test):
acc=[]#各维度准确率集合
nlist=[]#各维度集合
a=10
acc1=0
for n in range(10,300,10):#先到300维看看,如果波动比较大再加
# 对训练数据和测试数据进行PCA降维
X_train_pca, X_test_pca = pca_transform(X_train,X_test,n)
# 使用KNN算法进行训练和预测
knn = KNeighborsClassifier(n_neighbors=1) # 设置K值为1,可根据需求进行调整
knn.fit(X_train_pca, y_train)
predictions = knn.predict(X_test_pca)
# 计算准确率
accuracy = accuracy_score(y_test, predictions)
#print("Accuracy:", accuracy)
if accuracy==1:
return n,accuracy
acc.append(accuracy)
nlist.append(n)
#打印各维度对应的准确率,看看波动情况,如果准确率越来越平稳,则不用测试300维以后的维度,否之则不然
print("维度为:",n)
print("准确率为:",accuracy)
print("\n")
#获取最佳维度和准确率
for i in range(len(nlist)):
if acc1<acc[i]:
acc1=acc[i]
a=nlist[i]
return a,acc1
#前面已经划分好数据集
n,acc=pca_best(X_train,X_test)
print("最佳维度为:",n)
print("准确率为:",acc)
结果为:
最佳维度为: 20
准确率为: 0.975
下面我们对数据进行gabor滤波后再进行knn分类看看结果:
#建立gabor滤波器
def gabor_filter(img, frequency, theta):
kernel = cv2.getGaborKernel((21, 21), 5.0, theta, 10.0, 1.0, 0, ktype=cv2.CV_32F)
filtered_img = cv2.filter2D(img, cv2.CV_8UC3, kernel)
return filtered_img
#图像滤波
def extract_gabor_features(image):
#因为加载数据时已经进行过灰度转换了,所以下面一行注释掉
#gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_img=image
filtered_img = gabor_filter(gray_img, frequency=0.6, theta=1.0)
flattened_features = filtered_img.flatten()
return flattened_features
def gabor_image(x):#将加载的数据集进行滤波
x_gabor=[]
for i in x:
features = extract_gabor_features(i)
x_gabor.append(features)
return x_gabor
#滤波
x_gabor=gabor_image(X)
#划分数据集
X_train, X_test, y_train, y_test=data_split(x_gabor,y)
knn = KNeighborsClassifier(n_neighbors=1) # 设置K值为1,可根据需求进行调整
knn.fit(X_train, y_train)
predictions = knn.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, predictions)
print("准确率为:",accuracy)
结果为:
准确率为: 0.955