当前位置:   article > 正文

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

基于opencv的人脸识别系统


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

1. 调用库函数

import cv2
import numpy as np
  • 1
  • 2

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

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

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

pos_path = './resource/face_detect/video2imagem3/'
neg_path = './resource/face_detect/video2imagec1/'
test_path = './resource/face/'
images = []
labels = []
  • 1
  • 2
  • 3
  • 4
  • 5

4. 调用人脸检测器

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

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

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

7. 建立LBPH人脸识别模型

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

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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

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')
  • 1
  • 2
  • 3
  • 4
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/733681
推荐阅读
相关标签
  

闽ICP备14008679号