人脸对齐(三)--AAM算法

原文:

http://blog.csdn.net/colourfulcloud/article/details/9774017

AAM(Active Appearance Model)主动外观模型主要分为两个阶段,模型建立阶段和模型匹配阶段。其中模型建立阶段包括了对训练样本分别建立形状模型(Shape Model)和纹理模型(Texture Model),然后将两个模型进行结合,形成AAM模型。模型匹配阶段是指在视频序列中将已建立好的AAM模型在当前帧图像中寻找最匹配的目标的过程。

 

1样本选取与标定

1.1样本采集

要建立AAM模型,就需要采集目标的样本,建立样本库。一般来说,样本越多,AAM模型的效果越好,但建立模型的时间越长;样本的差异性越大,AAM模型所能处理的人脸的范围越广,但准确性会相对下降,因而需要根据经验值选取所要采用的样本数。

1.2样本取点

在采集了样本后,我们得到的只是一系列包括了我们所需要的目标信息的图像。而我们要建立关于人脸的AAM模型,就需要把目标从样本中提取出来而去除背景等的影响。而我们提取目标的方法就是在样本中手动把人脸的轮廓标定出来。

1.3样本数据处理

在手动标定了样本中的点后,通过程序把样本的点的位置{x,y}保存为向量的形式m1={x1,y1,x2,y2,x3,y3,……,x68,y68}。于是从n个样本中我们得到了m1到mn这n个向量作为输入数据。

 

2形状模型(Shape Model)

对输入数据我们首先建立活动形状模型ASM。建立ASM模型包括Procrustes变换和PCA降维两个步骤。

2.1 Procrustes变换

要建立ASM模型,需要对样本的人脸进行归一化。由于每个样本的拍摄角度,人脸角度,人脸远近等因素,样本中的人脸的位置,大小均不相同。Procrustes变换的主要思想是将观测对象的中心平移到原点,然后将对象的大小伸缩到固定大小并将对象旋转到正确位置。

每一个样本的对象都有四个参数,重心的x坐标和y坐标,对象大小和对象旋转的角度。对于每两个样本,首先将两个样本的对象的重点都移动到同一位置,然后将两个样本的对象通过放大缩小操作伸缩到一样大小,最后通过两个对象相应的特征点的位置来计算出两个对象的旋转角度的差别,然后旋转对象,使相应点的距离的平方和最小,从而使使两个对象的角度一致。

对样本的对象两两进行Procrustes变换,最终所有对象都移动到固定的初始位置,大小、角度也一致。然后对转换后的所有样本求平均,就得到了一个平均的形状模型。

2.2 PCA降维

在得到平均形状模型后,我们得到了68*2*n个参数,改变这些参数就可以在平均形状模型上进行改变,因而这些参数代表了平均形状模型的特征。

但得到的这些参数是多维的,存在着大量的数据冗余,因而需要利用PCA进行降维。

PCA(Principal component analysis)即主元分析,是一种对数据进行分析的技术,它可以有效的找出数据中最“主要”的元素和结构,去除噪音和冗余,将原有的复杂数据降维,揭示隐藏在复杂数据背后的简单结构。它的优点是简单,而且无参数限制,可以方便的应用于各个场合。

从线形代数的角度来看,PCA的目标就是使用另一组基去重新描述得到的数据空间。而新的基要能尽量揭示原有的数据间的关系,而这个基即最重要的“主元”。PCA的目标就是找到这样的“主元”,最大程度的去除冗余和噪音的干扰。

PCA的流程如下:

(1) 采集数据形成m*n的矩阵。m为观测数据的维数,n为观测样本的个数。

(2) 在每个观测变量(矩阵行向量)上减去该观测变量的平均值得到矩阵X。

(3) 对XXT进行特征值分解(SVD分解),取特征向量组成P的行向量以及对应的特征根。

最终我们得到68*2*n个按照权值从大到小排列的特征量,通过设定阀值选取前p(p<<68*2*n)个特征量,也就是最能代表形状模型的p个特征,来作为形状模型的参数。因而我们可以通过调整这p个特征量方便地改变形状模型。

 

3纹理模型(Texture Model)

纹理模型(Texture Model)描述了目标的纹理特征。纹理模型的输入数据和形状模型一样,在这里可以看做是n张图片,每张图片上有一个点集。

3.1 Delaunay三角划分

Delaunay三角划分将空间点连接为三角形,使得所有三角形中最小的角最大的一个技术。三角划分的要点是任何三角形的外接圆都不包括任何其他顶点,即外接圆性质。

一个实现Delaunay三角划分的算法如下:

(1)  添加外部三角形,并从它的一个顶点(在这里会产生一个确定的外部起点)处开始;

(2)  加入一个内部点;在三角形的外接圆内搜索该点,去掉包含该点的三角划分;

(3)  重新构造三角图,在刚刚去掉的三角形外接圆内包括新的点;

