苦学Opencv的第十四天:人脸检测和人脸识别

Python OpenCV入门到精通学习日记:人脸检测和人脸识别

前言

经过了十三天的不懈努力,我们终于也是来到了人脸检测和人脸识别啦!相信大家也很激动吧。接下来我们开始吧!

人脸识别是基于人的脸部特征信息进行身份识别的一种生物识别技术,也是计算机视觉重点发展的技术。机器学习算法诞生之后,计算机可以通过摄像头等输入设备自动分析图像中包含的内容信息,随着技术的不断发展,现在已经有了多种人脸识别的算法。接下来我们将学习OpenCV自带的多种图像跟踪技术和3种人脸识别技术的用法。

人脸检测和人脸识别

  • Python OpenCV入门到精通学习日记:人脸检测和人脸识别
    • 前言
    • 1 人脸检测
      • 1.1 级联分类器
      • 1.2 方法
      • 1.3 分析人脸位置
    • 2 检测其他内容
      • 2.1 眼睛检测
      • 2.2 猫脸检测
      • 2.3 行人检测
      • 2.4 车牌检测
    • 3 人脸识别
      • 3.1 Eigenfaces人脸识别器
      • 3.2 Fisherfaces人脸识别器
      • 3.3 Local Binary Pattern Histogram人脸识别器
    • 小结

1 人脸检测

人脸检测是让计算机在一幅画面中找出人脸的位置。毕竟计算机还达不到人类的智能水平,所以计算机在检测人脸的过程中实际上是在做“分类”操作,例如,计算机发现图像中有一些像素组成了眼睛的特征,那这些像素就有可能是“眼睛”;如果“眼睛”旁边还有“鼻子”和“另一只眼睛”的特征,那这3个元素所在的区域就很有可能是人脸区域;但如果“眼睛”旁边缺少必要的“鼻子”和“另一只眼睛”,那就认为这些像素并没有组成人脸,它们不是人脸图像的一部分。

检测人脸的算法比较复杂,但OpenCV已经将这些算法封装好,我们将学习如何利用OpenCV自带的功能进行人脸检测。

1.1 级联分类器

将一系列简单的分类器按照一定顺序级联到一起就构成了级联分类器,使用级联分类器的程序可以通过一系列简单的判断来对样本进行识别。例如,依次满足“有6条腿”“有翅膀”“有头、胸、腹”这3个条件的样本就可以被初步判断为昆虫,但如果任何一个条件不满足,则不会被认为是昆虫。

OpenCV提供了一些已经训练好的级联分类器,这些级联分类器以XML文件的方式保存在指定路径中。
路径如下:

...\Python\Lib\site-packages\cv2\data\

如果没有错,那你会在data文件夹里面看见这些:
在这里插入图片描述
不同版本的OpenCV自带的级联分类器XML文件可能会有差别,data文件夹中缺少的XML文件可以到OpenCV的源码托管平台下载,链接: 源码托管平台github,github需要翻墙,如果没有条件,steam++也有github免费加速功能,凑合一下吧,链接: steam++。

每一个XML文件都对应一种级联分类器,但有些级联分类器的功能是类似的,部分XML文件对应的功能表格如下:

级联分类器XML文件名检测的内容
haarcascade_eye.xml眼睛检测
haarcascade_eye_tree_eyeglasses.xml眼镜检测
haarcascade_frontalcatface.xml前面猫脸检测
haarcascade_frontalface_default.xml前面人脸检测
haarcascade_fullbody.xml身形检测
haarcascade_lefteye_2splits.xml左眼检测
haarcascade_lowerbody.xml下半身检测
haarcascade_profileface.xml侧面人脸检测
haarcascade_righteye_2splits.xml右眼检测
haarcascade_russianplatenumber.xml车牌检测
haarcascade_smile.xml笑容检测
haarcascade_upperbody.xml上半身检测

想要实现哪种图像检测,就要在程序启动时加载对应的级联分类器。接下来我们学习如何加载并使用这些XML文件。

1.2 方法

OpenCV实现人脸检测需要做两步操作加载级联分类器使用分类器识别图像。这两步操作都有对应的方法。首先是加载级联分类器,OpenCV通过CascadeClassifier()方法创建了分类器对象。

<CascadeClassifier object> =cv2.CascadeClassifier(filename)
参数说明:filename:级联分类器的XML文件名。
返回值说明:object:分类器对象。

然后我们使用已经创建好的分类器对图像进行识别,这个过程需要调用分类器对象的detectMultiScale()方法。

