python实现多人脸识别

本篇文章是使用python通过调用电脑摄像头实时检测摄像头画面识别画面中的人脸

这里的python版本是3.9,各个版本思路上相似

我的大体思路是:采集人脸数据—->训练模型—->实现人脸识别

第一步:采集人脸数据

首先要导入cv库

import cv2

如果没有opencv库的话要用pip先安装一个

pip install opencv-python

采集人脸要用到调用摄像头

capture = cv2.VideoCapture(1)

在这里需要说明的是代码后面括号里的数字1代表着调用外接的摄像头,0是调用电脑的摄像头

调用完结束就开始读取画面了

success, frame = capture.read()
success用来判断摄像头是否调用成功,frame代表捕捉的每一帧图像

读取完之后要转换为灰度图像

转换灰度图像有个好处就是提高图像的准确度,说到灰度就想起来华为之前的一部手机—华为P9,双摄设计,其中一个就是黑白镜头,因为这颗黑白镜头而大大提高了成像质量

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

在这里需要调用一个叫分类器的东西,这个文件我是从官网上下载的

网址:Home – OpenCV

python实现多人脸识别

然后点击library—->release

python实现多人脸识别

我下载的版本号是4.5.5,仅供参考

下载解压,解压之后进入opencv文件夹,找到这个路径:opencv\sources\data\haarcascades

python实现多人脸识别

然后导入分类器

face_detect = cv2.CascadeClassifier('填xml文件路径,例opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml')
路径要具体到文件然后再跟上文件的名字

face = face_detect.detectMultiScale(gray, 1.01, 5, 0, (100, 100), (300, 300))
框定人脸区域

然后用for循环实时刷新,注意缩进

for x, y, w, h in face:
    # x,y指横纵坐标,左上角开始,h为高,w为宽
    cv2.rectangle(frame, (x, y), (x + w, y + h), color=(0, 0, 225), thickness=2)

然后开启摄像头窗口

开启窗口
cv2.imshow('result', frame)

后面再用waitkey保持画面的连续

c = cv2.waitKey(1)

加一个if判断,用来保存捕捉的图片和退出程序

if ord('k') == cv2.waitKey(1):
    cv2.imwrite('D:/testPhoto/lq/' + str(num) + '.jpg',frame)
    print(str(num),'保存成功')
    num += 1
if ord('q') == cv2.waitKey(1):  # 按下q退出
    break

最后整个文件的代码是这样的:

import cv2

num = 1
capture = cv2.VideoCapture(0)  # 0为电脑内置摄像头  使用电脑摄像头时为0,使用外接摄像头时为1
while (True):
    # 摄像头读取,success为是否成功打开摄像头,true,false。 frame为视频的每一帧图像
    success, frame = capture.read()
    # frame = cv2.flip(frame, 1)  # 摄像头是和人对立的,将图像左右调换回来正常显示。
    # 将采集到的图像转换为灰度图像,提高识别度
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 导入分类器
    face_detect = cv2.CascadeClassifier('D:/code/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml')
    face = face_detect.detectMultiScale(gray, 1.01, 5, 0, (100, 100), (300, 300))
    # 框入人脸,for循环用来实时刷新
    for x, y, w, h in face:
        # x,y指横纵坐标,左上角开始,h为高,w为宽
        cv2.rectangle(frame, (x, y), (x + w, y + h), color=(0, 0, 225), thickness=2)
    # 开启窗口
    cv2.imshow('result', frame)
    # 用waitKey保持画面连续
    c = cv2.waitKey(1)
    if ord('k') == cv2.waitKey(1):
        cv2.imwrite('D:/testPhoto/lq/' + str(num) + '.jpg',frame)
        print(str(num),'保存成功')
        num += 1
    if ord('q') == cv2.waitKey(1):  # 按下q退出
        break

cv2.destroyAllWindows()

while循环是用来保持摄像头画面的,num的作用是用来记录照片保存了多少张

第二步:训练模型

这里需要用到pillow库,需要用到pip下载

pillow简单来说就是可以为python提供图像处理功能

pip install pillow

首先需要用到一行代码,他的功能就是连接目录与文件名或目录,生成一个列表,列举文件夹下所有的文件

ImagePaths = [os.path.join(path, f) for f in os.listdir(path)]

建立一个存放数据的集合

facesSamples = []
ids = []

然后再一次调用分类器

face_detector = cv2.CascadeClassifier()
括号内跟分类器路径

