计算机视觉实验3,4——人脸识别

1. 读入数据

使用了att_faces数据集, 存储格式为/att_faces/s1/1.pgm, 因此需要写个读入函数读取主文件夹下所有文件夹下的所有文件:

os.walk(path) 遍历path路径返回信息:
  • root: path根路径
  • dirs: path下的所有文件夹, 不递归
  • files: path下的所有文件, 不递归
#%%
from cv2 import cv2
import matplotlib.pyplot as plt
import os
import numpy as np
import re
def readimgs(path):#读取所有文件
    imgs=[]
    labels=[]
    for root,dirnames,f, in os.walk(path):#取得所有文件夹
        for dir in dirnames:#遍历子文件夹
            path2=os.path.join(path,dir)
            for r,d,files, in os.walk(path2):#对文件夹取所有文件
                for onefile in files:#对每个文件添加到列表中
                    path3=os.path.join(path2,onefile)
                    img=cv2.imread(path3)
                    img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转灰度
                    imgs.append(img)#添加到图片集
                    labels.append(int(re.sub("\\D","",dir)))#文件夹名作为标签

    return imgs,labels

2. cv2.Eigenfaces训练

也可以换成Fisherface, 用法一样, 不过Eigen原理是PCA, Fisher原理是LDA

分割好训练集和测试集, att_faces数据中每个人有10张图片, 因此我每个人留了第一张作为测试集.

EigenFaceRecognizer_create(num_components = 0, threshold = DBL_MAX ):
  • num_components, 保留的主成分数
  • threshold, 预测时的阈值设置
  • 返回一个识别模型
model.train(src, labels):
  • src: 数据组, 具体到图像就是图像顺序容器, 例如vector, [img1,img2,....]
  • labels: 给定标签, 标签顺序不重要, 只要保证图像和标签对应即可. 顺序容器如Vector, 或者Mat (虽然我的list一定要转换为array才行...)
#%%主函数训练
if __name__ == "__main__":
    #读取全部文件
    imgs,labels=readimgs("./att_faces")
    #划分训练集 测试集
    testimgs=[]
    testlabels=[]
    trainimgs=[]
    trainlabels=[]
    for i in range(len(labels)):
        if(i%10==0):#每10张, 即每一组留一张作为测试集
            testimgs.append(imgs[i])
            testlabels.append(labels[i])
        else:
            trainimgs.append(imgs[i])
            trainlabels.append(labels[i])

    trainlabels=np.asarray(trainlabels)
    
    model = cv2.face.EigenFaceRecognizer_create()
    model.train(trainimgs,trainlabels)

3. Eigenfaces预测

预测就是对之前保留的测试集, 一一预测并且检验正确率.

model.predict(data): 模型对data进行预测, 返回output[2]
  • output[0], label, 即预测的标签.
  • output[1], confidence, 即置信度, 注意confidence是越高越不相似
#%% 验证
    count=0
    for i in range(0,len(testlabels)):
        test_img=testimgs[i]
        output=model.predict(test_img)#对测试集每个图片进行预测
        if(output[0]==testlabels[i]):#结果和真实标签比较
            count+=1
    
    print(count/len(testlabels))#输出成功率

输出效果如下: 准确率达到0.975


准确率

存在一个错误样例:


唯一一个错判样例, 左为原图, 右为预测标签所属图

你可能感兴趣的:(计算机视觉实验3,4——人脸识别)