objects = cascade.detectMultiScale(image, scaleFactor,minNeighbors, flags, minSize, maxSize)
对象说明:cascade:已有的分类器对象。
参数说明:image:待分析的图像。scaleFactor:可选参数,扫描图像时的缩放比例。minNeighbors:可选参数,每个候选区域至少保留多少个检测结果才可以判定为人脸。该值越大,分析的误差越小。flags:可选参数,旧版本OpenCV的参数,建议使用默认值。minSize:可选参数,最小的目标尺寸。maxSize:可选参数,最大的目标尺寸。返回值说明:objects:捕捉到的目标区域数组,数组中每一个元素都是一个目标区域,每一个目标区域都包含4个值,分别是:左上角点横坐标、左上角点纵坐标、区域宽、区域高。object的格式为:[[244 203 111 111] [432 81 133133]]。

1.3 分析人脸位置

haarcascade_frontalface_default.xml是检测正面人脸的级联分类器文件,加载该文件就可以创建出追踪正面人脸的分类器,调用分类器对象的detectMultiScale()方法,得到的objects结果就是分析得出的人脸区域的坐标、宽和高。

import cv2img = cv2.imread("model.png")  # 读取人脸图像
# 加载识别人脸的级联分类器
faceCascade = cv2.CascadeClassifier("cascades/haarcascade_frontalface_default.xml")
faces = faceCascade.detectMultiScale(img, 1.3)  # 识别出所有人脸
for (x, y, w, h) in faces:  # 遍历所有人脸的区域cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5)  # 在图像中人脸的位置绘制方框
cv2.imshow("img", img)  # 显示最终处理的效果
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

🌟faceCascade = cv2.CascadeClassifier("cascades/haarcascade_frontalface_default.xml")cascades/haarcascade_frontalface_default.xml是haarcascade_frontalface_default.xml文件的路径,你这个文件在哪,你就设置在哪。

运行结果如下:
在这里插入图片描述

看着这个代码,我在想,那么我能不能把昨天学习的视频处理放在这里使用呢?说办就办。我们只需要将代码进行修改就可以了:

import cv2capture = cv2.VideoCapture(0) # 打开笔记本内置摄像头
while (capture.isOpened()): # 笔记本内置摄像头被打开后retval, img = capture.read() # 从摄像头中实时读取视频faceCascade = cv2.CascadeClassifier("cascades/haarcascade_frontalface_default.xml")faces = faceCascade.detectMultiScale(img, 1.3)  # 识别出所有人脸for (x, y, w, h) in faces:  # 遍历所有人脸的区域cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5)  # 在图像中人脸的位置绘制方框cv2.imshow("Video", img) # 在窗口中显示读取到的视频key = cv2.waitKey(1) # 窗口的图像刷新时间为1毫秒if key == 32: # 如果按下空格键break
capture.release() # 关闭笔记本内置摄像头
cv2.destroyAllWindows() # 销毁显示摄像头视频的窗口

很好,成功了!!!看成果:
在这里插入图片描述

OpenCV还可以实现为人脸添加戴墨镜的的功能,需要执行以下3个步骤:

  • 编写一个覆盖图片的overlay_img()方法。因为素材中可能包含透明像素,这些透明像素不可以遮挡人脸,所以在覆盖背景图像时要做判断忽略所有透明像素判断一个像素是否为透明像素,只需将图像从3通道转为4通道,判断第4通道的alpha值,alpha值为1表示完全不透明,0表示完全透明。
  • 创建人脸识别级联分类器,分析图像中人脸的区域。
  • 把墨镜图像按照人脸宽度进行缩放,并覆盖到人脸区域约1/3的位置。

接下来可以开始编写代码了:

import cv2# 覆盖图像
def overlay_img(img, img_over, img_over_x, img_over_y):"""覆盖图像:param img: 背景图像:param img_over: 覆盖的图像:param img_over_x: 覆盖图像在背景图像上的横坐标:param img_over_y: 覆盖图像在背景图像上的纵坐标:return: 两张图像合并之后的图像"""img_h, img_w, img_p = img.shape  # 背景图像宽、高、通道数img_over_h, img_over_w, img_over_c = img_over.shape  # 覆盖图像高、宽、通道数if img_over_c == 3:  # 通道数等于3img_over = cv2.cvtColor(img_over, cv2.COLOR_BGR2BGRA)  # 转换成4通道图像for w in range(0, img_over_w):  # 遍历列for h in range(0, img_over_h):  # 遍历行if img_over[h, w, 3] != 0:  # 如果不是全透明的像素for c in range(0, 3):  # 遍历三个通道x = img_over_x + w  # 覆盖像素的横坐标y = img_over_y + h  # 覆盖像素的纵坐标if x >= img_w or y >= img_h:  # 如果坐标超出最大宽高break  # 不做操作img[y, x, c] = img_over[h, w, c]  # 覆盖像素return img  # 完成覆盖的图像face_img = cv2.imread("peoples.png")  # 读取人脸图像
glass_img = cv2.imread("glass.png", cv2.IMREAD_UNCHANGED)  # 读取眼镜图像,保留图像类型
height, width, channel = glass_img.shape  # 获取眼镜图像高、宽、通道数
# 加载级联分类器
face_cascade = cv2.CascadeClassifier("./cascades/haarcascade_frontalface_default.xml")
garyframe = cv2.cvtColor(face_img, cv2.COLOR_BGR2GRAY)  # 转为黑白图像
faces = face_cascade.detectMultiScale(garyframe, 1.3, 5)  # 识别人脸
for (x, y, w, h) in faces:  # 遍历所有人脸的区域gw = w  # 眼镜缩放之后的宽度gh = int(height * w / width)  # 眼镜缩放之后的高度度glass_img = cv2.resize(glass_img, (gw, gh))  # 按照人脸大小缩放眼镜overlay_img(face_img, glass_img, x, y + int(h * 1 / 3))  # 将眼镜绘制到人脸上
cv2.imshow("screen", face_img)  # 显示最终处理的效果
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

运行如下:
在这里插入图片描述
那么如何在视频中实现呢?让我们试试看:

import cv2# 覆盖图像
def overlay_img(img, img_over, img_over_x, img_over_y):"""覆盖图像:param img: 背景图像:param img_over: 覆盖的图像:param img_over_x: 覆盖图像在背景图像上的横坐标:param img_over_y: 覆盖图像在背景图像上的纵坐标:return: 两张图像合并之后的图像"""img_h, img_w, img_p = img.shape  # 背景图像宽、高、通道数img_over_h, img_over_w, img_over_c = img_over.shape  # 覆盖图像高、宽、通道数if img_over_c == 3:  # 通道数等于3img_over = cv2.cvtColor(img_over, cv2.COLOR_BGR2BGRA)  # 转换成4通道图像for w in range(0, img_over_w):  # 遍历列for h in range(0, img_over_h):  # 遍历行if img_over[h, w, 3] != 0:  # 如果不是全透明的像素for c in range(0, 3):  # 遍历三个通道x = img_over_x + w  # 覆盖像素的横坐标y = img_over_y + h  # 覆盖像素的纵坐标if x >= img_w or y >= img_h:  # 如果坐标超出最大宽高break  # 不做操作img[y, x, c] = img_over[h, w, c]  # 覆盖像素return img  # 完成覆盖的图像capture = cv2.VideoCapture(0)
while (capture.isOpened()):retval, face_img = capture.read()glass_img = cv2.imread("glass.png", cv2.IMREAD_UNCHANGED)  # 读取眼镜图像,保留图像类型height, width, channel = glass_img.shape  # 获取眼镜图像高、宽、通道数# 加载级联分类器face_cascade = cv2.CascadeClassifier("./cascades/haarcascade_frontalface_default.xml")garyframe = cv2.cvtColor(face_img, cv2.COLOR_BGR2GRAY)  # 转为黑白图像faces = face_cascade.detectMultiScale(garyframe, 1.3, 5)  # 识别人脸for (x, y, w, h) in faces:  # 遍历所有人脸的区域gw = w  # 眼镜缩放之后的宽度gh = int(height * w / width)  # 眼镜缩放之后的高度度glass_img = cv2.resize(glass_img, (gw, gh))  # 按照人脸大小缩放眼镜overlay_img(face_img, glass_img, x, y + int(h * 1 / 3))  # 将眼镜绘制到人脸上cv2.imshow("screen", face_img)  # 显示最终处理的效果key = cv2.waitKey(1)if key == 32:break
capture.release()
cv2.destroyAllWindows()  # 释放所有窗体

正常运行但是会有报错:libpng warning: iCCP: known incorrect sRGB profile
在这里插入图片描述

libpng warning: iCCP: known incorrect sRGB profile 指的是 PNG 图像文件中包含了一个已知不正确的 sRGB 色彩配置文件。这个警告通常不会影响图像的显示或处理,但它表明图像可能在不同的环境或软件中打开时颜色表现不一致。关于这个⚠️警告大家有什么见解麻烦在评论区讲讲哦~

2 检测其他内容

OpenCV提供的级联分类器除了可以识别人脸以外,还可以识别一些其他具有明显特征的物体,如眼睛、行人等。我来学习几个OpenCV自带的级联分类器的用法。

2.1 眼睛检测

haarcascade_eye.xml是检测眼睛的级联分类器文件,加载该文件就可以追踪眼睛的分类器。

这是一个梨子→[🍐]:在图像的眼睛位置绘制红框。

import cv2img = cv2.imread("img.png")  # 读取人脸图像
# 加载识别眼睛的级联分类器
eyeCascade = cv2.CascadeClassifier("cascades\\haarcascade_eye.xml")
eyes = eyeCascade.detectMultiScale(img, 1.15)  # 识别出所有眼睛
for (x, y, w, h) in eyes:  # 遍历所有眼睛的区域cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 4)  # 在图像中眼睛的位置绘制方框
cv2.imshow("img", img)  # 显示最终处理的效果
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

运行结果如下:
在这里插入图片描述

2.2 猫脸检测

OpenCV还提供了2个训练好的检测猫脸的级联分类器,分别是haarcascade_frontalcatface.xml 和
haarcascade_frontalcatface_extended.xml,前者的判断标准比较高,较为精确,但可能有些猫脸识别不出来;后者的判断标准比较低,只要类似猫脸就会被认为是猫脸。使用猫脸分类器不仅可以判断猫脸的位置,还可以识别图像中有几只猫。

这是一个梨子→[🍐]:在图像里找到猫脸的位置。

import cv2
img = cv2.imread("img.png")  # 读取猫脸图像
# 加载识别猫脸的级联分类器
catFaceCascade = cv2.CascadeClassifier("cascades\\haarcascade_frontalcatface.xml")
catFace = catFaceCascade.detectMultiScale(img, 1.15, 4)  # 识别出所有猫脸
for (x, y, w, h) in catFace:  # 遍历所有猫脸的区域cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 5)# 在图像中猫脸的位置绘制方框
cv2.imshow("Where is your cat ?", img)  # 显示最终处理的效果
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

运行结果如下:
在这里插入图片描述

2.3 行人检测

haarcascade_fullbody.xml是检测人体(正面直立全身或背面直立全身)的级联分类器文件,加载该文件就可以追踪人体的分类器。

这是一个梨子→[🍐]:在图像中找到行人的位置。

import cv2
img = cv2.imread("img.png")  # 读取图像
# 加载识别类人体的级联分类器
bodyCascade = cv2.CascadeClassifier("cascades\\haarcascade_fullbody.xml")
bodys = bodyCascade.detectMultiScale(img, 1.15, 4)  # 识别出所有人体
for (x, y, w, h) in bodys:  # 遍历所有人体区域cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 1)# 在图像中人体的位置绘制方框
cv2.imshow("img", img)  # 显示最终处理的效果
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

运行结果如下:
在这里插入图片描述

2.4 车牌检测

haarcascade_russian_plate_number.xml是检测汽车车牌的级联分类器文件,加载该文件就可以追踪图像中的车牌。

这是一个梨子→[🍐]:标记图像中车牌的位置。

import cv2img = cv2.imread("img.png")  # 读取车的图像
# 加载识别车牌的级联分类器
plateCascade = cv2.CascadeClassifier("cascades\\haarcascade_russian_plate_number.xml")
plates = plateCascade.detectMultiScale(img, 1.15, 4)  # 识别出所有车牌
for (x, y, w, h) in plates:  # 遍历所有车牌区域cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)  # 在图像中车牌的位置绘制方框
cv2.imshow("img", img)  # 显示最终处理的效果
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

运行结果如下:
在这里插入图片描述

3 人脸识别

OpenCV提供了3种人脸识别方法 ,分别是 Eigenfaces 、Fisherfaces和LBPH。这3种方法都是通过对比样本的特征最终实现人脸识别。因为这3种算法提取特征的方式不一样,侧重点不同,所以不能分出孰优孰劣,只能说每种方法都有各自的识别风格。OpenCV为每一种人脸识别方法都提供了创建识别器、训练识别器和识别3种方法,这3种方法的语法非常相似。那么开始学吧!!!

3.1 Eigenfaces人脸识别器

Eigenfaces也叫作“特征脸”。Eigenfaces通过==PCA(主成分分析)==方法将人脸数据转换到另外一个空间维度做相似性计算。在计算过程中,算法可以忽略一些无关紧要的数据,仅识别一些具有代表性的特征数据,最后根据这些特征识别人脸。

开发者需要通过以下方法完成人脸识别操作:

  • 通过cv2.face.EigenFaceRecognizer_create()方法创建Eigenfaces人脸识别器。
recognizer =cv2.face.EigenFaceRecognizer_create(num_components,threshold)参数说明:num_components:可选参数,PCA方法中保留的分量个数,建议使用默认值。threshold:可选参数,人脸识别时使用的阈值,建议使用默认值。
返回值说明:recognizer:创建的Eigenfaces人脸识别器对象。
  • 创建识别器对象后,需要通过对象的train()方法训练识别器。建议每个人都给出2幅以上的人脸图像作为训练样本。
recognizer.train(src, labels)对象说明:recognizer:已有的Eigenfaces人脸识别器对象。
参数说明:src:用来训练的人脸图像样本列表,格式为list。样本图像必须宽、高一致。labels:样本对应的标签,格式为数组,元素类型为整数。数组长度必须与样本列表长度相同。样本与标签按照插入顺序一一对应
  • 训练识别器后可以通过识别器的predict()方法识别人脸,该方法对比样本的特征,给出最相近的结果和评分。
label, confidence = recognizer.predict(src)对象说明:recognizer:已有的Eigenfaces人脸识别器对象。
参数说明:src:需要识别的人脸图像,该图像宽、高必须与样本一致。
返回值说明:label:与样本匹配程度最高的标签值。confidence:匹配程度最高的信用度评分。评分小于5000匹配程度较高,0分表示2幅图像完全一样。

这是一个梨子→[🍐]:使用Eigenfaces识别人脸,首先我们以两个人的照片作为训练样本,这里选用杨幂和北川景子(日本女演员,因为网上说她和杨幂长得很像,所以选她)。

import cv2
import numpy as npphotos = list()  # 样本图像列表
lables = list()  # 标签列表
target_size = (200, 200)  # 设置统一的图像尺寸photos.append(cv2.resize(cv2.imread("face\\bei_1.png", 0),target_size))  # 记录第1张人脸图像
lables.append(0)  # 第1张图像对应的标签
photos.append(cv2.resize(cv2.imread("face\\bei_2.png", 0),target_size))  # 记录第2张人脸图像
lables.append(0)  # 第2张图像对应的标签
photos.append(cv2.resize(cv2.imread("face\\bei_3.png", 0),target_size))  # 记录第3张人脸图像
lables.append(0)  # 第3张图像对应的标签photos.append(cv2.resize(cv2.imread("face\\yangmi_1.png", 0),target_size))  # 记录第4张人脸图像
lables.append(1)  # 第4张图像对应的标签
photos.append(cv2.resize(cv2.imread("face\\yangmi_2.png", 0),target_size))  # 记录第5张人脸图像
lables.append(1)  # 第5张图像对应的标签
photos.append(cv2.resize(cv2.imread("face\\yangmi_3.png", 0),target_size))  # 记录第6张人脸图像
lables.append(1)  # 第6张图像对应的标签names = {"0": "bei", "1": "yangmi"}  # 标签对应的名称字典recognizer = cv2.face.EigenFaceRecognizer_create()  # 创建特征脸识别器
recognizer.train(photos, np.array(lables))  # 识别器开始训练i = cv2.imread("face\\yangmi_test.png", 0)  # 待识别的人脸图像
i = cv2.resize(i,target_size)
label, confidence = recognizer.predict(i)  # 识别器开始分析人脸图像
print("confidence = " + str(confidence))  # 打印评分
print(names[str(label)])  # 数组字典里标签对应的名字
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

运行结果如下:
在这里插入图片描述

我的测试图也的确是杨幂,就是这个匹配程度很低,另外这是文件目录:

在这里插入图片描述
🌟因为我的图片都是网上随便找的,这可能是导致匹配度不高的原因,大家可以用家里人的照片试试。

❗️❗️❗️这里要注意:训练的图像和被检测的图像的尺寸相同,识别器要求所有训练图像具有相同的尺寸,如果尺寸不同,就需要在训练之前将它们调整为统一的尺寸。后面的Fisherfaces人脸识别器也是一样的。

3.2 Fisherfaces人脸识别器

Fisherfaces 是由 Ronald Fisher最早提出的,这也是Fisherfaces名字的由来。Fisherfaces通过LDA(线性判别分析技术)方法将人脸数据转换到另外一个空间维度做投影计算,最后根据不同人脸数据的投影距离判断其相似度。

开发者需要通过以下方法完成人脸识别操作。

  • 通过cv2.face.FisherFaceRecognizer_create()方法创建Fisherfaces人脸识别器。
face.FisherFaceRecognizer_create(num_components,threshold)参数说明:num_components:可选参数,通过Fisherface方法进行判断分析时保留的分量个数,建议使用默认值。threshold:可选参数,人脸识别时使用的阈值,建议使用默认值。
返回值说明:recognizer:创建的Fisherfaces人脸识别器对象。
  • 创建识别器对象后,需通过对象的train()方法训练识别器。建议每个人都给出2幅以上的人脸图像作为训练样本。
  • 训练识别器后可以通过识别器的predict()方法识别人脸,该方法对比样本的特征,给出最相近的结果和评分。这两步和上一个一样,就不赘述了。

那我们继续我们的🍐吧!

import cv2
import numpy as npphotos = list()  # 样本图像列表
lables = list()  # 标签列表
target_size = (200, 200)  # 设置统一的图像尺寸photos.append(cv2.resize(cv2.imread("face\\bei_1.png", 0),target_size))  # 记录第1张人脸图像
lables.append(0)  # 第1张图像对应的标签
photos.append(cv2.resize(cv2.imread("face\\bei_2.png", 0),target_size))  # 记录第2张人脸图像
lables.append(0)  # 第2张图像对应的标签
photos.append(cv2.resize(cv2.imread("face\\bei_3.png", 0),target_size))  # 记录第3张人脸图像
lables.append(0)  # 第3张图像对应的标签photos.append(cv2.resize(cv2.imread("face\\yangmi_1.png", 0),target_size))  # 记录第4张人脸图像
lables.append(1)  # 第4张图像对应的标签
photos.append(cv2.resize(cv2.imread("face\\yangmi_2.png", 0),target_size))  # 记录第5张人脸图像
lables.append(1)  # 第5张图像对应的标签
photos.append(cv2.resize(cv2.imread("face\\yangmi_3.png", 0),target_size))  # 记录第6张人脸图像
lables.append(1)  # 第6张图像对应的标签names = {"0": "bei", "1": "yangmi"}  # 标签对应的名称字典recognizer = cv2.face.FisherFaceRecognizer_create()  # 创建特征脸识别器
recognizer.train(photos, np.array(lables))  # 识别器开始训练i = cv2.imread("face\\yangmi_test.png", 0)  # 待识别的人脸图像
i = cv2.resize(i,target_size)
label, confidence = recognizer.predict(i)  # 识别器开始分析人脸图像
print("confidence = " + str(confidence))  # 打印评分
print(names[str(label)])  # 数组字典里标签对应的名字
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

运行结果如下:
在这里插入图片描述

🌟同样的训练内容和测试内容,Fisherfaces人脸识别器似乎表现更好。

3.3 Local Binary Pattern Histogram人脸识别器

Local Binary Pattern Histogram简称LBPH,即局部二进制模式直方图,这是一种基于局部二进制模式算法,这种算法善于捕获局部纹理特征

开发者需要通过以下方法来完成人脸识别操作。

  • 通过cv2.face. LBPHFaceRecognizer_create()方法创建LBPH人脸识别器。
recognizer = cv2.face.LBPHFaceRecognizer_create(radius,neighbors, grid_x, grid_y, threshold)参数说明:radius:可选参数,圆形局部二进制模式的半径,建议使用默认值。neighbors:可选参数,圆形局部二进制模式的采样点数目,建议使用默认值。
返回值说明:grid_x:可选参数,水平方向上的单元格数,建议使用默认值。grid_y:可选参数,垂直方向上的单元格数,建议使用默认值。threshold:可选参数,人脸识别时使用的阈值,建议使用默认值。

后面两步和上面一样的啦,就不赘述了,但是要注意,这里的匹配度只要小于50就算匹配度较高了。

直接给大家最喜欢的🍐:

import cv2
import numpy as npphotos = list()  # 样本图像列表
lables = list()  # 标签列表
target_size = (200, 200)  # 设置统一的图像尺寸photos.append(cv2.resize(cv2.imread("face\\bei_1.png", 0),target_size))  # 记录第1张人脸图像
lables.append(0)  # 第1张图像对应的标签
photos.append(cv2.resize(cv2.imread("face\\bei_2.png", 0),target_size))  # 记录第2张人脸图像
lables.append(0)  # 第2张图像对应的标签
photos.append(cv2.resize(cv2.imread("face\\bei_3.png", 0),target_size))  # 记录第3张人脸图像
lables.append(0)  # 第3张图像对应的标签photos.append(cv2.resize(cv2.imread("face\\yangmi_1.png", 0),target_size))  # 记录第4张人脸图像
lables.append(1)  # 第4张图像对应的标签
photos.append(cv2.resize(cv2.imread("face\\yangmi_2.png", 0),target_size))  # 记录第5张人脸图像
lables.append(1)  # 第5张图像对应的标签
photos.append(cv2.resize(cv2.imread("face\\yangmi_3.png", 0),target_size))  # 记录第6张人脸图像
lables.append(1)  # 第6张图像对应的标签names = {"0": "bei", "1": "yangmi"}  # 标签对应的名称字典recognizer = cv2.face.LBPHFaceRecognizer_create()  # 创建特征脸识别器
recognizer.train(photos, np.array(lables))  # 识别器开始训练i = cv2.imread("face\\yangmi_test.png", 0)  # 待识别的人脸图像
i = cv2.resize(i,target_size)
label, confidence = recognizer.predict(i)  # 识别器开始分析人脸图像
print("confidence = " + str(confidence))  # 打印评分
print(names[str(label)])  # 数组字典里标签对应的名字
cv2.waitKey()  # 按下任何键盘按键后
cv2.destroyAllWindows()  # 释放所有窗体

