目录
检测面部关键点是一个非常具有挑战性的问题。面部特征因人而异,即使是单个人,由于 3D 姿势、大小、位置、视角和照明条件,也会有很大的变化。计算机视觉研究在解决这些困难方面取得了长足的进步,但仍有许多改进的机会。
面部识别
面部识别扫描系统还使用计算机视觉技术来识别个人以用于安全目的。面部识别中最常见的计算机视觉示例是用于保护智能手机。面部识别和生物识别技术的更高级用途包括使用个人独特生理特征来验证其身份的住宅或商业安全系统。深度学习算法可以识别一个人指纹中的独特模式,并使用它们来控制对高安全性区域的访问,例如高度机密的工作场所,例如核电站、研究实验室和银行金库。
基于 Haar 特征的人脸特征检测
使用基于 Haar 特征的级联分类器进行对象检测是 Paul Viola 和 Michael Jones 在 2001 年的论文“Rapid Object Detection using a Boosted Cascade of Simple Features”中提出的一种有效的对象检测方法。它是一种基于机器学习的方法,其中一个级联函数是从大量的正负图像中训练出来的。然后它用于检测其他图像中的对象。
最初,该算法需要大量的正图像(人脸图像)和负图像(没有人脸的图像)来训练分类器。然后我们需要从中提取特征。为此,使用了下图中显示的 Haar 特征。它们就像我们的卷积核。每个特征都是通过从黑色矩形下的像素总和中减去白色矩形下的像素总和而获得的单个值。
对于每个特征计算,我们需要找到白色和黑色矩形下的像素之和。为了解决这个问题,他们引入了积分图像。无论您的图像多大,它都会将给定像素的计算减少为仅涉及四个像素的操作。
为此,我们将每个特征应用于所有训练图像。对于每个特征,它会找到将人脸分类为正面和负面的最佳阈值。甚至 200 个特征也能以 95% 的准确率提供检测。他们的最终设置有大约 6000 个功能。所以现在你拍一张照片。获取每个 24x24 窗口。对其应用 6000 个特征。检查它是否是一张脸。
在一幅图像中,大部分图像是非人脸区域。所以最好有一个简单的方法来检查窗口是否不是人脸区域。如果不是,请一次性丢弃,不要再次处理。为此,他们引入了Cascade of Classifiers的概念。不是在一个窗口上应用所有 6000 个特征,而是将这些特征分组到分类器的不同阶段并一个一个地应用。作者的检测器有 38 个阶段的 6000 多个特征,前五个阶段有 1、10、25、25 和 50 个特征。
每个预测的关键点由像素索引空间中的 (x,y) 实值对指定。有15个关键点,分别代表脸部的不同元素。输入图像在数据文件的最后一个字段中给出,由像素列表(按行排序)组成,为 (0,255) 中的整数。图像为 96x96 像素。
让我们构建应用程序
第 1 步:获取输入视频
有两种输入视频的方法:
1. 实时网络摄像头视频。
rgb = cv2.VideoCapture(0)
2. 预先录制的视频文件。
rgb = cv2.VideoCapture("Input.mp4")
第 2 步:输入源的预处理
现在我们需要对视频文件进行预处理并将其转换为更适合面部检测的形式,即我们需要从视频中逐帧提取帧,因为模型将图像作为其输入。我们还需要将帧转换为灰度,因为模型在灰度图像上效果更好。
_, fr = rgb.read()
gray = cv2.cvtColor(fr, cv2.COLOR_BGR2GRAY)
第 3 步:人脸检测
在我们检测面部特征之前,我们需要检测包含面部的图像/帧部分,因为如前所述,haar 级联分类器应用数百个特征来检测面部特征的位置。为了节省时间和处理能力,我们只给出包含人脸的那部分图像。detectMultiScale() 为我们提供x,y坐标以及宽度和高度作为包含面部的图像的矩形部分的w,h 。
facec = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
faces = facec.detectMultiScale(gray, 1.3, 5)
第 4 步:特征检测。
现在我们将人脸传递给模型以检测面部特征,并将所有 15 个检测到的特征及其各自的坐标与合适的标签(例如 ['left_eye_center_x', 'left_eye_center_y'])进行映射。
pred_dict 是模型预测的面部特征的坐标列表。
pred, pred_dict = cnn.predict_points(roi[np.newaxis,:,:,np.newaxis])
pred, pred_dict = cnn.scale_prediction((x, fc.shape[1]+x), (y, fc.shape [0]+y))
第 5 步:应用过滤器。
现在我们将帧和特征坐标传递给 apply_filter() 方法,该方法将过滤图像放置在适当的位置。
fr = apply_filter(fr, pred_dict)
第 6 步:编写输出文件
要写入视频文件,我们建议使用 cv2 库。对于这个应用程序,我们使用了带有 vp80 编码的 WebM 格式,这最终有助于在网页上流畅地运行视频文件。
fps = int(video_capture.get(cv2.CAP_PROP_FPS)
width = int(video_capture.get(3))
height = int(video_capture.get(4))
fourcc = cv2.VideoWriter_fourcc(*'vp80')
PATH = '/Users /prate/static/demo.webm'
out = cv2.VideoWriter(PATH,fourcc, fps, (width,height))
我们必须在对它们应用过滤器后立即在输出视频中写入帧,以便获得序列化输出。
for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
out.write(frame)
输出
视频文件的输出
结论
此应用程序专注于预测以视频形式或网络摄像头实时显示在输入中的面部面部特征,此过程称为面部特征识别。在这个应用程序中,我们可以使用 Haar Cascade 预测的面部特征坐标轻松地在面部应用各种过滤器。