基于OpenCV实现人脸识别--Python

目录

前言

第一章 OpenCV介绍

第二章 功能描述

2.1 对已有的数据进行检测

2.2 陌生人检测并发出警告

2.3 保存陌生人的视频

2.4 输入图片进行检测

2.5 现场录用信息

第三章 功能实现

3.1 截取人脸图片

3.2 对图片进行处理

3.3 进行训练

3.4 进行预测

3.5 实时预测

第四章 出现的问题

源码获取


前言

学习了图像识别,都没有具体的做出一个项目。现在的人脸识别很火,于是就做了一个基于opencv的人脸识别

第一章 OpenCV介绍

OpenCV基本函数使用--Python_牧子川的博客-CSDN博客

第二章 功能描述

以下的功能都实现了,但是有些功能会在源码进行解释

2.1 对已有的数据进行检测

当训练器已经包含了本人的面部信息时,在进行识别时能准确的识别出来,并显示出来

2.2 陌生人检测并发出警告

当有陌生人靠近并停留了10s钟以上时,就会发出警报

2.3 保存陌生人的视频

当有陌生人靠经并停留10秒中以上时,将该陌生人的信息进行保存未视频

2.4 输入图片进行检测

可以对输入的人脸的图片进行检测

2.5 现场录用信息

可以以及录用人脸信息,并保存当前的人脸信息

第三章 功能实现

3.1 截取人脸图片

第一步 打开摄像头

import cv2

cap = cv2.VideoCapture(0)
while cap.isOpened():
    _, frame = cap.read()
    cv2.imshow("img", frame)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
cap.release()与cv2.destroyAllWindows()只能放在while循环体外。

第二步 截取图片

使用的是人脸分类器

classfier = cv2.CascadeClassifier(r'G:\Opencv 4.5.3\opencv\build\etc\lbpcascades\lbpcascade_frontalface_improved.xml')

detectMultiScale函数。它可以检测出图片中所有的人脸,并将人脸用vector保存各个人脸的坐标、大小(用矩形表示),是一个一维数组[x, y, w, h]分别代表着上左,上右,下左,下右的坐标

faceRects = classfier.detectMultiScale(grey, scaleFactor=1.2, minNeighbors=20, flags=4)

detectMultiScale函数参数介绍 

1、grey:是输入图像

2、scaleFactor:这个是每次缩小图像的比例,默认是1.1 ,我这里选用1.2

3、minNeighbors=15:它表明如果有15个框都重叠一起了,那这里肯定是脸部,当minNeighbors越大时,能适当提高精度

4、minSize():匹配物体的最小范围 maxSize():匹配物体的最大范围

5、 flags = 0:可以取如下这些值:

CASCADE_DO_CANNY_PRUNING = 1, 利用canny边缘检测来排除一些边缘很少或者很多的图像区域

CASCADE_SCALE_IMAGE = 2, 正常比例检测

CASCADE_FIND_BIGGEST_OBJECT = 4, 只检测最大的物体

 第三步 保存图片

cv2.imwrite(img_name, image)
cv2.rectangle(frame, (x - 20, y - 20), (x + w + 20, y + h + 20), rect_color, 2)
# 显示当前捕捉到了多少人脸图片了
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame, 'num:%d' % num, (x + 30, y + 30), font, 1, (255, 0, 255), 4)
num += 1
if num > 200:  # 如果超过指定最大保存数量退出循环
    break

保存图像  

cv2.imwrite(file,img,num)保存一个图像

file:保存的文件名

img:要保存的图像。

num:可选,它针对特定的格式:对于JPEG,其表示的是图像的质量,用0 - 100的整数表示,默认95;对于png ,第三个参数表示的是压缩级别。默认为3.

3.2 对图片进行处理

 对图片进行训练时,实际上训练的时图片的像素点,所以我们要得到图片的像素

第一步 得到像素点

# 使用LBP分类器,还有一种更精确但速度较慢的Haar分类器
face_cascade = cv2.CascadeClassifier(r'G:\Opencv 4.5.3\opencv\build\etc\lbpcascades\lbpcascade_frontalface.xml')  # todo 
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)
(x, y, w, h) = faces[0]
return gray[y:y + w, x:x + h], faces[0]

 第二步 得到图片相对应的标签和像素

label = int(dir_name.replace("s", ""))
face, rect = detect_face(image)
# 忽略为检测到的人脸
if face is not None:
    faces.append(face)
    labels.append(label)
return faces, labels

3.3 进行训练

opencv中的face有专门的训练方式,对每个参考图像计算LBPH,得到一个向量。每个人脸都是整个向量集中的一个点。

cv2.face_FaceRecognizer.train(src,labels)

● src:训练图像,用来学习的人脸图像。
● labels:标签,人脸图像所对应的标签。

def train(face_recognizer):
    """训练数据"""
    print("数据准备")
    faces, labels = prepare_training_data(r"./train_data")
    print("准备完成")
    print("Total faces: ", len(faces))
    print("Total labels: ", len(labels))
    print("开始训练")
    # 训练人脸识别器
    face_recognizer.train(faces, np.array(labels))
    # 保存训练好的模型
    face_recognizer.save(r"./models/train1.yml")
    print("训练完成")

3.4 进行预测

cv2.face_FaceRecognizer.predict()

使用我们的人脸识别器预测图像 predict()入口参数必须为单通道灰度图像
对当前人脸图像进行判断,从人脸库中寻找与当前图像距离最近的人脸图像,与某个人脸图像最近,就将当前图像标注为其对应的标签。如果待测图像与所有人脸图像的距离都大于函数cv2.face.LBPHFaceRecognizer_create()中参数threshold所指定的距离值,则认为没有找到对应的结果,即无法识别当前人脸。

返回的是一个元组,第一个是识别某一类,第二类是一个置信度,即有多少可能

# 加载训练好的模型
face_recognizer.read(r'./models/train1.yml')
addr = input("请输入图片地址:")
test_img = cv2.imread(addr)
# 复制图像,因为我们不想更改原始图像
test_img = test_img.copy()
face, rect = detect_face(test_img)
label = face_recognizer.predict(face)
label_text = subjects[label[0]]

draw_rectangle(test_img, rect)
draw_text(test_img, label_text, rect[0], rect[1] - 5)

cv2.imshow("predict", test_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.5 实时预测

就是在框出人脸图像的同时对这个图片进行预测,即把截取图片和预测同时进行

face_recognizer.read(r'./models/train.yml')
cap = cv2.VideoCapture(0)
# 循环检测识别人脸
while True:
    _, frame = cap.read()
    face, rect = detect_face(frame)
    try:
        label = face_recognizer.predict(face)
    except Exception as e:
        print("错误信息为:", e)
        traceback.print_exc()
        print('traceback.format_exc():\n%s'%traceback.format_exc())
        cv2.imshow('camera', frame)
    else:
        print(label)
        if label[1] > 80:
            draw_rectangle(frame, rect)
            draw_text(frame, subjects[0], rect[0], rect[1] - 5)
        else:
            label_text = subjects[label[0]]
            draw_rectangle(frame, rect)
            draw_text(frame, label_text, rect[0], rect[1] - 5)

    cv2.imshow('camera', frame)
    # 等待10毫秒看是否有按键输入
    k = cv2.waitKey(10)
    # 如果输入q则退出循环
    if k & 0xFF == ord('q'):
       break

# 释放摄像头并销毁所有窗口
cap.release()
cv2.destroyAllWindows()

第四章 出现的问题

难点一:无法打开本机自带摄像头

解决方法:cap = cv2.VideoCapture(0)调用本机摄像头

难点二:在进行人脸识别时,只要人稍微一动,就会识别失败

解决方法:在读入图片时,可以先延时一小段时间在进行读入图片,这样在识别到第一帧图片时会等一会在去识别另一帧图片,只要时间间隔短,则不会出现这种情况

难点三:训练好模型后进行检测总是会出错,不能正确检测出本人

解决方法:这个原因为数据集不够,人脸的特征没有完全被学到;环境因素的影响会导致模型识别错误,可以通过增加人脸数据集的方式再次进行训练,增加噪声

源码获取

GitHub Face-recognition

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牧锦程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值