然后用for循环遍历所有的图片并且进一步处理图片

    for ImagePath in ImagePaths:
        # 将图片转换为灰度图片
        img = Image.open(ImagePath).convert('L')
        # 将图像转换为数组
        img_numpy = np.array(img, 'uint8')
        # 为了获取id,将图片和路径分裂并获取
        faces = face_detector.detectMultiScale(img_numpy)
        id = 1
        # 将获取的图片和id添加到list中
        for x, y, w, h in faces:
            ids.append(id)
            facesSamples.append(img_numpy[y:y + h, x:x + w])

    print('id:', id)
    print('fs:', facesSamples)
    return facesSamples, ids

在末尾部分设置了图片路径和yml文件保存的地址等信息

    # 图片路径
    path = 'D:/testPhoto/sjs/'
    # 获取图像数组和id标签数组
    faces, ids = get_image_lable(path)
    # 加载识别器
    recognizer = cv2.face.LBPHFaceRecognizer_create()
    # 训练模型
    recognizer.train(faces, np.array(ids))
    # 保存模型
    recognizer.write('D:/testPhoto/sjs/train.yml')

训练模型这部分整体的代码是这样子的

import cv2
import os
from PIL import Image
import numpy as np

def get_image_lable(path):

    ImagePaths = [os.path.join(path, f) for f in os.listdir(path)]
    # 新建集合存放数据
    facesSamples = []
    ids = []
    # 调用分类器
    face_detector = cv2.CascadeClassifier('D:/code/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml')

    for ImagePath in ImagePaths:
        # 将图片转换为灰度图片
        img = Image.open(ImagePath).convert('L')
        # 将图像转换为数组
        img_numpy = np.array(img, 'uint8')
        # 为了获取id,将图片和路径分裂并获取
        faces = face_detector.detectMultiScale(img_numpy)
        id = 1
        # 将获取的图片和id添加到list中
        for x, y, w, h in faces:
            ids.append(id)
            facesSamples.append(img_numpy[y:y + h, x:x + w])
    print('id:', id)
    print('fs:', facesSamples)
    return facesSamples, ids

if __name__ == '__main__':
    # 图片路径
    path = 'D:/testPhoto/sjs/'
    # 获取图像数组和id标签数组
    faces, ids = get_image_lable(path)
    # 加载识别器
    recognizer = cv2.face.LBPHFaceRecognizer_create()
    # 训练模型
    recognizer.train(faces, np.array(ids))
    # 保存模型
    recognizer.write('D:/testPhoto/sjs/train.yml')

cv2.destroyAllWindows()

第三步:实时识别

这里识别人脸采用的算法是LBPH

recognizer_sjs = cv2.face.LBPHFaceRecognizer_create()
recognizer_jhs = cv2.face.LBPHFaceRecognizer_create()
recognizer_sjs这个是我自己起的名字,可以根据个人喜好更换

将之前训练好的模型导入

recognizer_sjs.read('D:/train.yml/')

具体的路径因人而异

到这一步,再次调用分类器

cascade_path = "D:/code/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml"
face_cascade = cv2.CascadeClassifier(cascade_path)

设置好名字,可能是我的原因,在我的电脑上没办法用中文的字体标注出来,所以建议还是用英文的字体

idum_sjs = 0
idum_jhs = 1
names = ['fxxtsjs','jhs']

这里的idum后面设定的数字和下面的name是对应的,比如说我这个设定的idum_sjs名字就是fxxtsjs,往下顺延即可

加载标注名字所用的字体,我选择的是opencv自带的

font = cv2.FONT_HERSHEY_SIMPLEX

然后就可以打开摄像头了

cam = cv2.VideoCapture(0)
minW = 0.1 * cam.get(3)
minH = 0.1 * cam.get(4)

下面需要添加一个while循环,用来确保摄像头画面连续不间断

while True:
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 识别人脸
    faces = face_cascade.detectMultiScale(
        gray,
        scaleFactor=1.2,
        minNeighbors=5,
        minSize=(int(minW), int(minH))
    )

紧接着添加一个for循环,让识别的框一直出现在画面上

for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
    idnum_sjs, confidence_sjs = recognizer_sjs.predict(gray[y:y + h, x:x + w])
    idnum_jhs, confidence_jhs = recognizer_jhs.predict(gray[y:y + h, x:x + w])

然后开始计算识别结果

if confidence_sjs < 50:
    idnum_sjs = names[idum_sjs]
    cv2.putText(img, str(idnum_sjs), (x + 5, y - 5), font, 1, (0, 0, 255), 1)
