首页-达尔闻    全部    项目分享| 七步完成树莓派实时人脸识别

项目分享| 七步完成树莓派实时人脸识别

树莓派识别人脸项目再添一个,本次项目主要展示一步一步使用树莓派原装摄像头PiCam来实现实时人脸识别。虽然有详细的步骤,但你是新手零基础的话,建议补充人脸识别,以及树莓派使用的基础知识之后,再来尝试这个项目。
收藏
  • 树莓派识别人脸项目再添一个,本次项目主要展示一步一步使用树莓派原装摄像头PiCam来实现实时人脸识别。虽然有详细的步骤,但你是新手零基础的话,建议补充人脸识别,以及树莓派使用的基础知识之后,再来尝试这个项目。

    项目中使用到的软硬件

    硬件部分:Raspberry Pi 3 Model B,Raspberry Pi 3 Camera Module

    软件部分:OPENCV,Python3

     

    有很多树莓派的项目是使用的开源OpenCV,这里将用树莓派和python进行协同。代码编写有三个步骤:

    步骤1:采集人脸数据和人脸检测

    步骤2:训练人脸识别模型

    步骤3:人脸识别推理

    初步:配置软件环境:

    在Raspberry Pi上安装OpenCV 3 + Python,这里不是重点,安装方法网上一大堆,自行搜索安装。

    第二步:调用相机

    如果已经RPi中安装了OpenCV,接下来就测试一下确认相机是否工作正常。在IDE上输入以下Python代码:

    这段代码可以调用PiCam ,捕获视频流,并且通过黑白模式和RGB模式显示出来。按下Esc键即可退出程序。

    第三步:人脸检测

    人脸识别中的最基本任务是实现人脸检测,要先在一张图片中捕获到人脸,再去识别图片中的人脸和数据库中人脸数据进行比较。

    人脸检测的最常见方法是使用“ Haar分类器” 。。基于Haar功能的级联分类器的对象检测是Paul Viola和Michael Jones提出的一种有效的对象检测,基于机器学习的方法。

    进行人脸检测工作该算法需要大量的正图像(有人脸图像)和负图像(无人脸的图像)来训练分类器,然后从中提取特征。OpenCV可以进行人脸的训练和推理。如果想训练这些XML文件可以从 haarcascades 目录下载。

    代码如下,或者你可以访问下载代码

    https://github.com/Mjrovai/OpenCV-Face-Recognition/blob/master/FaceDetection/faceDetection.py 

    import numpy as np
    import cv2
    faceCascade = cv2.CascadeClassifier('Cascades/haarcascade_frontalface_default.xml')
    cap = cv2.VideoCapture(0)
    cap.set(3,640) # set Width
    cap.set(4,480) # set Height
    while True:
        ret, img = cap.read()
        img = cv2.flip(img, -1)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = faceCascade.detectMultiScale(
            gray,
                scaleFactor=1.2,
            minNeighbors=5,
                minSize=(20, 20)
        )
        for (x,y,w,h) in faces: 
           cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
            roi_gray = gray[y:y+h, x:x+w]
            roi_color = img[y:y+h, x:x+w]
         cv2.imshow('video',img)
        k = cv2.waitKey(30) & 0xff
        if k == 27: # press 'ESC' to quit
            break
    cap.release()
    cv2.destroyAllWindows()

     

    其中代码的这一部分是调用我们的分类器功能的:

    faces = faceCascade.detectMultiScale(
            gray,
                scaleFactor=1.2,
            minNeighbors=5,
                minSize=(20, 20)
        )

     

    代码这一部分用作“标记”图像中的面孔,

    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
        roi_gray = gray[y:y+h, x:x+w]
        roi_color = img[y:y+h, x:x+w]

     

    如果发现人脸,它会返回检测到的面部位置,作为左上角(x,y)的矩形,则将“ w”作为宽度,将“ h”作为高度= =(x,y,w,h) 。如下图:

    如果可以实现以上功能,人脸检测功能基本实现,可以使用Rpi运行python代码。效果是这样的:

    第四步:采集人脸数据

    让我们开始项目代码的第一阶段。我们在这要存储每个ID的一组照片被后续进行人脸识别。

    首先创建一个开发项目:FacialRecognitionProject,创建一个数据集数据集,存储我们的面部标本数据集。并且存储上述的调用PiCam代码和人脸检测代码。

    import cv2
    import os
    cam = cv2.VideoCapture(0)
    cam.set(3, 640) # set video width
    cam.set(4, 480) # set video height
    face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')# For each person, enter one numeric face id
    face_id = input('\n enter user id end press <return> ==>  ')
    print("\n [INFO] Initializing face capture. Look the camera and wait ...")# Initialize individual sampling face count
    count = 0
    while(True):   
    ret, img = cam.read()   
    img = cv2.flip(img, -1) # flip video image vertically   
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)   
    faces = face_detector.detectMultiScale(gray, 1.3, 5)   
    for (x,y,w,h) in faces:
            cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)
                count += 1
            # Save the captured image into the datasets folder
            cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w])
            cv2.imshow('image', img)
        k = cv2.waitKey(100) & 0xff # Press 'ESC' for exiting video
        if k == 27:
            break
        elif count >= 30: # Take 30 face sample and stop video
             break
    # Do a bit of cleanup
    print("\n [INFO] Exiting Program and cleanup stuff")
    cam.release()
    cv2.destroyAllWindows()

    对于每个捕获的帧,我们都把他保存在“数据集”目录上的文件。注意一下,要保存上述文件,必须导入库“ os”。每个文件的名称格式:

    cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w])
    User.face_id.count.jpg

    就像这样:

    第五步:模型训练

    现在要把之前存储的各个id号的图片提取特征,然后用于训练识别器。最后识别器上会生成一个yml文件。 首先在终端下载PIL库,函数getImagesAndLabels(路径)恢复我们刚刚的数据集上收集到ID号和对应的人脸特征。 具体代码如下:

    import cv2
    import numpy as np
    from PIL import Image
    import os
    # Path for face image database
    path = 'dataset'
    recognizer = cv2.face.LBPHFaceRecognizer_create()
    detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml");
    # function to get the images and label data
    def getImagesAndLabels(path):
        imagePaths = [os.path.join(path,f) for f in os.listdir(path)]
            faceSamples=[]
        ids = []
        for imagePath in imagePaths:
            PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale
            img_numpy = np.array(PIL_img,'uint8')
            id = int(os.path.split(imagePath)[-1].split(".")[1])
            faces = detector.detectMultiScale(img_numpy)
            for (x,y,w,h) in faces:
                faceSamples.append(img_numpy[y:y+h,x:x+w])
                ids.append(id)
        return faceSamples,ids
    print ("\n [INFO] Training faces. It will take a few seconds. Wait ...")
    faces,ids = getImagesAndLabels(path)
    recognizer.train(faces, np.array(ids))
    # Save the model into trainer/trainer.yml
    recognizer.write('trainer/trainer.yml') # recognizer.save() worked on Mac, but not on Pi
    # Print the numer of faces trained and end program
    print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))

    第六步:人脸识别

    人脸识别器已经实现,现在要在相机上捕获人脸。如果此人之前拍摄并训练过他的脸,识别器将做出预测,返回ID名和索引。

    使用刚刚训练的识别器模型(加载trainer.yml),在这里使用了新的阵列,用姓名代替之前的标签,然后就和刚刚“人脸分类器”的步骤一样去进行人脸识别,并识别。预测将返回每张图片识别后的匹配率。 具体代码可以在“达尔闻说”微信回复:树莓派人脸识别,下载。

    第七步:结果

    最后,我们由PiCam采集图像,由识别器判断是否是我们数据集的人脸,在图像中显示该人名以及匹配指数,如果PiCam的图像不是我们数据库中的图像,无法进行识别的话,我们将显示未知。具体代码可以在“达尔闻说”微信回复:树莓派人脸识别,下载。 效果如下: