基于OpenCV的简单人脸识别系统


声明:本程序基于Python的OpenCV模块编程,利用opencv已有的人脸检测器和人脸识别器进行实时人脸识别

1. 调用库函数

import cv2
import numpy as np

2. 调用摄像头并设置窗口

frameWidth = 640
frameHeight = 480
cap = cv2.VideoCapture(0)
cap.set(3, frameWidth)      #设置参数,10为亮度
cap.set(4, frameHeight)
cap.set(10,150)

3. 设置图片正负样本数据集的路径

pos_path = './resource/face_detect/video2imagem3/'
neg_path = './resource/face_detect/video2imagec1/'
test_path = './resource/face/'
images = []
labels = []

4. 调用人脸检测器

注:人脸识别器在安装opencv库的时候就一块安装了,在opencv的安装路径下可以找到。

faceCascade = cv2.CascadeClassifier("resource/haarcascade_frontalface_default.xml")

5. 正负样本载入

由于本数据集人脸数据是通过程序处理视频获得的,因此,便于批量导入程序中。

正样本(人脸)与负样本(环境)比例大致为1:3,据说这样比例效果较好;标签为0,1。
导入语句如下:

for i in range(60):         # 正样本
    images.append(cv2.imread(pos_path+str(2*(i+1))+'.jpg',cv2.IMREAD_GRAYSCALE))
    labels.append(0)

for i in range(173):        # 负样本
    images.append(cv2.imread(neg_path+str(2*(i+1))+'.jpg',cv2.IMREAD_GRAYSCALE))
    labels.append(1)

6.提取人脸区域

这里对于没检测到人脸区域的图片不进行处理,对于人脸区域,将其周围20像素左右部分提取出来

def processing(imageslist):
    for j in range(len(imageslist)):
        faces = faceCascade.detectMultiScale(imageslist[j], 1.1, 4)
        for x,y,w,h in faces:
            if x >= 20 and y >= 20:		# 未处理没检测到人脸的情况
               imageslist[j] = imageslist[j][y-20:y+h+20, x-20:x+w+20]
    return imageslist

7. 建立LBPH人脸识别模型

这里采用LBPH人脸识别模块,因为这种方法不需要图片数据集为统一尺寸,EigenFaces和Fisherfaces模块均需要训练集图片和测试的图片尺寸保持一致。

imagesCopy = images
# 提取图像中人脸的区域
imagesCopy = processing(imagesCopy)
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.train(imagesCopy, np.array(labels))

8. 实时检测

人脸检测中,如果未检测到人脸,则face返回的是空元组,检测到人脸后,提取出人脸区域,采用recognizer.predict进行识别,对于返回值的confidence,小于50认为结果可靠,而大于80则认为差别较大。

while True:
    success,img = cap.read()
    predict_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    face = faceCascade.detectMultiScale(predict_image, 1.1, 4)
    # print(face)     # 空的元组有可能
    if face != ():
        for x, y, w, h in face:
            if x >= 20 and y >= 20:
                faceArea = predict_image[y-20:y+h+20, x-20:x+w+20]
                cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 1)
                label, confidence = recognizer.predict(faceArea)
                if confidence <= 80 and label == 0:
                    cv2.putText(img, "LQL",(x, y-20), cv2.FONT_HERSHEY_COMPLEX, 1,(255,0,0,1))
                    print("YOU ARE LQL")
                else:
                    cv2.putText(img, "OTHERS", (x, y-20), cv2.FONT_HERSHEY_COMPLEX, 1,(255,0,0),1)
                    print("OTHERS")
                    print(confidence)
                    print(label)
    else:
        cv2.putText(img, "None", (320, 240), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 0, 255), 1)
        print("None")
    cv2.imshow("img", img)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

9. 测试结果

能够基本实现特定人脸识别的功能。

10. 不足之处

  1. 未将训练部分与检测部分分开,导致每次都要重新训练,消耗一定的时间,目前只做了一种人脸识别;–已解决
  2. 由于数据是从视频中导出的图片,因此对于训练集中可能存在的未检测到人脸的情况也未作处理;
  3. 没有将所有的图片尺寸resize为统一尺寸,因此只能用LBPH模块进行人脸识别,不过,在另一方面,用cv2.resize可能会存在画面比例失衡的问题,损失训练效果;
  4. 另外,对于负样本,只用了背景图片,后续可以试试物体之类的。
    总之,目前只是实现了一个简单的实时人脸识别功能,后续有时间再改进。

11. 改进方法

  1. 下列语句可以对训练好的模型进行保存和读取,因此可以将训练部分与识别部分分隔开
recognizer = cv2.face.LBPHFaceRecognizer_create()

recognizer.save('./resource/face_detect/MyFaceModel.xml')
recognizer.read('./resource/face_detect/MyFaceModel.xml')
  • 15
    点赞
  • 99
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值