运行结果如下:
在这里插入图片描述

🌟根据结果我们可以发现:识别器可以识别出杨幂,但是匹配度依旧不高,可能还是图像质量不好和数量不多的原因导致的。

小结

人脸检测和人脸识别是相辅相成的,检测到了人脸才可以识别人脸。三种人脸识别器也是非常重要,我们需要熟练掌握实现方法和原理!!!

大家如果听到了这里,那么恭喜,你已经成功入门opencv啦!!!!激动之余别忘记复习一下内容,明天我们将开始实战,做一个小型的人脸识别系统!!!加油吧!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/51612.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring 常用的三种拦截器详解

前言 在开发过程中&#xff0c;我们常常使用到拦截器来处理一些逻辑。最常用的三种拦截器分别是 AOP、 Interceptor 、 Filter&#xff0c;但其实很多人并不知道什么时候用AOP&#xff0c;什么时候用Interceptor&#xff0c;什么时候用Filter&#xff0c;也不知道其拦截顺序&am…

spring —— 事务管理器

事务管理主要针对数据源进行操作&#xff1a;在数据库方面&#xff0c;通过 TransactionManager 事务管理器进行管理&#xff0c;表明一旦出现错误&#xff0c;该数据源的所有数据全部复原。那么数据库如何判断是否发生了错误呢&#xff1f;这就需要在代码方面&#xff0c;通过…

抖音直播弹幕数据逆向:websocket和JS注入

&#x1f50d; 思路与步骤详解 &#x1f575;️‍♂️ 思路介绍 首先&#xff0c;我们通过抓包工具进入的直播间&#xff0c;捕获其网络通信数据&#xff0c;重点关注WebSocket连接。发现直播弹幕数据通过WebSocket传输&#xff0c;这种方式比传统的HTTP更适合实时数据的传输。…

前端基于 axios 实现批量任务调度管理器 demo

一、背景介绍 这是一个基于 axios 实现的批量任务调度管理器的 demo。它使用了axios、promise 等多种技术和原理来实现批量处理多个异步请求&#xff0c;并确保所有请求都能正确处理并报告其状态。 假设有一个场景&#xff1a;有一个任务列表&#xff0c;有单个任务的处理功能…

【Qt】QLCDNumberQProgressBarQCalendarWidget

目录 QLCDNumber 倒计时小程序 相关属性 QProgressBar 进度条小程序 相关设置 QLCDNumber QLCDNumber是Qt框架中用于显示数字或计数值的小部件。通常用于显示整数值&#xff0c;例如时钟、计时器、计数器等 常用属性 属性说明intValueQLCDNumber显示的初始值(int类型)va…

企业版邮箱适用哪些企业

企业邮箱适合哪些企业呢&#xff1f;企业版邮箱为企业提供安全、稳定、集成的邮件服务&#xff0c;支持初创、中小、大型企业及特定行业需求。ZohoMail作为优质提供商&#xff0c;提供多层安全措施、移动访问、集成能力及定制化服务&#xff0c;满足不同规模企业需求。 一、企…

2023年系统架构设计师考试总结

原文链接&#xff1a;https://www.cnblogs.com/zhaotianff/p/17812187.html 上周六参加了2023年系统架构设计师考试&#xff0c;这次考试与以前有点区别&#xff0c;是第一次采用电子化考试&#xff0c;也是教材改版后的第一次考试。 说说考前准备&#xff1a;为了准备这次考试…

基于微信小程序的校园警务系统/校园安全管理系统/校园出入管理系统

摘要 伴随着社会以及科学技术的发展&#xff0c;小程序已经渗透在人们的身边&#xff0c;小程序慢慢的变成了人们的生活必不可少的一部分&#xff0c;紧接着网络飞速的发展&#xff0c;小程序这一名词已不陌生&#xff0c;越来越多的学校机构等都会定制一款属于自己个性化的小程…

