Advertisement

人脸检测实战终极:使用 OpenCV 和 Python 进行人脸对齐

阅读量:

import the necessary packages

from imutils.face_utils.helpers import FACIAL_LANDMARKS_68_IDXS

from imutils.face_utils.helpers import FACIAL_LANDMARKS_5_IDXS

from imutils.face_utils.helpers import shape_to_np

import numpy as np

import cv2

class FaceAligner:

def init(self, predictor, desiredLeftEye=(0.35, 0.35),

desiredFaceWidth=256, desiredFaceHeight=None):

store the facial landmark predictor, desired output left

eye position, and desired output face width + height

self.predictor = predictor

self.desiredLeftEye = desiredLeftEye

self.desiredFaceWidth = desiredFaceWidth

self.desiredFaceHeight = desiredFaceHeight

if the desired face height is None, set it to be the

desired face width (normal behavior)

if self.desiredFaceHeight is None:

self.desiredFaceHeight = self.desiredFaceWidth

导入必要的包

定义的构造函数开始我们的 FaceAligner 类。

我们的构造函数有 4 个参数:

predictor :面部标志性预测器模型。

requiredLeftEye 作为一个可选参数,在图形界面中被设置为一个(x, y)坐标元组,默认情况下会将其显示为初始值。该元组用于指定所需输出左眼位置,在大多数情况下(通常在20-40%范围内),这些百分比会被用来控制对齐后的人脸可见度。具体使用的百分比将根据应用程序的不同而有所变化。当使用20%时,默认会提供一个被放大的脸部视图;而对于较大的数值,则会使脸部显得更加紧凑。

requiredFaceWidth :另一个可选参数,在像素单位下定义我们想要的人脸。我们将此值设为256像素作为默认设置。

requiredFaceHeight :最后一个可选参数, a value in terms of pixels that determines the face height we require.

接下来,请我们确定是要一张方型的人脸图像还是长方形的图像。
首先,请检查requiredFaceHeight是否设定了默认值。
如果没有,默认情况下我们将它设置为desiredFaceWidth。
这意味着面部呈现方型。
另一种方法则是根据需要分别指定desiredFaceWidth和desiredFaceHeight以获取所需范围内的长方形区域。

我们现在成功搭建了我们的 FaceAligner 对象,并且随后我们决定并实现了对齐面部特征的功能模块。

这个函数有点长,所以我把它分成了 5 个代码块,让它更容易理解:

def align(self, image, gray, rect):

convert the landmark (x, y)-coordinates to a NumPy array

shape = self.predictor(gray, rect)

shape = shape_to_np(shape)

extract the left and right eye (x, y)-coordinates

(lStart, lEnd) = FACIAL_LANDMARKS_IDXS[“left_eye”]

(rStart, rEnd) = FACIAL_LANDMARKS_IDXS[“right_eye”]

leftEyePts = shape[lStart:lEnd]

rightEyePts = shape[rStart:rEnd]

定义了 align 函数,它接受三个参数:

image : RGB 输入图像。

gray :灰度输入图像。

rect :由 dlib 的 HOG 人脸检测器生成的边界框矩形。

应用 dlib 的面部标志预测器并将标志转换为 NumPy 格式的 (x, y) 坐标。

接下来,在 helpers.py 文件中使用 FACIAL_LANDMARK_IDXS 字典提取 left_eye 和 right_eye 区域的 2 元组值,并将这些值存储在与左/右眼相关的起始和结束索引位置。

提取leftEyePts 和 rightEyePts 。

接下来,计算每只眼睛的中心以及眼睛质心之间的角度。

这个角度是对齐我们的图像的关键组成部分。

眼睛之间的绿线夹角,如下图所示,是我们比较关心的。

image-20211212213556697

接下来是角度计算:

compute the center of mass for each eye

leftEyeCenter = leftEyePts.mean(axis=0).astype(“int”)

rightEyeCenter = rightEyePts.mean(axis=0).astype(“int”)

compute the angle between the eye centroids

dY = rightEyeCenter[1] - leftEyeCenter[1]

dX = rightEyeCenter[0] - leftEyeCenter[0]

angle = np.degrees(np.arctan2(dY, dX)) - 180

