第十节、人脸识别

人脸检测是OpenCV的一个很不错的功能,它是人脸识别的基础。什么是人脸识别?其实就是一个程序能够识别出给定图像或者视频中的人脸。实现这一目标的方法之一是用一系列分好类的图像(人脸数据库)来训练,并基于这些图像进行识别。

人脸识别所需要的人脸库可以通过两种方式来获得:自己获得图像或从人脸数据库免费获得可用的人脸图像,互联网上有许多人脸数据库,这里以ORL人脸库(包含40个人的每人10张人脸的共400张人脸)为例,ORL人脸库中每一张图像大小为92x112,我们要想对这些样本进行人脸识别,必须要在包含人脸的样本图像上进行人脸识别。除了要识别ORL人脸库,我们也还想要识别出自己,所以我们还需要准备自己的图像。

一 生成自己的人脸图像

我们通过摄像头采集自己的人脸,大约10张图像就可以,我们需要把图像调整为92x112的大小,并且保存到一个指定文件夹,文件名后缀为.pgm。代码如下:

#1、生成自己人脸识别数据
def generator(data):
    '''
    生成的图片满足以下条件
    1、图像是灰度格式,后缀为.pgm
    2、图像大小要一样
    
    params:
        data:指定生成的人脸数据的保存路径
    '''
    '''
    打开摄像头,读取帧,检测帧中的人脸,并剪切,缩放
    '''
    name = input('my name:')
    #如果路径存在则删除
    path = os.path.join(data,name)
    if os.path.isdir(path):
        #os.remove(path)   #删除文件
        #os.removedirs(path)   #删除空文件夹
        shutil.rmtree(path)    #递归删除文件夹
        
    #创建文件夹
    os.mkdir(path)
    
    #创建一个级联分类器 加载一个 .xml 分类器文件. 它既可以是Haar特征也可以是LBP特征的分类器.
    face_cascade = cv2.CascadeClassifier('./haarcascades/haarcascade_frontalface_default.xml')
    
    #打开摄像头    
    camera = cv2.VideoCapture(0)
    cv2.namedWindow('Dynamic')
    #计数
    count = 1
    
    while(True):
        #读取一帧图像
        ret,frame = camera.read()
        #判断图片读取成功?
        if ret:
            gray_img = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
            #人脸检测
            faces = face_cascade.detectMultiScale(gray_img,1.3,5)            
            for (x,y,w,h) in faces:
                #在原图像上绘制矩形
                cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
                #调整图像大小 和ORL人脸库图像一样大小
                f = cv2.resize(frame[y:y+h,x:x+w],(92,112))
                #保存人脸
                cv2.imwrite('%s/%s.pgm'%(path,str(count)),f)
                count += 1                
            cv2.imshow('Dynamic',frame)            
            #如果按下q键则退出
            if cv2.waitKey(100) & 0xff == ord('q') :
                break
    camera.release()
    cv2.destroyAllWindows()

程序运行后,我们需要输入自己的姓名,这里我输入zy,并在data路径下生成了一个zy文件夹,下面保存着采集到的图像:

二 人脸识别(OpenCV)

OpenCV 3有三种人脸识别的方法,它们分别基于不同的三种算法,Eigenfaces,Fisherfaces和Local Binary Pattern Histogram。

这些方法都有一个类似的过程,即都使用分好类的训练数据集来进行训练,对图像或视频中检测到的人脸进行分析,并从两方面来确定:是否识别到目标;目标真正被识别到的置信度的衡量,这也称为置信度评分,在实际应用中可以通过设置阈值来进行筛选。

这里我们主要来介绍一下利用特征脸进行人脸识别的方法,特征脸法,本质上其实就是PCA降维,这种算法的基本思路是,把二维的图像先灰度化,转化为一通道的图像,之后再把它首尾相接转化为一个列向量,假设图像大小是20*20的,那么这个向量就是400维,理论上讲组织成一个向量,就可以应用任何机器学习算法了,但是维度太高算法复杂度也会随之升高,所以需要使用PCA算法降维,然后使用简单排序或者KNN都可以。