(4)  返回第二步,直到没有新的点加入。

Delaunay三角划分使每一张图上的点集划分为一系列的三角形,如上图,为下一步进行三角映射作准备。

 

3.2三角映射

使用Delaunay三角划分后,每一个样本都可以划分为一系列三角形,而不同样本间这些三角形是对应的。要得到平均纹理模型,就需要把样本中的目标的纹理通过分片仿射投影到同一个样本上,而这种分片仿射就是三角映射。

我们先设定一个样本为平均脸,既然在样本中的点与平均脸的所有三角形都是一一对应的,我们就可以根据三角形中每一点的位置计算其对应平均脸中某一点的位置,然后把该点的像素值复制到平均脸对应点的位置上。在这里因为三角形的形状不同,因而肯定需要舍弃一部分点,也要填补一部分的点,可以根据邻近的像素点决定判决准则。最终每一个样本都可以转化到平均脸上,然后把这n个脸求平均,就得到了平均纹理模型。

3.3 PCA降维

在求出平均纹理模型后,我们同样得到了很多可以控制这个模型的参数,因而我们同样需要对这些结果进行PCA降维,从而提取出对平均纹理模型影响最大的前q个参数。我们可以通过调整这q个参数改变纹理模型。

 

4组合模型(Combine Model)

在得到形状模型和纹理模型后,我们就可以对这两个模型进行加权组合,得到组合模型,也就是AAM模型。同时我们也得到了p+q个参数,这些参数就是用来改变AAM模型的特征的。虽然前面进行过两次PCA降维使参数维数大大降低,但两个模型结合后,某些参数还是会受到别的参数的影响,因而我们需要再一次进行PCA降维,最终得到r个参数(r<p+q),我们可以调整这r个参数,利用AAM模型变化出形态各异的人脸。

 

5搜索模型(Search Model)

AAM模型建立以后,我们就可以实际在视频序列中跟踪人脸。初始时记AAM模型的r个参数为向量 ,然后对输入的图像,首先假设某个位置有人脸,得到人脸的实际参数c,然后我们通过不断地调整 使c和 之间的距离最小,若这个最小值小于某个阀值,就可以认为当前位置出现人脸,我们就能够在视频中检测到了人脸。

当然,若在每一帧都遍历图像寻找目标显然效率过低,因而在后续的帧中,算法都只从上一帧的领域开始搜索目标,若搜索失败,则再扩大搜索范围,直至遍历整幅图像,这种算法可以大大提高算法的速度。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
人脸对齐算法是一种常见的人脸识别前置步骤,可以提高人脸识别的准确率。在 OpenCV 4.6 中,可以使用 dlib 库提供的人脸检测器和关键点检测器来实现人脸对齐。以下是 C++ 代码实现人脸对齐的示例: ```c++ #include <opencv2/opencv.hpp> #include <dlib/opencv.h> #include <dlib/image_processing.h> #include <dlib/image_processing/frontal_face_detector.h> #include <dlib/image_processing/shape_predictor.h> using namespace cv; using namespace dlib; int main() { // 加载人脸检测器和关键点检测器 frontal_face_detector detector = get_frontal_face_detector(); shape_predictor predictor; deserialize("shape_predictor_68_face_landmarks.dat") >> predictor; // 加载需要对齐的图像 Mat img = imread("test.jpg"); // 将 OpenCV 的 Mat 转换为 dlib 的图像类型 cv_image<bgr_pixel> dlib_img(img); // 人脸检测和关键点检测 std::vector<rectangle> faces = detector(dlib_img); full_object_detection shape = predictor(dlib_img, faces[0]); // 计算人脸对齐矩阵 Point2f src_points[3]; Point2f dst_points[3]; src_points[0] = Point2f(shape.part(36).x(), shape.part(36).y()); src_points[1] = Point2f(shape.part(45).x(), shape.part(45).y()); src_points[2] = Point2f(shape.part(30).x(), shape.part(30).y()); dst_points[0] = Point2f(0.2f * img.cols, 0.2f * img.rows); dst_points[1] = Point2f(0.8f * img.cols, 0.2f * img.rows); dst_points[2] = Point2f(0.5f * img.cols, 0.8f * img.rows); Mat warp_mat = getAffineTransform(src_points, dst_points); // 对齐图像 Mat aligned_img; warpAffine(img, aligned_img, warp_mat, img.size()); // 显示对齐前和对齐后的图像 imshow("Original Image", img); imshow("Aligned Image", aligned_img); waitKey(0); return 0; } ``` 在本例中,我们首先加载了 dlib 提供的人脸检测器和关键点检测器。然后,将需要对齐的图像转换为 dlib 的图像类型,进行人脸检测和关键点检测。接着,根据检测到的关键点计算人脸对齐矩阵,并使用 `warpAffine` 函数对图像进行对齐。最后,将对齐前和对齐后的图像显示出来。需要注意的是,本例中使用了

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值