人脸对齐是人脸识别系统中很重要的一个环节,SDM是传统人脸对齐算法中性能较为不错的一种,在今天这个深度学习如火如荼的时代,SDM依旧具有一定的优势。SDM相比深度网络具有模型小,速度快等优点。尽管SDM已经出现了好几年,但是网络上对其具体的详细讲解的知识还是比较少,尤其是和训练相关的东西。这几天自己硬着头皮啃了下源码,给出自己的理解。

1、数据集的下载

关于人脸对对齐的数据集有很多,比较常用的几个库可以到这里下载:点击打开链接。本文采用的是lfw数据集进行的实验,下载后可以看到数据集分为testset和trainset两个文件夹,分别包含了测试集和训练集,各个数据集下包含了图片和对应的标签。

2、求平均人脸形状

人脸对齐中,较为关键的第一步就是获取训练集的人脸关键点的平均形状。因为测试数据集是基于平均脸进行偏移实现人脸对齐的。首先,正则化第一张人脸图片:

(1)取第一张图片包含gt points的最小矩形。

(2)以得到的最小矩形向左上角平移,平移的大小x、y方向分别为矩形宽和高,然后矩形的宽和高分别扩展为原来的两倍,将这个变化后的矩形对图片中的人脸进行裁剪,同时对裁剪出来的人脸的特征点做相应的调整,这样裁剪出来的人脸基本上包含了整个人脸部分。

(3)将新裁剪出来的人脸缩放到400*400的大小,同时对应的特征点做相应的调整,当然这里你不一定也要设置为400*400,可以根据自己的需要修改。这里只是讲解下主要涉及的函数,太具体的需要大家自己摸索,具体代码如下:

bounding_box.m用来获取人脸裁剪的信息:

function [cropmin,cropmax,offset,minshape,marginW,marginH] = ...bounding_box ( shape )%获取特征点的人脸包围盒
minshape = min(shape);
maxshape = max(shape);%% calculating bounding box %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
width   = maxshape(1) - minshape(1);
height  = maxshape(2) - minshape(2);marginW = width/2;
marginH = height/2;cropmin = round(minshape - [marginW marginH]);%最左上角的点
cropmax = round(maxshape + [marginW marginH]);%最右下角的点offset = [0 0];if(cropmin(1)<=0)offset(1)  = -cropmin(1);cropmin(1) = 1;
endif(cropmin(2)<=0)offset(2)  = -cropmin(2);cropmin(2) = 1;
endend

normalize_first_shape.m用于正则化第一张图片

function [shape] = normalize_first_shape( Data, options )shape = Data.shape;%% calculating bounding box %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[cropmin,cropmax,offset,minshape,marginW,marginH] = bounding_box ( shape );%获取原始图片裁剪信息%% calculate scale factor %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
W_H = cropmax - cropmin;
wh1 = W_H(1);
wh2 = W_H(2);CanvasSize = options.canvasSize;scf = CanvasSize(1)/wh1;
if(scf*wh2 > CanvasSize(2))scf = CanvasSize(2)/wh2;
end%% croping image (for debug only) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
debug = 0;if debug img = imread(Data.img);cropImage   = img(cropmin(2):cropmax(2), cropmin(1):cropmax(1));scaleImage  = imresize(cropImage, scf);
end%% scale shape and image %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%调整对应的人脸特征点
shape = shape - repmat((minshape - [marginW marginH] + offset) ..., size(shape, 1), 1);
shape = shape*scf;if debug% Displaying image and feature points.figure(1);imshow(scaleImage);hold on;plot(shape(:, 1), shape(:, 2), 'g*');pause;
endend

利用第一张正则化特征点来正则化其他图片的特征点

function [shape,img] = normalize_rest_shape ( ref, data, options )cvw = options.canvasSize(1);
cvh = options.canvasSize(2);base = ref.shape;shape = data.shape;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Use procrustes analysis to align shape.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%利用普氏分析法将其他图片与第一张图片对齐,从而获得平均形状
[d, z, tform] = procrustes(base, shape, 'Reflection',false);%% normaling shape %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
debug = 0;if debugTrans = -1/tform.b*tform.c*tform.T';Trans = Trans(1, :);transM = [1/tform.b*tform.T Trans'];cvXY   = [1 cvw 1 cvw;1 1 cvh cvh];img       = im2double(rgb2gray(imread(data.img)));normImg   = quad2Box(img, cvXY, transM);figure(1);imshow(normImg);hold on;plot(z(:, 1), z(:, 2), 'r.');pause;endshape = z;end

顶层归一化函数

function Data = normalize_data ( Data, options )n = length(Data);%% noramlizing the first image
%正则化第一张图片
shape          = normalize_first_shape( Data(1) , options );
Data(1).shape  = shape;%% using the first to noramlizing others.
%根据第一张图片正则化第二张人脸图片
for i = 2 : n[shape] = normalize_rest_shape( Data(1), Data(i), options );Data(i).shape  = shape;
endend

形状学习,获取平均形状

