OpenCV人脸监测与识别系统开发

OpenCV人脸监测与识别系统开发 felix 2023-06-07 09:20:16 309

人脸识别技术是基于人的脸部特征,对输入的人脸图像或者视频流,首先判断其是否存在人脸,如果存在人脸,则进一步的给出每个脸的位置、大小和各个主要面部器官的位置信息。并依据这些信息,进一步提取每个人脸中所蕴涵的身份特征,并将其与已知的人脸进行对比,从而识别每个人脸的身份。

1.人脸识别步骤

梳理一下人脸识别实现的步骤,主要由人脸采集,预处理,特征提取,匹配与识别四个步骤组成

2 人脸监测

人脸识别首先应该先实现人脸监测,要先在一张图片中捕获到人脸,再去识别图片中的人脸和数据库中人脸数据进行比较。

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

进行人脸检测需要大量的图像数据来训练分类器,然后从中提取特征,使用OpenCV可以进行人脸的训练和推理,也可以训练自己的分类器为任何对象进行分类,同时OpenCV包含许多预先训练过的分类器,我们只需要调用OpenCV的接口就可以。

代码如下:

  1. #导入cv模块
  2. import cv2 as cv
  3. #检测函数
  4. def face_detect():
  5. gary = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
  6. face_detect = cv.CascadeClassifier('haarcascade_frontalface_default.xml')
  7. face = face_detect.detectMultiScale(gary)
  8. for x,y,w,h in face:
  9. cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2)
  10. cv.imshow('result',img)
  11. #读取图像
  12. img = cv.imread('face2.jpg')
  13. #检测函数
  14. face_detect()
  15. #等待
  16. while True:
  17. if ord('q') == cv.waitKey(0):
  18. break
  19. #释放内存
  20. cv.destroyAllWindows()

在代码中,首先对读取的图像进行了灰度处理,然后引入级联分类器文件,通过detectMultiScale()函数来调用分类器功能,通过rectangle()函数来标记图像中的面孔,如果发现人脸,它会返回检测到的面部位置,作为左上角(x,y)的矩形,并将”w”作为宽度,将”h”作为高度 。

运行效果如下:

3.录入人脸功能模块

导入第三方库:

  1. import cv2
  2. import os
  3. from PIL import Image
  4. import numpy as np

OS:主要是对文件和文件夹进行操作,在Python中对⽂件和⽂件夹的操作要借助os模块⾥⾯的相关功能。

PIL:python中最常用的图形处理库,PIL支持图像存储、显示和处理,它能够处理几乎所有图片格式,可以完成对图像的缩放、裁剪、叠加以及图像添加线条、图像和文字等操作。

NumPy:一个由多维数组对象和用于处理数组的例程集合组成的库。可以执行以下操作:数组的算数和逻辑运算。傅立叶变换和用于图形操作的例程。与线性代数有关的操作。 NumPy 拥有线性代数和随机数生成的内置函数。

存储人脸数据:

  1. facesSamples=[]

存储姓名数据:

  1. ids=[]

存储图片信息:

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