分别通过平均每只眼睛的所有 (x, y) 点来计算每只眼睛的质心,也称为质心。

给定眼睛中心后方某点位置时,在坐标系中我们可以测量(x, y)坐标的差异值,并通过反正切函数来确定两眼之间的旋转角度的具体数值。

这个角度将允许我们校正旋转。

以确定角度为前提,我们首先计算沿 y 轴方向的增量 dY 。 基于第 38 行中 rightEyeCenter 和 leftEyeCenter 的差异进行计算。

类似地,我们计算 dX ,即第 39 行 x 方向的增量。

在随后的过程中确定面部旋转的角位移。我们使用带有参数dY和dX的NumPy库中的arctan2函数工具,并将计算结果从弧度转换为角度。随后将其结果减去180度以确定最终的角位移。

在以下代码块中,我们估算所需的右侧眼睛的坐标(基于左眼位置作为函数)同时估算新生成图像的比例。

compute the desired right eye x-coordinate based on the

desired x-coordinate of the left eye

desiredRightEyeX = 1.0 - self.desiredLeftEye[0]

determine the scale of the new resulting image by taking

the ratio of the distance between eyes in the current

image to the ratio of distance between eyes in the

desired image

dist = np.sqrt((dX ** 2) + (dY ** 2))

desiredDist = (desiredRightEyeX - self.desiredLeftEye[0])

desiredDist *= self.desiredFaceWidth

scale = desiredDist / dist

为了所求的右眼x值来依据所需的左眼x坐标进行计算,在程序逻辑中将通过从1.0中减去self.desiredLeftEye[0]来确定所需RightEyeX值以确保左右边缘的位置相匹配。这是因为所求的LeftEyeX坐标与图像左边界的距离与对应的RightEyeX坐标与图像右边界的距离是相同的。

然后可以通过在当前图片中计算两者的比例关系来确定在目标图片中的相应位置。

首先,计算欧几里得距离比 dist 。

接下来,使用左右眼 x 值之间的差异,计算所需的距离,desiredDist。

在第52行将所需距离按面宽的比例进行缩放。其本质是将眼睛到视点的距离按所需宽度进行调整。

最后,比例是通过将 desiredDist 除以我们之前计算的 dist 来计算的。

现在获得了旋转角度和缩放比例参数,在执行仿射变换计算之前必须先完成一系列操作。这一系列操作主要包括两个主要部分:一是确定人眼连线的中点位置;二是构建并调整旋转变换矩阵及其平移分量。

compute center (x, y)-coordinates (i.e., the median point)

between the two eyes in the input image