elif confidence_jhs < 50:
    idnum_jhs = names[idum_jhs]
    cv2.putText(img, str(idnum_jhs), (x + 5, y - 5), font, 1, (0, 0, 255), 1)
else:
    idnum = 'unknown'

最后展现画面

cv2.imshow('camera', img)

实时识别的整体代码如下

-----&#x68C0;&#x6D4B;&#x3001;&#x6821;&#x9A8C;&#x5E76;&#x8F93;&#x51FA;&#x7ED3;&#x679C;-----
import cv2

&#x51C6;&#x5907;&#x8BC6;&#x522B;&#x65B9;&#x6CD5;
recognizer_sjs = cv2.face.LBPHFaceRecognizer_create()
recognizer_jhs = cv2.face.LBPHFaceRecognizer_create()
&#x5F15;&#x7528;&#x4E4B;&#x524D;&#x7684;&#x6A21;&#x578B;
recognizer_sjs.read('D:/testPhoto/sjs/train.yml/')
recognizer_jhs.read('D:/testPhoto/jhs/train.yml/')
&#x8C03;&#x7528;&#x4EBA;&#x8138;&#x5206;&#x7C7B;&#x5668;
cascade_path = "D:/code/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml"
face_cascade = cv2.CascadeClassifier(cascade_path)
&#x52A0;&#x8F7D;&#x4E00;&#x4E2A;&#x5B57;&#x4F53;&#xFF0C;&#x4EE5;&#x4FBF;&#x6807;&#x6CE8;
font = cv2.FONT_HERSHEY_SIMPLEX
&#x8BBE;&#x7F6E;ID&#x4E0E;&#x6807;&#x6CE8;&#x7684;name
idum_sjs = 0
idum_jhs = 1
names = ['fxxtsjs','jhs']

&#x8C03;&#x7528;&#x6444;&#x50CF;&#x5934;
cam = cv2.VideoCapture(0)
minW = 0.1 * cam.get(3)
minH = 0.1 * cam.get(4)

while True:
    ret, img = cam.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # &#x8BC6;&#x522B;&#x4EBA;&#x8138;
    faces = face_cascade.detectMultiScale(
        gray,
        scaleFactor=1.2,
        minNeighbors=5,
        minSize=(int(minW), int(minH))
    )
    # &#x8FDB;&#x884C;&#x6821;&#x9A8C;
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
        idnum_sjs, confidence_sjs = recognizer_sjs.predict(gray[y:y + h, x:x + w])
        idnum_jhs, confidence_jhs = recognizer_jhs.predict(gray[y:y + h, x:x + w])
        # &#x8BA1;&#x7B97;&#x51FA;&#x4E00;&#x4E2A;&#x68C0;&#x9A8C;&#x7ED3;&#x679C;
        if confidence_sjs < 50:
            idnum_sjs = names[idum_sjs]
            # &#x6CE8;&#x4E0A;&#x59D3;&#x540D;
            cv2.putText(img, str(idnum_sjs), (x + 5, y - 5), font, 1, (0, 0, 255), 1)
        elif confidence_jhs < 50:
            idnum_jhs = names[idum_jhs]
            # &#x6CE8;&#x4E0A;&#x59D3;&#x540D;
            cv2.putText(img, str(idnum_jhs), (x + 5, y - 5), font, 1, (0, 0, 255), 1)
        else:
            idnum = 'unknown'

        # &#x5C55;&#x793A;&#x7ED3;&#x679C;
        cv2.imshow('camera', img)
        k = cv2.waitKey(20)
        if k == 27:
            break
        elif ord('q') == cv2.waitKey(1):  # &#x6309;&#x4E0B;q&#x9000;&#x51FA;
            break

&#x91CA;&#x653E;&#x8D44;&#x6E90;
cam.release()
cv2.destroyAllWindows()

python实现多人脸识别

最后提几点注意的地方:

1.人脸识别是我自己第一次做,所以上面的这些代码还有些不完美的地方,欢迎大家在评论区留言 并提出宝贵的意见,我会认真阅读并采纳

2.这段代码可以实现录入多个人脸,并且可以同时实时识别,添加其他人脸的时候需要注意路径的 正确与否,第三部添加多个人脸的地方就是在几乎每个出现sjs和jhs的地方,第三步添加人脸需 要改动的好像有准备识别方法中的recognize,下面的id名字,name中的名称以及标注姓名那里

Original: https://blog.csdn.net/fxxtsjs/article/details/123915073
Author: fxxtsjs
Title: python实现多人脸识别

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/701328/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球