function do_learn_shape ( options )%学习人脸的平均形状%% locating data folders %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
imageDataPath = options.trainingImageDataPath;%训练数据的路径
truthDataPath = options.trainingTruthDataPath;%训练数据的标签%% loading training data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Data = load_data( imageDataPath, truthDataPath, options );%加载图片和标签%% normalizing training data %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Data = normalize_data( Data, options );%归一化人脸形状%% shape model training %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ShapeModel = build_shape_model( Data );%对归一化后的人脸特征点求平均形状if ~exist( options.modelPath , 'dir' )mkdir( options.modelPath );
end%保存人脸的平均形状
save([options.modelPath options.slash options.datasetName ...'_ShapeModel.mat'], 'ShapeModel');clear Data;
clear ShapeModel;

下面的效果图是通过主成分分析归一化后的人脸形状获得的平均形状

若有不当之处,请指教

SDM人脸对齐系列一:数据预处理相关推荐

  1. SDM人脸对齐算法研究

    人脸对齐的算法是我本科阶段的毕业设计课题,从最初的一脸迷茫到最后完成毕设,两个月的时光,恭喜自己顺利完成了毕业设计,在过程中,更是不能缺少指导老师以及学长们给予的帮助.衷心感谢! 人脸对齐的目的是对人 ...

  2. 人脸对齐之SDM / 人脸对齐之LBF / 人脸实时替换

    人脸对齐之SDM(Supervised Descent Method) 人脸对齐之LBF(Local Binary Features) 人脸识别技术大总结(1):Face Detection & ...

  3. 【算法系列】数据预处理全面介绍

    转载自知乎"宋城"的<最全面的数据预处理介绍>一文 背景 本文主要介绍详细处理流程以及这样处理的原因,对于处理方法的原理介绍较为简略.当然,想深入了解原理可以根据这份框 ...

  4. 【深度学习系列】数据预处理

    PaddlePaddle的基本数据格式 根据官网的资料,总结出PaddlePaddle支持多种不同的数据格式,包括四种数据类型和三种序列格式: 四种数据类型: dense_vector:稠密的浮点数向 ...

  5. PLS系列001 数据预处理

    偏最小二乘法中的数据预处理 1 数据预处理 1.1 均值|方差|协方差|相关系数 1.2 数据标准化 Reference 1 数据预处理 1.1 均值|方差|协方差|相关系数 矩阵数据表X=(x1,x ...

  6. 第四篇:基于深度学习的人脸特征点检测 - 数据预处理

    在上一篇博文中,我们整理了300-W.LFPW.HELEN.AFW.IBUG和300-VW这6个数据集,使用Python将特征点绘制在对应的图片上,人工验证了数据集的正确性,最终获得了223034个人 ...

  7. 人脸对齐(九)--SDM算法

    转自:http://blog.csdn.net/huneng1991/article/details/51901912 http://blog.csdn.net/qq_14845119/article ...

  8. 人脸对齐:SDM人脸关键点检测

    1 介绍 本文所述方法为SDM在人脸对齐上的应用(Supvised Descent Method).SDM本是一种求函数逼近的方法,可以用于最小二乘求解.SDM并非一种人脸对齐方法,只是作者在提出新的 ...

  9. 机器学习--详解人脸对齐算法SDM-LBF

    https://www.cnblogs.com/Anita9002/p/7095380.html 引自:http://blog.csdn.net/taily_duan/article/details/ ...

最新文章

  1. Paddle下的Tensor运算以及简单回归问题
  2. linux wget 下载文件 报错 To connect to xxxx, use ‘--no-check-certificate’ 解决方法
  3. WSGI、Flask及Werkzeug三者之间的关系
  4. ViewPager 详解(五)-----使用Fragment实现ViewPager滑动
  5. Qt for ios / Qt for Android 设置透明状态栏
  6. php七牛云储存图片,wordpress使用七牛云存储图片 | 厘米天空
  7. Linux centos 主机名颜色设置 和 别名设置
  8. [snmp++]读取cisco路由交换机信息[一] - 环境搭建
  9. 前端学习(1716):前端系列javascript之页面配置下
  10. Mysql 零距离-入门(二)
  11. 中国移动回应“5G消息APP”下架:并非面向客户商用发布的产品
  12. 清北学堂模拟赛d1t1 位运算1(bit)
  13. 搬砖的也能学Python----if - elif 语句
  14. c语言,指针与数组--指针与二维数组2
  15. 防火墙虚拟系统资源分配配置实例
  16. 回溯____蓝桥 棋盘
  17. 2018中国食品工业年鉴2017PDF版
  18. PWM的基本原理及如何产生PWM
  19. 游园惊梦--记游第九届软博会
  20. SAP 安全证书的导入

热门文章

  1. 视频教程-JavaScript打飞机小游戏视频教程-JavaScript
  2. 实现函数指针的功能,tr1::bind,tr1::function,virtual函数重载
  3. cisco(思科)交换机配置篇【二】
  4. 一.隐藏手机下面虚拟键盘(华为,魅族......)
  5. PLC型号的选择方法
  6. 凌晨3点不回家-现实版
  7. python+flask+html/css+mysql+BAE 打造CSDN简历自动生成系统(附网站完全源码)
  8. DecisionTreeClassifier实例:Iris莺尾花分类
  9. 文字转语音软件哪个好?看完这篇你就知道了
  10. 前端好用的框架及工具