eyesCenter = (int((leftEyeCenter[0] + rightEyeCenter[0]) // 2),

int((leftEyeCenter[1] + rightEyeCenter[1]) // 2))

grab the rotation matrix for rotating and scaling the face

M = cv2.getRotationMatrix2D(eyesCenter, angle, scale)

update the translation component of the matrix

tX = self.desiredFaceWidth * 0.5

tY = self.desiredFaceHeight * self.desiredLeftEye[1]

M[0, 2] += (tX - eyesCenter[0])

M[1, 2] += (tY - eyesCenter[1])

确定 eyeCenter ,即左右眼之间的中点。这一中点将被用于我们的旋转矩阵计算。该定位点位于鼻子顶端的位置上:它是我们将面部进行旋转的关键基准点:

image-20211212214237870

为了获取旋转矩阵 M 的信息,我们调用 OpenCV 库中的 cv2.getRotationMatrix2D 函数,并指定 eyeCenter 点、旋转角度以及缩放比例作为参数输入。这些参数在之前的步骤中已经完成计算工作,请根据具体需求进行处理和返回结果。

cv2.getRotationMatrix2D 的参数说明如下:

eyeCenter :眼睛之间的中点是我们将围绕面部旋转的点。

angle:我们将面部旋转到的角度,以确保眼睛位于同一水平线上。

scale :我们将放大或缩小图像的百分比,确保图像缩放到所需的大小。

现在必须更新矩阵的平移分量,使人脸在仿射变换后仍然在图像中。

取所需面宽的一半并将值存储为 tX,即 x 方向的平移。

为了求取tY值,在y轴方向上的平移量可以通过将面部高度与所需左眼y坐标相乘来确定。

自我介绍下啦!我是2013年从上海交通大学毕业后的小白。之前在一家小公司工作过一段时间后,又曾在华为、OPPO等大公司实习过。自2018年入职阿里科技至今

意识到相当一部分Python工程师在寻求技能提升时倾向于自主学习或参加培训课程。然而高昂的培训费用给诸多学员带来了不小的压力。自学往往缺乏系统性而导致效率低下且时间漫长。遇到技术瓶颈难以突破!

为满足那些希望系统学习Python编程技能却又不知从何处着手的学习者的实际需求,《2024年Python开发全套学习资料》应运而生。其 primary purpose is to provide a comprehensive and structured learning pathway for those eager to master Python programming but lack a clear starting point. 此外, 这份学习资料不仅能够帮助他们快速掌握必要的技能, 还能有效缓解他们的学习压力.

img
img

该平台不仅提供针对初学者提供的零基础学习资源,
还为有丰富开发经验者设计的专业级深入课程,
其内容覆盖了Python核心知识点约95%,
系统性地构建了一个完整的知识体系!

因为文件较大,在此处仅对目录大纲进行截图展示;其中每个节点均涵盖大厂面经、学习笔记、源码讲义等具体内容;此外还包括实战项目及讲解视频,并后续将持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注Python)

img

如果你也洞察到了 Python 的发展潜力,并打算深入学习 Python,在这里我们为您精心准备了一份详实的 免费 学习 资源包。我们诚挚邀请大家参与进来,并将全面深入分析 Python 在兼职机会及就业市场前景方面的各种机遇与趋势。

一、Python所有方向的学习路线

在Python领域中构建学习路线时,在于对核心知识点进行系统归纳和整理,并帮助构建各个领域相关的知识点体系。其主要作用在于通过这些知识点的学习资源推荐列表来辅助学习者系统地掌握相关技术。

二、学习软件

想要做好某件事,首先要掌握好工具。这里有多种常用开发工具,帮助大家节省宝贵的时间。

三、全套PDF电子书

书籍的主要优势在于其权威性和系统性设计。在最初的阶段, 你可以通过观看教学视频或聆听专业人士的讲解来获取知识的主要方式, 这种途径能够帮助你快速了解基础概念和技术要点, 但仅限于表面理解, 并不能保证深入掌握相关知识。等到你完成了学习内容后, 你会发现对所学内容已经形成了较为全面的理解, 此时建议大家在完成学习后还是要深入阅读权威技术书籍

四、入门学习视频

在观看视频学习的过程中, 我们不能仅仅靠看和想, 而是要动手实践. 科学的学习方法是通过理解后再加以应用, 这时候进行实践练习就非常合适.

四、实战案例

关于光学理论的知识点实用性不大;如果此时能结合实际案例进行深入研究会更有帮助。

五、面试资料

掌握Python编程语言的主要用途在于获得一份优质职位。这些面试题来源于阿里、腾讯、字节等一线互联网大厂的最新发布,并且其中部分题目由阿里资深专家进行了权威解答。完成一套完整的练习题集后,相信每一位读者都能够顺利获得理想中的职位机会。

成为一名熟练的Python程序员可能需要多年的积累。
但是一旦打下了扎实的基础,则只需几周即可。
通过遵循我提供的学习路线和参考资料,并采取积极主动的学习态度进行实践练习,则有很高的概率能够取得显著成效。
愿您在这条编程之路上收获满满!未来可期!

到实际当中去,这时候可以搞点实战案例来学习。

五、面试资料

我们学习Python主要是为了获得高薪职位的机会。这些试题源自阿里、腾讯及字节等一线互联网企业的最新考卷,并由经验丰富的资深专家提供权威解析。做完这套试题的人普遍都能获得理想中的工作机会。

成为一名Python程序员专家也许需要投入大量时间。
然而, 打好扎实基础仅需几周时间。
如果你遵循我的学习路线和资料主动投入实践练习中, 你就有很大概率取得成功。
祝愿你在编程世界中取得成功!

全部评论 (0)

还没有任何评论哟~