1、准备数据

我们先来准备训练所需要的数据,这里我们需要的数据有训练的图像,每个图像对应的标签以及标签对应的真实姓名。

#2、读取ORL人脸数据库 准备训练数据
def LoadImages(data):
    '''
    加载数据集
    params:
        data:训练集数据所在的目录,要求数据尺寸大小一样        
    ret:
        images:[m,height,width]  m为样本数,height为高,width为宽
        names:名字的集合
        labels:标签
    '''
    images = []
    labels = []
    names = []
    
    label = 0
    #过滤所有的文件夹
    for subDirname in os.listdir(data):
        subjectPath = os.path.join(data,subDirname)
        if os.path.isdir(subjectPath):                
            #每一个文件夹下存放着一个人的照片    
            names.append(subDirname)
            for fileName in os.listdir(subjectPath):
                imgPath = os.path.join(subjectPath,fileName)
                img = cv2.imread(imgPath,cv2.IMREAD_GRAYSCALE)
                images.append(img)
                labels.append(label)
            label += 1
    images = np.asarray(images)
    labels = np.asarray(labels)
    return images,labels,names

2、人脸识别

有了训练数据之后,我们就可以直接调用OpenCV 3的人脸识别库进行训练,训练好之后,就可以进行识别:

def FaceRec(data):    
    #加载训练数据
    X,y,names=LoadImages('./face')
    
    model = cv2.face.EigenFaceRecognizer_create()
    model.train(X,y)
    
    #创建一个级联分类器 加载一个 .xml 分类器文件. 它既可以是Haar特征也可以是LBP特征的分类器.
    face_cascade = cv2.CascadeClassifier('./haarcascades/haarcascade_frontalface_default.xml')
    
    #打开摄像头    
    camera = cv2.VideoCapture(0)
    cv2.namedWindow('Dynamic')
    
    while(True):
        #读取一帧图像
        ret,frame = camera.read()
        #判断图片读取成功?
        if ret:
            gray_img = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
            #人脸检测
            
            faces = face_cascade.detectMultiScale(gray_img,1.3,5)            
            for (x,y,w,h) in faces:
                #在原图像上绘制矩形
                frame = cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
                roi_gray = gray_img[y:y+h,x:x+w]
                
                try:
                    #宽92 高112
                    roi_gray = cv2.resize(roi_gray,(92,112),interpolation=cv2.INTER_LINEAR)
                    params = model.predict(roi_gray)
                    print('Label:%s,confidence:%.2f'%(params[0],params[1]))
                    cv2.putText(frame,names[params[0]],(x,y-20),cv2.FONT_HERSHEY_SIMPLEX,1,255,2)
                except:
                    continue

            cv2.imshow('Dynamic',frame)            
            #如果按下q键则退出
            if cv2.waitKey(100) & 0xff == ord('q') :
                break
    camera.release()
    cv2.destroyAllWindows()

这里我们cv2.face.EigenFaceRecognizer_create()创建人脸识别模型,通过图像数组和对应标签数组来训练模型,EigenFaceRecognizer_create()函数有两个可以设置的重要参数:第一个是想要保留的主成分数目,第二个是指定的置信度阈值,这是一个浮点数。

接下来,重复与人脸检测操作类似的过程。通过在检测到的人脸上进行人脸识别,注意这里有两个步骤:

1、将检测到人脸调整为指定的大小92x112;

2、调用prdict()函数进行预测;

三 自己实现特征脸

参考文献

Python计算特征值与特征向量案例

人脸识别经典算法实现(一)——特征脸法

机器学习: 特征脸算法 EigenFaces

猜你喜欢

转载自www.cnblogs.com/zyly/p/9498857.html
今日推荐