《通讯世界》是什么级别的期刊?是正规期刊吗?能评职称吗?

问题解答 问&#xff1a;《通讯世界》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的第一批认定学术期刊。 问&#xff1a;《通讯世界》级别&#xff1f; 答&#xff1a;国家级。主管单位&#xff1a;科学技术部 主办单位&#xff1a;中国科学技…

关于虚拟机在桥接模式下连接网络问题的记录

2024年7月28日03:49:19 环境&#xff1a;ubuntu22.04 desktop 虚拟机 问题&#xff1a;使用wget下载nginx安装包时出现问题&#xff0c;443端口持续无连接成功回复。 随后在确定配置ip无问题&#xff0c;检查了其正常访问互联网&#xff0c;随后试图ping niginx网站&#xff…

基于OSS前端直传的分片上传以及断点续传

一、大文件分片上传 原型 大文件如果直接上传的话由于nginx的限制会导致响应500报错&#xff0c;或者响应时间过长导致响应超时 并且大文件上传有如下缺点 上传时间长: 对于大文件&#xff0c;直接上传可能需要较长时间&#xff0c;特别是在网络速度较慢或不稳定的情况下。这…

ChatGPT秘籍:如何用AI阅读文献,提升你的学术效率

在当今信息泛滥的时代&#xff0c;迅速高效地搜集与处理信息显得尤为关键。本文将聚焦于如何利用ChatGPT高效阅读文献与文档&#xff0c;并提供详尽的技巧、心得以及实用的指令和插件解析&#xff0c;助你充分发挥ChatGPT的潜能。无论你是学生、科研人员还是行业从业者&#xf…

雪花算法的一些问题解析

前言 最近做项目&#xff0c;有些老旧项目&#xff0c;需要生成分布式唯一ID&#xff0c;不允许重复&#xff0c;此时如果要对其他中间件和数据库依赖小&#xff0c;那么就需要一套固定的ID生成规则&#xff0c;雪花算法就正当合适&#xff0c;当时Twitter就是用来存储数据库I…

JSP基础语法与指令

任何语言都有自己的语法&#xff0c;在java中有&#xff0c;JSP作为java技术的一种应用&#xff0c;它拥有一些自己扩充的语法(了解知道即可&#xff01;&#xff01;&#xff01;)&#xff0c; Java所有语法都支持&#xff01; JSP表达式 <html><head><title…

【Redis 初阶】初识 Redis

一、了解 Redis Redis 官网&#xff1a;Redis - The Real-time Data Platform Redis 是一种基于键值对&#xff08;key-value&#xff09;的 NoSQL 数据库。与很多键值对数据库不同的是&#xff0c;Redis 中的 key 都是 string&#xff08;字符串&#xff09;&#xff0c;值&a…

计算机毕业设计LSTM+Tensorflow股票分析预测 基金分析预测 股票爬虫 大数据毕业设计 深度学习 机器学习 数据可视化 人工智能

|-- 项目 |-- db.sqlite3 数据库相关 重要 想看数据&#xff0c;可以用navicat打开 |-- requirements.txt 项目依赖库&#xff0c;可以理解为部分技术栈之类的 |-- data 原始数据文件 |-- data 每个股票的模型保存位置 |-- app 主要代码文件夹 | |-- mod…

汽车辐射大?技术来救它:整车辐射抗扰发射天线仿真建模及性能预测

摘要 针对车辆电磁辐射抗扰度测试条件要求高、预测难度大的问题&#xff0c;通过仿真软件建立电磁抗扰度测试发射天线&#xff08;简称抗扰发射天线&#xff09;模型及无车情况下的电磁抗扰试验场强环境&#xff0c;为整车电磁辐射抗扰性能的预测搭建了一个仿真平台。 验证试验…

纹理映射学习笔记

概述 本文的纹理映射将三维曲面与二维的纹理建立对应关系。 曲面参数表达&#xff1a; x x ( s , t ) , y y ( s , t ) , z z ( s , t ) x x(s,t), y y(s,t), zz(s,t) xx(s,t),yy(s,t),zz(s,t) 即给定纹理坐标(s,t),我们能可以计算出曲面坐标(x,y,z) 映射 考虑由参数…

渲染技术如何帮助设计内容实现从平面到立体的转换

随着数字艺术和视觉特效的飞速发展&#xff0c;三维建模与渲染技术在影视、游戏、广告、工业设计、建筑可视化等多个领域展现出了其不可或缺的重要性。这一技术不仅实现了从平面到立体的跨越&#xff0c;还极大地丰富了视觉表达的层次感和真实感。 三维建模&#xff1a;构建虚…