零基础用一百行代码完成动态的人脸识别(opencv+python)

废话:(其实是介绍了一下该文章的大概来路)     

电子化的时代到处都能看到人脸识别的用途;比如:刷脸门禁,火车站检票口,又比如检查站,还有一些比较高端的汽车还支持刷脸开门等等。

     近期呢接了个学校的一个项目有关于刷脸门禁的,我在CSDN上找了很多,确实有很多相关的博客参考但是怎么说呢总觉得还是差点意思。。。所以我自己写了一个,感兴趣的朋友拿来参考参考,还有个人能力有限如果文章有什么不足可以在评论区跟我留言我看到了会及时更改的。

废话不多说直接开始。

正文:

1.介绍:

        本文中人脸识别的讲解分一下五个步骤去讲解:

第一步:人脸的采集

第二步:加载数据,返回目标值

第三步:加载算法

第四步:进行算法的训练,找到数据和目标之间的规律

第五步:动态加载数据

2.开始写各个函数:

2.1  人脸的采集

      主要实现步骤是:先从摄像头捕获人脸,对获取到的人脸进行分类。把获取到的人脸转成灰度图片每一个人脸进行10张抓拍,并裁剪成64*64的大小(主要目的就是提高算法的速度,提升人脸识别的准确率);把图片写入到指定文件目录中,抓拍张数大于10时退出本次录入。

     开始录入人脸之前先对每一个人脸创建新的文件夹进行获取到的人脸的保存。take_faces函数就是用来创建文件夹和命名人脸数据文件的。

    下面就是代码啦:

#从摄像头获取人脸并且进行分类
def take_phone(path): #获取摄像头数据,调用分类器进行人脸的分类和采集
    cap=cv2.VideoCapture(0)
    face_detector=cv2.CascadeClassifier('E:/wodexiangmu/opencv2/sistinemaster/haarcascade_frontalface_default.xml')#这儿我使用的是绝对路径,这个是一个人脸分类器。分类这一块静态进行分类
    filename=1#计数器,就是抓拍拍到第几张了,进行计数
    flag_write=False #写入状态的flag
    while True:
        flag, frame=cap.read()
        if not flag:
            break
        gray=cv2.cvtColor(frame,code=cv2.COLOR_BGR2GRAY)  #进行灰度处理
        faces=face_detector.detectMultiScale(gray,minNeighbors=10)
        for x,y,w,h in faces:
            if flag_write:
                face=gray[y:y+h,x:x+w]
                face=cv2.resize(face,dsize=(64,64))  #进行裁剪
                cv2.imwrite('./faces_dynamic/%s/%d.jpg'%(path,filename),face) #进行写入
                filename+=1
            cv2.rectangle(frame,pt1=(x,y),pt2=(x+w,y+h),color=[0,255,0],thickness=2)#框出人脸
        if filename>10:  #抓拍张数的判断
            break
        cv2.imshow('face',frame)  #显示
        key=cv2.waitKey(1000//24)
        if key==ord('q'):  
            break
        if key==ord('w'):  #点击w开始进行录入
            flag_write=True
    cv2.destroyAllWindows()  
    cap.release()

#通过分类的人脸进行命名和保存
def take_faces():#创建采集人脸数据的文件夹,调用上面写的采集函数可称为是采集函数
    while True:
        key = input('请输入文件夹的名字(拼音的缩写,如果输入Q,程序退出!:)')
        if key == 'Q':
            break
        # 在faces_dynamic下面创建子文件夹
        os.makedirs('./faces_dynamic/%s' % (key), exist_ok=True)
        take_phone(key)

 2.2加载数据,返回目标值

      主要步骤是先获取到我们第一步采集的人脸,按照人脸的名字,人脸 的关键点并且标签进行归类。对图片进行均衡化处理,为了就是图片颜色鲜明,方便分类;把人脸和标签进行数据化(计算机识别的数字,把获取到那些信息转成一堆数组和无序的数字来表达),最后把这些数据返回出来就行。

    代码放这儿啦:

#load——data是获取人脸数据并且灰度化得到模型的脸部关键点信息,标签,姓名
def load_data():
    listdir = os.listdir('./faces_dynamic')#此处为获取模型中的人脸数据
    names = [d for d in listdir if not d.startswith('.')]
    faces = []#保存人脸的关键点信息
    target=[i for i in range(len(names))]*10 #保存标签
    for dir in names:
        for i in range(1, 11):#加载图片
            gray = cv2.imread('./faces_dynamic/%s/%d.jpg' % (dir, i))  # 三维图片;灰度化
            gray_ = gray[:, :, 0]  # 二维数组
            gray_=cv2.equalizeHist(gray_)#图片的均衡化处理,颜色鲜明
            faces.append(gray_)#添加二维的人脸数据

    faces = np.asarray(faces) #转换成数字
    target=np.asarray(target) #转换成数字
    target.sort()#标签的打散
    return faces,target,names #返回人脸数据,标签,姓名

2.3算法的加载

目前流行的人脸识别算法为一些三种:

                                                             ①EigenFaceRecognizer_create()                                                                                                     ②FisherFaceRecognizer_create()

                                                             ③LBPHFaceRecognizer_create()

通过实测发现:LBPH算法的准确率比其他三种算法高很多,所以本文选用LBPH算法作为人脸识别算法。下面供大家参考了,大家可以自行选择。

    #face_recognizer=cv2.face.EigenFaceRecognizer_create()#置信度很大,准确率较低
    #face_recognizer = cv2.face.FisherFaceRecognizer_create()#置信度较低,准确率还行
    face_recognizer = cv2.face.LBPHFaceRecognizer_create()#置信度很低,准确率最高可选用

2.4算法训练,找到数据与检测到的目标之间的规律

        用train方法进行匹配和关联

2.5动态加载数据

   主要步骤是:先调用摄像头获取人脸,调用分类器进行人脸关键点来进行分类。灰度化并对获取人脸进行裁剪,对人脸进行判断。在终端里打印出此人是谁,置信度为多少。在动态画面中框出人脸,显示名字标签。

def dynamic_recognizer_face(face_recognizer,names):#人脸识别函数
    cap=cv2.VideoCapture(0)
    #人脸检测
    face_detector=cv2.CascadeClassifier('E:/wodexiangmu/opencv2/sistinemaster/haarcascade_frontalface_default.xml')
    while True:
        flag,frame=cap.read()
        if not flag:
            break
        gray=cv2.cvtColor(frame,code=cv2.COLOR_BGR2GRAY)
        faces=face_detector.detectMultiScale(gray,minNeighbors=10)
        for x,y,w,h in faces:
            face=gray[y:y+h,x:x+w]
            face=cv2.resize(face,dsize=(64,64))
            face=cv2.equalizeHist(face)#动态采集的数据进行均衡化处理
            y_,confidence=face_recognizer.predict(face)#人脸辨识
            label=names[y_]
            print('这个人是:%s;置信度为:%0.1f'%(label,confidence))
            cv2.rectangle(frame,pt1=(x,y),pt2=(x+w,y+h),color=[0,255,0],thickness=2)
            cv2.putText(frame,text=label,org=(x,y-10),
                        fontFace=cv2.FONT_HERSHEY_SCRIPT_COMPLEX,
                        fontScale=1.5,
                        color=[0,0,255],thickness=2)
        cv2.imshow('face',frame)
        key=cv2.waitKey(1000//24)
        if key==ord('q'):
            break
    cv2.destroyAllWindows()
    cap.release()

3.放个源码和演示视频

3.1源码

注意事项:   

     1.复制,剪贴使用源码时注意替换:分类器的绝对路径。换成自己的路径即可(相对和绝对路径的选择因人而异)

     2.先屏蔽5,开启1;进行人脸的采集,采集成功后屏蔽1.开启5进行人脸的识别。

     3.如果会用Qt的大佬可以用Qt来进行本项目的完善。(完善了记得在评论去喊我,我会给你点赞收藏的哟)

import cv2
import os
import  numpy as np
#load——data是获取人脸数据并且灰度化得到模型的脸部关键点信息,标签,姓名
def load_data():
    listdir = os.listdir('./faces_dynamic')#此处为获取模型中的人脸数据
    names = [d for d in listdir if not d.startswith('.')]
    faces = []#保存人脸的关键点信息
    target=[i for i in range(len(names))]*10 #保存标签
    for dir in names:
        for i in range(1, 11):#加载图片
            gray = cv2.imread('./faces_dynamic/%s/%d.jpg' % (dir, i))  # 三维图片;灰度化
            gray_ = gray[:, :, 0]  # 二维数组
            gray_=cv2.equalizeHist(gray_)#图片的均衡化处理,颜色鲜明
            faces.append(gray_)#添加二维的人脸数据

    faces = np.asarray(faces) #转换成数字
    target=np.asarray(target) #转换成数字
    target.sort()#标签的打散
    return faces,target,names #返回人脸数据,标签,姓名
def take_phone(path): #获取摄像头数据,调用分类器进行人脸的分类和采集
    cap=cv2.VideoCapture(0)
    face_detector=cv2.CascadeClassifier('E:/wodexiangmu/opencv2/sistinemaster/haarcascade_frontalface_default.xml')
    filename=1
    flag_write=False
    while True:
        flag, frame=cap.read()
        if not flag:
            break
        gray=cv2.cvtColor(frame,code=cv2.COLOR_BGR2GRAY)
        faces=face_detector.detectMultiScale(gray,minNeighbors=10)
        for x,y,w,h in faces:
            if flag_write:
                face=gray[y:y+h,x:x+w]
                face=cv2.resize(face,dsize=(64,64))
                cv2.imwrite('./faces_dynamic/%s/%d.jpg'%(path,filename),face)
                filename+=1
            cv2.rectangle(frame,pt1=(x,y),pt2=(x+w,y+h),color=[0,255,0],thickness=2)
        if filename>10:
            break
        cv2.imshow('face',frame)
        key=cv2.waitKey(1000//24)
        if key==ord('q'):
            break
        if key==ord('w'):
            flag_write=True
    cv2.destroyAllWindows()
    cap.release()
def take_faces():#创建采集人脸数据的文件夹,调用上面写的采集函数可称为是采集函数
    while True:
        key = input('请输入文件夹的名字(拼音的缩写,如果输入Q,程序退出!:)')
        if key == 'Q':
            break
        # 在faces_dynamic下面创建子文件夹
        os.makedirs('./faces_dynamic/%s' % (key), exist_ok=True)
        take_phone(key)
def dynamic_recognizer_face(face_recognizer,names):#人脸识别函数
    cap=cv2.VideoCapture(0)
    #人脸检测
    face_detector=cv2.CascadeClassifier('E:/wodexiangmu/opencv2/sistinemaster/haarcascade_frontalface_default.xml')
    while True:
        flag,frame=cap.read()
        if not flag:
            break
        gray=cv2.cvtColor(frame,code=cv2.COLOR_BGR2GRAY)
        faces=face_detector.detectMultiScale(gray,minNeighbors=10)
        for x,y,w,h in faces:
            face=gray[y:y+h,x:x+w]
            face=cv2.resize(face,dsize=(64,64))
            face=cv2.equalizeHist(face)#动态采集的数据进行均衡化处理
            y_,confidence=face_recognizer.predict(face)#人脸辨识
            label=names[y_]
            print('这个人是:%s;置信度为:%0.1f'%(label,confidence))
            cv2.rectangle(frame,pt1=(x,y),pt2=(x+w,y+h),color=[0,255,0],thickness=2)
            cv2.putText(frame,text=label,org=(x,y-10),
                        fontFace=cv2.FONT_HERSHEY_SCRIPT_COMPLEX,
                        fontScale=1.5,
                        color=[0,0,255],thickness=2)
        cv2.imshow('face',frame)
        key=cv2.waitKey(1000//24)
        if key==ord('q'):
            break
    cv2.destroyAllWindows()
    cap.release()
if __name__ == '__main__':
    #1.动态的采集人脸
    #take_faces()
    #2.加载数据,返回目标值
    faces,target,names=load_data()
    #3.加载算法
    #face_recognizer=cv2.face.EigenFaceRecognizer_create()#置信度很大,准确率较低
    #face_recognizer = cv2.face.FisherFaceRecognizer_create()#置信度较低,准确率还行
    face_recognizer = cv2.face.LBPHFaceRecognizer_create()#置信度很低,准确率最高可选用
    #4.进行算法训练,找到数据和目标之间的规律
    face_recognizer.train(faces,target)
    #5.动态加载数据
    dynamic_recognizer_face(face_recognizer,names)

3.2视频演示

在我主页的视频那一栏我放了演示视频大家可以去看看(主要是这儿不能直接插入视频)。。。

 

最后:

最后希望能帮到大家,如果有什么问题可以私信,也可以留言,看到了就会回复和及时改进的。

                                          下个项目再见。。。

 

 

 

           

 

 

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2023年6月6日
下一篇 2023年6月6日

相关推荐