加载分类器:

  1. face_detector = cv2.CascadeClassifier('haarcascade_frontalface_alt2.xml'

遍历列表中的图片:

  1. for imagePath in imagePaths:

将打开的图片灰度化:

  1. PIL_img = Image.open(imagePath).convert('L')

将图片转化为数组:

  1. img_numpy = np.array(PIL_img,'uint8')

获取图片人脸特征:

  1. faces = face_detector.detectMultiScale(img_numpy)

获取每一张拍摄图片的id与姓名:

  1. id = int(os.path.split(imagePath)[1].split('.')[0])

做判断,预防拍摄无面容图片:

  1. for x,y,w,h in faces:
  2. ids.append(id)
  3. facesSamples.append(img_numpy[y:y+h,x:x+w])

打印面部特征与id,并返回数据:

  1. print('id',id)
  2. print('fs:',facesSamples)
  3. return facesSamples,ids

调用图片路径:

  1. path='./data/jm/'

获取图像数组和id标签数组和姓名:

  1. faces,ids=getImageAndLabels(path)

加载识别器:

  1. recognizer = cv2.face.LBPHFaceRecognizer_create()

训练数据:

  1. recognizer.train(faces,np.array(ids))

保存面部特征到文件夹:

  1. recognizer.write('tupian/tupian.yml')

完整代码如下:

  1. import os
  2. import cv2
  3. from PIL import Image
  4. import numpy as np
  5. def getImageAndLabels(path):
  6. facesSamples=[]
  7. ids=[]
  8. imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
  9. #检测人脸
  10. face_detector = cv2.CascadeClassifier('haarcascade_frontalface_alt2.xml')
  11. #打印数组imagePaths
  12. print('数据排列:',imagePaths)
  13. #遍历列表中的图片
  14. for imagePath in imagePaths:
  15. #打开图片,黑白化
  16. PIL_img=Image.open(imagePath).convert('L')
  17. #将图像转换为数组,以黑白深浅
  18. # PIL_img = cv2.resize(PIL_img, dsize=(400, 400))
  19. img_numpy=np.array(PIL_img,'uint8')
  20. #获取图片人脸特征
  21. faces = face_detector.detectMultiScale(img_numpy)
  22. #获取每张图片的id和姓名
  23. id = int(os.path.split(imagePath)[1].split('.')[0])
  24. #预防无面容照片
  25. for x,y,w,h in faces:
  26. ids.append(id)
  27. facesSamples.append(img_numpy[y:y+h,x:x+w])
  28. print('id:', id)
  29. print('fs:', facesSamples)
  30. return facesSamples,ids
  31. if __name__ == '__main__':
  32. #图片路径
  33. path='./data/jm/'
  34. #获取图像数组和id标签数组和姓名
  35. faces,ids=getImageAndLabels(path)
  36. #获取训练对象
  37. recognizer=cv2.face.LBPHFaceRecognizer_create()
  38. #recognizer.train(faces,names)#np.array(ids)
  39. recognizer.train(faces,np.array(ids))
  40. #保存文件
  41. recognizer.write('trainer/trainer.yml')
  42. #save_to_file('names.txt',names)

4.人脸识别

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

使用刚刚训练的识别器模型(加载trainer.yml),然后就和刚刚“人脸分类器”的步骤一样去进行人脸识别,并且recognizer.predict将返回每张图片识别后的匹配率。

人脸识别实现函数如下:

  1. def face_detect(img):
  2. gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换为灰度
  3. face_detector=cv2.CascadeClassifier(r'haarcascade_frontalface_alt2.xml')
  4. face=face_detector.detectMultiScale(gray,1.1,5,cv2.CASCADE_SCALE_IMAGE,(100,100),(300,300))
  5. #face=face_detector.detectMultiScale(gray)
  6. for x,y,w,h in face:
  7. cv2.circle(img,center=(x+w//2,y+h//2),radius=w//2,color=(0,255,0),thickness=1)
  8. # 人脸识别
  9. ids, confidence = recogizer.predict(gray[y:y + h, x:x + w])
  10. #print('标签id:',ids,'置信评分:', confidence)
  11. if confidence > 80:
  12. cv2.putText(img, 'unkonw', (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
  13. else:
  14. cv2.putText(img,str(names[ids-1]), (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
  15. cv2.imshow('result',img)

添加名字标签:

  1. #名字标签
  2. def name():
  3. path = './tupian/'
  4. # names = []
  5. imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
  6. for imagePath in imagePaths:
  7. name = str(os.path.split(imagePath)[1].split('.',2)[1])
  8. names.append(name)

加载监控或已保存下来的视频:

  1. #加载视频
  2. cap=cv2.VideoCapture(8)
  3. name()
  4. while True:
  5. flag,frame=cap.read()
  6. if not flag:
  7. break
  8. face_detect_demo(frame)
  9. if ord(' ') == cv2.waitKey(10):
  10. break
  11. #释放内存+视频
  12. cv2.destroyAllWindows()
  13. cap.release()
最终效果如下

5.遇到的问题

1.旭日x3派并没有opencv-contrib-python库,需要通过

  1. pip install opencv-contrib-python

进行安装

2.用OPENCV出现这样的错误:

  1. cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'

这个错误可能是因为图片路径形式书写错误,图片的格式不对,图片的数量不一致,路径中存在中文导致。

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
felix
红包 点赞 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
felix
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区