我正在参加「掘金·启航计划」
人脸检测部分我们已经搞定。
接下来我们来看一下人脸识别,那么人脸识别和人脸检测有何区别呢?
人脸检测就是使用opencv通过其自带的人脸特征数据,检测当前图片中是否含有人脸,而人脸识别是在人脸检测的基础上,检测图片中的人脸是不是我们目标的人脸。
听起来好像有点高大上。也确实如此。但是,过程并不是像我说的这么简单。首先,我们需要先开始训练数据。
一:训练数据
1:安装 opencv-contrib-python 模块
pip install opencv-contrib-python
具体的安装方法,这个要看你自己的环境。
2 :训练数据
首先,我们需要做一下准备。准备一些人脸数据,这里我会将我用到的人脸数据放到文章末尾,可以下载。
上代码:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time : 2022/3/22 19:15
# @Author : stone
# @Email : 805795955@qq.com
# @File : task.py
# @Software: PyCharm
import os
import cv2 as cv
import sys
from PIL import Image
import numpy as np
def getFaceImgAndId(path):
faceArray = []
idArray = []
imgPath = [os.path.join(path, f) for f in os.listdir(path)]
print(imgPath)
# 加载特征数据
face_detector = cv.CascadeClassifier(
'C:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
for imagePath in imgPath:
# 打开图片
img = Image.open(imagePath).convert('L')
# 将图像转换为数组
img_np = np.array(img,'uint8')
# 图像人脸检测
faces = face_detector.detectMultiScale(img_np, scaleFactor=1.2, minNeighbors=10)
id = int(os.path.split(imagePath)[1].split('.')[0])
for x, y, w, h in faces:
faceArray.append(img_np[y:y+h,x:x+w])
idArray.append(id)
return faceArray,idArray
# 存储人脸识别图片路径
path = './face/'
# 获取图像数组和id标签数组
faces, id = getFaceImgAndId(path)
# 训练数据对象
recogObj = cv.face.LBPHFaceRecognizer_create()
recogObj.train(faces,np.array(id))
# 将训练完成的数据 写入特征文件
recogObj.write('trainer/trainer.yml')
执行代码过程中代码可能会报错:
AttributeError: module 'cv2' has no attribute 'gapi_wip_gst_GStreamerPipeline'
解决方法很简单,升级 opencv-python至最新版,执行下方命令:
pip install --user --upgrade opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
执行代码再次报错:
AttributeError: module ‘cv2‘ has no attribute ‘face‘
这个怎么解决呢?卸载opencv-contrib-python,opencv-python,重新安装应该就好了。
执行下方这四个命令:
pip uninstall opencv-contrib-python
pip uninstall opencv-python
pip install opencv-python
pip install opencv-contrib-python
再次执行,发现目录下trainer目录下多了一个trainer.yml文件(trainer这个目录需要提前创建好,不然执行上方代码会报错)
二:人脸识别
LBPH(Local Binary Pattern Histogram) 将检测到的人脸分为小单元, 并将其与模型中
的对应单元进行比较, 对每个区域的匹配值产生一个直方图。 由于这种方法的灵活性, LBPH
是唯一允许模型样本人脸和检测到的人脸在形状、 大小上可以不同的人脸识别算法。
调整后的区域中调用 predict()函数, 该函数返回两个元素的数组: 第一个元素是所识别
个体的标签, 第二个是置信度评分。 所有的算法都有一个置信度评分阈值, 置信度评分用来
衡量所识别人脸与原模型的差距, 0 表示完全匹配。 可能有时不想保留所有的识别结果, 则
需要进一步处理, 因此可用自己的算法来估算识别的置信度评分。 LBPH 一个好的识别参
考值要低于 50 , 任何高于 80 的参考值都会被认为是低的置信度评分。
上代码:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time : 2022/3/22 19:15
# @Author : stone
# @Email : 805795955@qq.com
# @File : task.py
# @Software: PyCharm
import cv2
import numpy as np
import os
#加载训练数据集文件
recogizer = cv2.face.LBPHFaceRecognizer_create()
recogizer.read('trainer/trainer.yml')
#准备识别的图片
img=cv2.imread('6.pgm')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
face_detector = cv2.CascadeClassifier(
'C:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
faces = face_detector.detectMultiScale(gray)
for x,y,w,h in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
#人脸识别
id,confidence=recogizer.predict(gray[y:y+h,x:x+w])
print('标签id:',id,'置信评分:',confidence)
cv2.imshow('result',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
执行代码,输出:
标签id: 11 置信评分: 124.17017878044689
有以上大概就是人脸识别的基本实现,也就是能简单的实现,具体应用还是要再细化一下。
有好的建议,请在下方输入你的评论。