精华内容
下载资源
问答
  • 最近需要做人脸对齐的算法,通俗理解就是将图片人人脸姿态不太正确的给矫正过来,所以写了python版本的人脸对齐算法。基本原理是先通过MTCNN检测到人脸的五个关键点,再把原图中人脸区域外扩100%(这样做的目的是...
  • 人脸识别算法高度依赖于人脸图像的位置。 眼睛通常是面部提取中使用的功能之一。 为了使程序识别人,需要在面部图像中正确定位眼睛。 面部图像根据眼睛坐标进行对齐,转换,裁剪和调整大小。 给定一个未对齐的面部...
  • 基于mtcnn方法实现人脸对齐,人脸检测,c++代码实现。
  • 人脸landmark识别和人脸对齐alignment的代码
  • 基于seetaface的人脸检测-人脸对齐-人脸识别模型,用于物联网大赛的人脸识别模块
  • 基于python和dlib编写的人脸对齐程序。包含了两个测试模型(人脸特征点68点检测和5点检测的模型),还有测试图片。详细可以参考博客:http://blog.csdn.net/hongbin_xu/article/details/78511292
  • 使用基于深度学习的最新人脸对齐方法进行构建。 注意: lua版本可用。 对于数值评估,强烈建议使用lua版本,该版本使用与本文评估的模型相同的相同模型。 不久将添加更多型号。 产品特点 检测图片中的2D面部地标 ...
  • 最新人脸检测 人脸对齐 人脸识别工程,五点人脸特征识别 实时性好
  • 用opencv从文件夹中提取图片,实现人脸图片对齐切割,并保存。
  • 人脸对齐

    千次阅读 2019-08-20 22:31:35
    人脸对齐问题重点是人脸特征对齐,特征点对齐主要体现在确定关键点的位置上。从而进一步用于人脸姿态,状态的判断。比如在辅助驾驶,疲劳监测,AR等。在人脸检测的基础上,根据输入的人脸图像,自动定位出面部关键...

    人脸对齐问题重点是人脸特征对齐,特征点对齐主要体现在确定关键点的位置上。从而进一步用于人脸姿态,状态的判断。比如在辅助驾驶,疲劳监测,AR等。在人脸检测的基础上,根据输入的人脸图像,自动定位出面部关键特征点,如眼睛、鼻尖、嘴角点、眉毛以及人脸各部件轮廓点等,输入为人脸外观图像,输出为人脸的特征点集合。人脸对齐(Facial alignment): 可以看作在一张人脸图像搜索人脸预先定义的点(也叫人脸形状),通常从一个粗估计的形状开始,然后通过迭代来细化形状的估计。在搜索的过程中,两种不同的信息被使用,一个是人脸的外观 ,另一个是形状。形状提供一个搜索空间上的约束条件。人脸对齐主要将人脸中的 eyes, mouth, nose and chin 检测出来,用特征点标记出来。人脸对齐是一个中间步骤,首先是人脸检测,然后是人脸对齐,人脸对齐的结果可以用于:人脸验证, 人脸识别(Face recognition),属性计算(Attribute computing),表情识别(Expression recognition), 姿态估计(Pose Estimation) 等。实际应用中人脸的不同尺度,姿态,遮挡,光照,复杂表情等对人脸对齐具有较大的挑战性 。综合考虑传统方法和目前最新进展,从技术实现上可将人脸关键点检测分为2大类:生成式方法(Generative methods) 和 判别式方法(Discriminative methods)。Generative methods 构建人脸shape和appearance的生成模型。这类方法将人脸对齐看作是一个优化问题,来寻找最优的shape和appearance参数,使得appearance模型能够最好拟合输入的人脸。这类方法包括:
    AAM (Active Appearnce Model):ASM模型起源于snake模型(作为动态边缘分割的snake模型),该方法用一条由n个控制点组成的连续闭合曲线作为snake模型,再用一个能量函数作为匹配度的评价函数,首先将模型设定在目标对象预估位置的周围,再通过不断迭代使能量函数最小化,当内外能量达到平衡时即得到目标对象的边界与特征。
    ASM(Active Shape Model):是指主观形状模型,即通过形状模型 对 目标物体进行抽象。
    ASM 是一种 基于点分布模型(Point Distribution Model, PDM)的算法。在PDM中,外形相似的物体,例如 人脸、人手、心脏等的几何形状可以通过若干关键特征点(landmarks)的坐标依次串联形成一个形状向量来表示。基于ASM的人脸 通常通过 标定好的68个关键特征点 来进行描述:
    ASM算法分为训练过程和搜索过程。
    ASM的训练过程如下:
    搜集 T 个训练样本,样本数量根据需要(假定 T=100)
    手动标记n个脸部特征点(假定 n=68)
    构建形状向量
    进行归一化和对齐
    为每个特征点构建局部特征
    ASM的搜索过程如下:
    初始化对齐人脸
    根据HOG人脸检测结果的大致人脸位置,将前面计算得到的平均脸 X0 进行仿射变换,得到一个初始的特征点模型:
    X = M ( X0 ) + b
    搜索特征点
    a)针对每个特征点:
    在特征点邻域内进行 迭代搜索,通过局部特征点的特征匹配,获取新的特征点位置;
    关于特征点搜索方式,有的方法沿着边缘的法线方向提取,有的方法在特征点附近的矩形区域提取,这里先不展开讨论。
    通过特征点选择算法,选择多个 候选点,候选点 采用上面同样的方法进行特征提取,然后与样本特征点模型进行匹配,匹配采用前面提到的马氏距离,距离最小的候选点即作为新的特征点中心。
    b)采用 平均人脸模型 对匹配结果进行修正;
    反复执行 (a)(b),直到收敛。
    用初始模型在新的图像中搜索目标形状,使搜索中的特征点和相对应的特征点最为接近,持续优化 b,计算最接近模型。

    gui_Singleton = 1;
    gui_State = struct('gui_Name',       mfilename, ...
                       'gui_Singleton',  gui_Singleton, ...
                       'gui_OpeningFcn', @MainForm_OpeningFcn, ...
                       'gui_OutputFcn',  @MainForm_OutputFcn, ...
                       'gui_LayoutFcn',  [] , ...
                       'gui_Callback',   []);
    if nargin && ischar(varargin{1})
        gui_State.gui_Callback = str2func(varargin{1});
    end
    
    if nargout
        [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
    else
        gui_mainfcn(gui_State, varargin{:});
    end
    
    
    function MainForm_OpeningFcn(hObject, eventdata, handles, varargin)
    handles.output = hObject;
    global landmark
    global Img
    
    axes(handles.axes1); box on; set(gca, 'XTickLabel', '', 'YTickLabel', '');
    axes(handles.axes2); box on; set(gca, 'XTickLabel', '', 'YTickLabel', '');
    guidata(hObject, handles);
    
    
    
    function varargout = MainForm_OutputFcn(hObject, eventdata, handles) 
    varargout{1} = handles.output;
    
    
    function pushbutton1_Callback(hObject, eventdata, handles)
    global landmark
    global Img
    imgfilePath = fullfile(pwd, 'images/wwf.jpg');
    [filename, pathname, filterindex] = uigetfile( ...
        { '*.jpg','All jpg Files';...
        '*.bmp','All bmp Files';...
        '*.*',  '所有文件 (*.*)'}, ...
        '选择文件', ...
        'MultiSelect', 'off', ...
        imgfilePath);
    filePath = 0;
    if isequal(filename, 0) || isequal(pathname, 0)
        return;
    end
    filePath = fullfile(pathname, filename);
    Img = imread(filePath);
    axes(handles.axes1); 
    imshow(Img , []);
    title('原图像');
    
    
    function pushbutton2_Callback(hObject, eventdata, handles)
    global landmark
    global Img
    
    % 目标图像大小
    rows = 160;
    cols = 150;
    % 目标图像
    targetimage = zeros(rows,cols);
    % 用于定义特征点位置的系数
    rowFrac = 0.3;
    colFrac = 0.7;
    % 基于三点的特征点坐标
    le = [(1-colFrac)*cols,rows*rowFrac];
    re = [colFrac*cols,rows*rowFrac];
    mouth = [0.5*cols,rows*(1-rowFrac),];
    landmark_tool = [le; re; mouth];
    % 得到仿射变换
    tform1 = cp2tform(landmark_tool,landmark,'affine');
    % 得到目标图像
    result1 = imtransform(Img,tform1);
    axes(handles.axes2); 
    imshow(result1 , []);
    title('三点对齐方法1');
    
    function pushbutton3_Callback(hObject, eventdata, handles)
    close;
    
    function pushbutton4_Callback(hObject, eventdata, handles)
    global landmark
    global Img
    
    % 目标图像大小
    rows = 150;
    cols = 160;
    % 目标图像
    targetimage = zeros(rows,cols);
    % 用于定义特征点位置的系数
    rowFrac = 0.3;
    colFrac = 0.7;
    % 基于三点的特征点坐标
    le = [(1-colFrac)*cols,rows*rowFrac];
    re = [colFrac*cols,rows*rowFrac];
    mouth = [0.5*cols,rows*(1-rowFrac),];
    landmark_tool = [le; re; mouth];
    % 得到仿射变换
    tform2 = fitgeotrans(landmark,landmark_tool,'affine');
    % 得到目标图像
    result2 = imwarp(Img,tform2,'outputview',imref2d(size(targetimage)));
    axes(handles.axes2); 
    imshow(result2 , []);
    title('三点对齐方法2');
    
    function pushbutton5_Callback(hObject, eventdata, handles)
    global landmark
    global Img
    
    % 目标图像大小
    rows = 150;
    cols = 160;
    % 目标图像
    targetimage = zeros(rows,cols);
    % 用于定义特征点位置的系数
    rowFrac = 0.3;
    colFrac = 0.7;
    % 基于三点的特征点坐标
    le = [(1-colFrac)*cols,rows*rowFrac];
    re = [colFrac*cols,rows*rowFrac];
    mouth = [0.5*cols,rows*(1-rowFrac),];
    landmark_tool = [le; re; mouth];
    % 得到仿射变换
    tform3 = estimateGeometricTransform(landmark,landmark_tool,'affine');
    % 得到目标图像
    result3 = imwarp(Img,tform3,'outputview',imref2d(size(targetimage)));
    axes(handles.axes2); 
    imshow(result3 , []);
    title('三点对齐方法3');
    
    function pushbutton6_Callback(hObject, eventdata, handles)
    global landmark
    global Img
    
    % 目标图像大小
    rows = 150;
    cols = 160;
    % 目标图像
    targetimage = zeros(rows,cols);
    % 用于定义特征点位置的系数
    rowFrac = 0.3;
    colFrac = 0.7;
    % 基于两点的特征点坐标
    le = [(1-colFrac)*cols,rows*rowFrac];
    re = [colFrac*cols,rows*rowFrac];
    landmark_tool = [le; re];
    % 得到其他类型的空间变换
    tform1 = fitgeotrans(landmark,landmark_tool,'NonreflectiveSimilarity');
    % 得到目标图像
    result1 = imwarp(Img,tform1,'outputview',imref2d(size(targetimage)));
    axes(handles.axes2); 
    imshow(result1 , []);
    title('二点对齐方法1');
    
    
    function pushbutton7_Callback(hObject, eventdata, handles)
    global landmark
    global Img
    
    % 目标图像大小
    rows = 150;
    cols = 160;
    % 目标图像
    targetimage = zeros(rows,cols);
    % 用于定义特征点位置的系数
    rowFrac = 0.3;
    colFrac = 0.7;
    % 基于两点的特征点坐标
    le = [(1-colFrac)*cols,rows*rowFrac];
    re = [colFrac*cols,rows*rowFrac];
    landmark_tool = [le; re];
    % 得到其他类型的空间变换
    tform2 = estimateGeometricTransform(landmark,landmark_tool,'Similarity');
    % 得到目标图像
    result2 = imwarp(Img,tform2,'outputview',imref2d(size(targetimage)));
    axes(handles.axes2); 
    imshow(result2 , []);
    title('二点对齐方法2');
    
    function pushbutton8_Callback(hObject, eventdata, handles)
    global landmark
    global Img
    axes(handles.axes1); imshow(Img, []);
    hold on;
    landmark=[];
    % 特征点个数
    TOLNUM=3;
    for k=1:TOLNUM
        % 取点
        a=ginput(1);
        % 绘制
        plot(a(1),a(2),'r+');
        % 存储
        landmark=[landmark;a];
    end
    hold off;
    
    
    function pushbutton9_Callback(hObject, eventdata, handles
    global landmark
    global Img
    axes(handles.axes1); imshow(Img, []);
    hold on;
    landmark=[];
    % 特征点个数
    TOLNUM=2;
    for k=1:TOLNUM
        % 取点
        a=ginput(1);
        % 绘制
        plot(a(1),a(2),'r+');
        % 存储
        landmark=[landmark;a];
    end
    hold off;
    

    结果:三点对齐在这里插入图片描述

    展开全文
  • 双重注意力MobDenseNet(DAMDNet)进行稳健的3D人脸对齐(ICCV2019研讨会)-Pytorch 笔记 在“ Demo.py”文件中,您将找到如何运行这些代码。 在“ FaceSwap / Demo2.py”文件中,您将找到如何运行人脸交换代码。 ...
  • 本文讲解了基于三点和两点的人脸对齐,使用了matlab的内置函数。
  • 某盘链接,包括lfw原图和lfw经过mtcnn人脸检测对齐后抠出来的160x160的数据集,还有CASIA-WebFace经过人脸检测对齐后抠出来的144x144的数据集,链接无效或出现任何问题都可以私聊我!
  • 兀在matlab的代码是什么的英文看边界:边界感知的人脸对齐算法 由清华大学创建。 我们通过利用边界线作为人脸的几何结构来帮助面部地标定位,提出了一种新的边界感知人脸对齐算法。 与传统的基于热图的方法和基于...
  • 人脸检测 人脸对齐 人脸识别工程,五点人脸特征识别 实时性好
  • 人脸检测对齐识别重建基于github上的一些项目,旨在构建最先进的人脸系统。 目前重构不可用,代码不优雅。 参考 项目 纸 特征 mtcnn align casia 数据集(cpp 实现 matlab cp2tform) 455594张图片algin 453078成功...
  • 这段代码使用 GPA 进行面部对齐:由 Pulak Purkait 开发。 算法的详细信息可以在https://graphics.stanford.edu/courses/cs164-09-spring/Handouts/paper_shape_spaces_imm403.pdf 中找到 如有任何疑问,请联系:...
  • 基于多视角人脸对齐的人脸姿态归一化与仿真方法
  • seetaface分为FaceDetection(人脸检测)、FaceAlignment(人脸对齐)、FaceIdentification(人脸识别)三个模块,三个模块相互独立,综合利用起来即可实现最终的人脸识别功能。
  • 人脸对齐是一个中间步骤,首先是人脸检测,然后是人脸对齐人脸对齐的结果可以用于: 人脸识别、Face recognition,属性计算、Attribute computing,表情识别、Expression recognition 人脸对齐难点:姿态,...

    转自:https://blog.csdn.net/zhangjunhit/article/details/78435972 略删改(红色为个人理解,不对之处,欢迎指正

    Face Alignment In-the-Wild: A Survey
    Computer Vision and Image Understanding Volume 162, September 2017, Pages 1-22
    https://www.sciencedirect.com/science/article/pii/S1077314217301455

    本文主要是这篇文章的翻译,后面增加具体的算法理解。

    还有另一篇综述文献(内容好像截止2013年)
    Facial feature point detection: A comprehensive survey
    Neurocomputing Available online 1 June 2017
    http://www.sciencedirect.com/science/article/pii/S0925231217308202

    人脸对齐的定义: face alignment can be formulated as a problem of searching over a face image for the pre-defined facial points (also called face shape), which typically starts from a coarse initial shape, and proceeds by refining the shape estimate step by step until convergence。During the search process, two different sources of information are typically used: facial appearance and shape information. The latter aims to explicitly model the spatial relations between the locations
    of facial points to ensure that the estimated facial points can form a valid face shape.
    人脸对齐可以看作在一张人脸图像搜索人脸预先定义的点(也叫人脸形状),通常从一个粗估计的形状开始,然后通过迭代来细化形状的估计。在搜索的过程中,两种不同的信息被使用,一个是人脸的外观 appearance ,另一个是形状。形状提供一个搜索空间上的约束条件

    在人脸检测的基础上,根据输入的人脸图像,自动定位出面部关键特征点,如眼睛、鼻尖、嘴角点、眉毛以及人脸各部件轮廓点等,输入为人脸外观图像,输出为人脸的特征点集合,见下图:

    这里写图片描述

    人脸对齐是一个中间步骤,首先是人脸检测,然后是人脸对齐,人脸对齐的结果可以用于:
    人脸识别、Face recognition,属性计算、Attribute computing,表情识别、Expression recognition

    人脸对齐难点:姿态,遮挡,表情,光照
    这里写图片描述

    这里我们首先将人脸对齐算法分为两大类: generative and discriminative
    1) Generative methods 这类方法对人脸形状和外观都建立 generative models,将人脸对齐问题看作一个搜索 shape and appearance 参数的优化问题

    2)Discriminative methods 这类方法直接分别训练特征点检测器,这些点的位置受到形状的约束

    其实,生成方法,就是用你数据学习联合概率模型P(x,y),再求出条件概率分布P(Y|X)作为预测,因为模型表示了给定数据X,生成Y的生成关系,所以,在人脸对齐里,就是用最优化方法得到全局表观模型再预测,判别模式就是用数据直接学习P(Y|X),只关心给定X预测什么样的Y输出,因此,不完全受全局模型的影响(外在约束不算)

    这里写图片描述
    这里写图片描述

    下面我们来深入这两类方法

    3 Generative methods
    因为人脸的形状和外观多变性,通常我们将人脸建模为 deformable objects。用于人脸对齐的 Generative methods 对人脸外观构建 parametric models,拟合生成模型的目标是找到一组形状和外观参数可以得到一个最符合测试人脸图像的生成模型。基于人脸特征表示的类型,生成模型方法可以进一步细分为基于整体表示的 Active Appearance Models (AAMs) 和基于局部表示的 part-based generative deformable models

    3.1.1. Basic AAM algorithm: modeling and fitting
    基本的 Active Appearance Models (AAMs) 算法包括 modeling and fitting 两个部分:
    AAM modeling包括 shape model, appearance model, and motion model

    AAM fitting 这个拟合主要是寻找测试图像 test image 和 参考图像 reference image 之间的映射关系

    3.1.2. Recent advances on AAMs
    近年来针对AAMs的改进主要在三个方面:
    (1) unconstrained training data [22], 现实场景的训练数据
    (2) robust image representations [75, 76] 新的特征表示方法
    (3) robust and fast fitting strategies [75, 22] 新的拟合算法

    3.1.3 Discussion
    AAMs 的缺点:

    1)因为 holistic appearance model (也就是全局表观模型)被使用,局部遮挡情况难以被解决

    2)appearance parameter 维数很高,导致难优化,容易收敛于局部极小值

    3.2. Part-based generative deformable models
    Part-based generative methods build generative appearance models for facial parts, typically with a shape model to govern the deformations of the face shapes
    局部生成方法对人脸局部特征建立 generative appearance models,并使用一个 shape model 分析人脸形状的变形

    一般来说有两类方法构建 generative part models:一个是对每个人脸局部特征构建独立的 appearance model,另一个是 对所有的人脸局部特征同时构建 generative models

    Part-based generative methods 优点:
    more robust to global lighting and occlusion in wild conditions, easier to optimize

    随着现实场景训练数据的增加, discriminative methods 在人脸对齐中的优势比较明显

    4 Discriminative methods
    Discriminative face alignment methods seek to learn a (or a set of) discriminative function that directly maps the facial appearance to the target facial points
    这里有分两条技术线路:
    1)The first line is to follow the “divide and conquer”strategy by learning discriminative local appearance model (detector or regressor) for each facial point, and a shape model to impose global constraints on these local models(训练单点或者局部分类/检测器,这些点或者块受全局形状模型约束,如DPM,CLM,也就是分步解决
    2)The second line is to directly learn a vectorial regression function to infer the whole face shape, during which the shape constraint is implicitly encoded.(训练整个脸部形状回归向量,如ERT,ESR以及DNNs方法等

    这里写图片描述
    这里写图片描述

    4.7. Summary and discussion
    CLMs, constrained local regression and DPMs follow the “divide and conquer” principle to simplify the face alignment task by constructing individual local appearance model for each facial point
    这类方法效果不是很好,于是有了另一条研究线路(明显很慢
    another main stream in face alignment is to jointly estimate the whole face shape from image, implicitly exploiting the spatial constraints among facial points

    5 Towards the development of a robust face alignment system
    这里先提出一个整体框架,然后再优化细节问题
    这里写图片描述

    5.2. Training data augmentation
    数据增强还是很重要的,这里介绍了四个方法

    5.3. Face preprocessing
    For the task of face alignment, it is useful to remove the scaling variations of the detected faces, and enlarge the face region to ensure that all predefined facial points are enclosed

    排除检测到脸的尺度差异化,扩大脸部区域,保证面部数据全在检测框内。

    5.3.1. Handling scaling variations
    rescaling the bounding box produced by the face detector。尺度归一化。
    5.3.2. Enlarging face areas
    enlarge the face bounding box by 30%。外扩。

    5.4. Shape initialization
    Most face alignment methods start from a rough initialization, and then refine the shape iteratively until convergence. The initialization step typically has great influence on the final result, and an initial shape far from the ground truth might lead to very bad alignment results.初始形状选择,有平均脸,有随机采样真实脸,有多次随机采样,也有估计方法等等

    5.5. Accuracy and efficiency tradeoffs
    Face alignment in real time is crucial to many practical applications. The efficiency mainly depends on the feature extraction and shape prediction steps

    输出点的平均对齐误差。精度与效率平衡。

    6 System Evaluation
    测试评估使用的数据库有:
    这里写图片描述

    这里写图片描述

    这里写图片描述

    这里写图片描述
    这里写图片描述
    这里写图片描述

    上面这篇文章讲的主要是算法研究方向,补充一点人脸对齐领域的具体算法。参考:https://www.jianshu.com/p/e4b9317a817f

    从空间维度来考虑,以上这些方法又可分为2D方法,3D方法,稀疏方法和密集方法等。需要指出的是,由于深度学习方法可以很好的实现对多任务的处理,因此有很多新的算法可以同时完成对2D关键点和3D关键点的同时获取,进而可进一步支持后续的多任务分析,如人脸对齐,3D姿态分析等。

    在人脸关键点定位的发展史上,具有里程碑式的有如下五种方法:

    • 1995 年,Cootes 的 ASM(Active Shape Model)。
    • 1998 年,Cootes 的 AAM(Active Appearance Model) 算法。
    • 2006 年,Ristinacce 的 CLM(Constrained Local Model)算法。
    • 2010 年,Rollar 的 cascaded Regression 算法。
    • 2013 年,想港中文大学的汤晓欧和Sun Yi等开创深度学习人脸关键点检测的先河,首次将 CNN 应用到人脸关键点定位上。

    2. 2D人脸对齐

    2.1 AAM(Active Appearance Model)/ASM/Snake

    参考文献:An Introduction to Active Shape Models. Constrained Local Model for FaceAlignment. Xiaoguang Yan(2011).
    ASM模型起源于snake模型(作为动态边缘分割的snake模型),该方法用一条由n个控制点组成的连续闭合曲线作为snake模型,再用一个能量函数作为匹配度的评价函数,首先将模型设定在目标对象预估位置的周围,再通过不断迭代使能量函数最小化,当内外能量达到平衡时即得到目标对象的边界与特征。
    1989年yuille等人此提出使用参数化的可变形模板来代替snake模型,可变形模板概念的提出为aam的产生奠定了理论基础。
    1995年cootes等人提出的asm算法是aam的直接前身,asm采用参数化的采样形状来构成对象形状模型,并利用pca方法建立描述形状的控制点的运动模型,最后利用一组参数组来控制形状控制点的位置变化从而逼近当前对象的形状,该方法只单纯利用对象的形状,因此准确率不高。
    1998年,cootes等人在asm算法的基础上首先提出aam,与asm的不同之处是他不仅利用了对象的形状信息而且利用了对象的纹理信息。

    2.2 CLMS(Constrained Local Model)

    2.3 级联回归方法(Cascaded regression)

    • CPR(Cascaded Pose Regression)
      CPR通过一系列回归器将一个指定的初始预测值逐步细化,每一个回归器都依靠前一个回归器的输出来执行简单的图像操作,整个系统可自动的从训练样本中学习。
      人脸关键点检测的目的是估计向量(face shape) S=(x1, x2, ..., xK) ,其中K表示关键点的个数,由于每个关键点有横纵两个坐标,所以S得长度为2K。CPR检测流程一共有T个阶段,在每个阶段中首先进行特征提取f,这里使用的是shape-indexed features,也可以使用诸如HOG、SIFT等人工设计的特征,或者其他可学习特征(learning based features),然后通过训练得到的回归器R来估计增量ΔS( update vector),把ΔS加到前一个阶段的S上得到新的S,这样通过不断的迭代即可以得到最终的S(shape)。
      CPR中主要的操作是向量相加,不仅有效而且计算复杂度较低,所以近年来在face alignment中广泛应用

    • ESR
      ESR(Explicit Shape Regression)该方法出自2012的cvpr,是微软亚洲研究院(MSRA)孙剑组的作品。该文章主要提出了3个方法:
      (1)2层级联的boost回归(two-level boosted regression): 该方法最早是P Dollar大神在CVPR2010中Cascaded pose regression这篇论文中提出。作者这里的2层boost回归,第一层有10级,第二层有500级,这样分层的好处,比单独使用一个5000级而只有1层的效果要好很多。其中,第一层中的特征维度不固定,第二层中中的特征维度固定。
      (2)基于形状索引的特征(shape-indexed features): 该形状索引特征,计算回归的位置和真实位置之间的像素差,类似于中心差分算梯度,从而得到最终特征向量,并且该特征向量采用了局部坐标系,相比全局坐标系具有更好的鲁棒性。
      (3)基于相关系数的特征选择方法(correlation-based feature selection method):这里,需要从之前提取的400*400个特征中选择出最右代表性的前f个。简单的说,就是计算所有特征向量的相关系数,取前f个系数最高的作为最终的输出特征向量。

    • ERT(Ensemble of Regression Trees)
      是对ESR回归器的改进,dlib实现的就是这个。由原来ESR的两级boost回归器,替换为GBDT构成的森林。

    • Face Alignment at 3000 FPS
      cvpr2013, ESR是基础版本的形状回归,ERT将回归树修改为GBDT,由原始的直接回归形状,改进为回归形状残差,而LBF,是加速特征提取,由原来的像素差分特征池,改为随机选择点。

    • 说点自己的理解,其实,实际工程中,生成模型在资源上不是很占优势,基本上能工程化的,都是回归的思路,所以,以上方法里,也就是ERT,LBF值得去做了。实际上,ESR也是对CPR的改进。

    2.4 CNN 方法

    • DCNN
      香港中文大学汤晓欧,SunYi等人作品,首次将CNN用于人脸关键点检测。总体思想是由粗到细,实现5个人脸关键点的精确定位。网络结构分为3层:level 1、level 2、level 3。每层都包含多个独立的CNN模型,负责预测部分或全部关键点位置,在此基础上平均来得到该层最终的预测结果。虽然作者没有明确说这个问题,但是很明显的是,经过level-1,得到了一个相对较好的初始化。

    在这方面,face++ 发表在ICCV-2013的paper(Extensive facial landmark localization with coarse-to-fine convolutional network cascade)同样有这么个“初始化”的操作。借鉴别的文献中的idea:局部共享权值(locally sharing weights),理论听起来挺有道理的。传统的权值共享认为某一个特征会图像的不同位置出现,所以采用全局权值共享。但是人脸是由比较规范的结构,如人眼就是在上部,鼻子就是在中部,嘴就是在下部,因此应该采用局部权值共享。

    • TCNN
      • Facial Landmark Detection with Tweaked Convolutional Neural Networks》用了一个叫Vanilla CNN的网络模型,也是直接CNN回归,亮点在于对CNN提取的特征进行聚类,将各簇对应的样本进行分析,最后发现同一簇表现出“相同属性”(姿态,微笑,性别)的人脸。对此,设计了K个FC5和K个FC6层,用以对不同“面部属性”的人脸进行关键点检测。就是下图红圈那里。2016年,Wu等人研究了CNN在人脸关键点定位任务中到底学习到的是什么样的特征,在采用GMM(Gaussian Mixture Model, 混合高斯模型)对不同层的特征进行聚类分析,发现网络进行的是层次的,由粗到精的特征定位,越深层提取到的特征越能反应出人脸关键点的位置。针对这一发现,提出了TCNN(Tweaked Convolutional Neural Networks),其网络结构如图所示:这里写图片描述这里写图片描述

    上图为Vanilla CNN

    测试时,图片首先经过Vanilla CNN提取特征,即FC5的输出。将FC5输出的特征与K个聚类中心进行比较,将FC5输出的特征划分至相应的类别中,然后选择与之相应的FC6进行连接,最终得到输出

    • MTCNN

      CNN回归和检测多任务,多尺度级联,三个网络级联,由粗到精,同时完成检测和特征点定位回归。
    • LAB (LAB-Look at Boundary A Boundary-Aware Face Alignment Algorithm )
      2018cvpr 清华&商汤作品。借鉴人体姿态估计,将边界信息引入关键点回归上。网络包含3个部分:边界热度图估计模块(Boundary heatmap estimator),基于边界的关键点定位模块( Boundary-aware landmarks regressor )和边界有效性判别模块(Boundary effectiveness discriminator)

       

      LAB网络结构

    1. 边界热度图估计模块:采用stacked hourglass network 和 message passing layers。输入人脸图像,输出人脸边界热度图来表示面部的几何结构。人脸面部的各个器官边界共构成K个边界。每个stack结束时,特征图被分成K个分支,分别送给各个对应类型的边界热度图估计。最终生成的热度图与输入原始图像进行融合,作为关键点定位模块的输入。
    2. 基于边界的关键点定位模块,利用边界信息,通过4阶res-18网络来定位关键点
    3. 边界有效性判别模块,由于边界热度图在关键点定位中起着非常重要的作用,因此需要对生成的边界信息的准确性进行评判。该模块采用对抗网络,评判边界热度图的有效性。
    展开全文
  • 花了不少时间生成的regressor训练模型,主要在生成随机森林时花的时间。 !!!!注意 注意!!!! 与此对应的,还有一个LBF模型LBF.model 要一起下载!!!
  • 面部对齐 通过回归树进行人脸对齐 预要求 Visual Studio 2012+ 和 OpenCV 安装在 C:/opencv
  • 人脸对齐工具

    2017-01-03 10:01:18
    人脸识别的前处理工具,希望对大家有所帮助
  • 通过显式形状回归进行面部对齐。 在过程中。 CVPR,2012年。 模型已经过训练,请使用python定位面部标志。(需要numpy和opencv2)。 请在initializa_face.py中指定haar功能的opencv路径。 使用时:python test_...
  • 人脸预处理:人脸检测+人脸对齐

    千次阅读 2020-12-16 21:55:01
    因为如果没有人脸对齐这一步操作,或者训练的对齐方式与验证的对齐方式不同,这将导致很大的性能差距。 目前科研人员基本都用一致的对齐方法,就是MTCNN检测五个人脸关键点,然后使用相似性变换得到对齐后的人脸,...

    1 简介

    • 对于人脸识别任务,人脸预处理至关重要。首先我们需要检测出图像中的人脸,然后通过人脸相似性变换得到对齐后的标准人脸。然后在对其进行人脸识别。
    • 在人脸识别过程中,往往检测到的人脸是倾斜的。相似性变换根据检测到的关键点和目标点得到变换矩阵,把整张脸乘变换矩阵得到对齐后的人脸。因为如果没有人脸对齐这一步操作,或者训练的对齐方式与验证的对齐方式不同,这将导致很大的性能差距。
    • 目前科研人员基本都用一致的对齐方法,就是MTCNN检测五个人脸关键点,然后使用相似性变换得到对齐后的人脸,大小为112×112。
    • 博主找了好几种方法,结果效果都不一致,最后参考insightface的方法,达到了一致的效果。

    2 具体方法

    2.1 下载insightface源码及RetinaFace预训练模型

    https://github.com/deepinsight/insightface

    安装后解压,我们需要使用其中的几个文件,分别为:

    1. gender-age文件夹下的mtcnn-model文件夹,mtcnn_detector,helper
    2. deploy文件夹下的mtcnn_detector
    3. detection/RetinaFace文件夹下的rcnn文件夹,retinaface
    4. recognition/common文件夹下的face_align

    下载预处理模型:
    https://pan.baidu.com/s/1C6nKq122gJxRhb37vK0_LQ

    将这些置于一个文件夹中。
    在这里插入图片描述

    2.2 搭建开发环境

    我是用的是pycharm+anaconda+win10
    软件包安装

    pip install opencv-python numpy tqdm scikit-image Cython
    pip install mxnet-cu101 (根据自己的cuda版本来安装mxnet)
    

    2.3 编译rcnn的pyx文件

    参考博客:链接
    第一步:
    打开rcnn/cython文件夹下的cpu_nms文件,将

    cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1]
    

    改为

    cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1].astype(np.int32)
    

    第二步:
    将setup.py改为

    try:
        from setuptools import setup
        from setuptools import Extension
    except ImportError:
        from distutils.core import setup
        from distutils.extension import Extension
    from Cython.Distutils import build_ext
    import numpy as np
    
    ###这里的try...except...是百度的网上的帖子,必须加上,否则会出现Unable to find vcvarsall.bat错误。
    
    try:
        numpy_include = np.get_include()
    except AttributeError:
        numpy_include = np.get_numpy_include()
    
    ext_modules = [
        Extension(
            "bbox",
            ["bbox.pyx"],
            extra_compile_args=["/openmp"],
            include_dirs=[numpy_include]
        ),
        Extension(
            "anchors",
            ["anchors.pyx"],
            extra_compile_args=["/openmp"],
            include_dirs=[numpy_include]
        ),
        Extension(
            "cpu_nms",
            ["cpu_nms.pyx"],
            extra_compile_args=["/openmp"],
            include_dirs = [numpy_include]
        ),
    ]
    
    setup(
        name='frcnn_cython',
        ext_modules=ext_modules,
        # inject our custom trigger
        # cmdclass={'build_ext': custom_build_ext},
        cmdclass={'build_ext': build_ext},
    )
    
    

    第三步:
    进入cython文件夹下,在终端输入指令:

    python setup.py build_ext --inplace
    

    2.4 编写代码

    import cv2
    import numpy as np
    import face_align
    from retinaface import RetinaFace
    from tqdm import tqdm
    import os
    from mtcnn_detector import MtcnnDetector
    import mxnet as mx
    
    '''
    使用mtcnn检测,对于一些mtcnn检测不出的图像,可以使用retainface检测。
    检测对齐结果与别人完全一致。
    '''
    
    gpu_id = 0 # gpu号
    det_prefix = 'C:/Users/win10/Desktop/face_align/retinaface-R50/R50' # retinaface预训练模型
    model_folder = 'C:/Users/win10/Desktop/face_align/mtcnn-model' # mtcnn预训练模型
    input_root = "E:/Dataset/lfw" # 原始图像
    output_root = "E:/Dataset/lfw_align" # 处理后的图像
    image_size = 112 # 处理后大小
    align_mode = 'arcface' # 参考点选择
    target_size = 400 # 目标尺寸
    max_size = 800 # 限制图像最大尺寸
    
    # 得到校正后的图像
    def get_norm_crop(image_path):
        im = cv2.imread(image_path) # 读取图像
        im_shape = im.shape # 尺寸 (w,h,3)
        im_size_min = np.min(im_shape[0:2]) # 最小值
        im_size_max = np.max(im_shape[0:2]) # 最大值
        im_scale = float(target_size) / float(im_size_min) # 比例
        # 防止原图尺寸过大
        if np.round(im_scale * im_size_max) > max_size:
            im_scale = float(max_size) / float(im_size_max)
        # 检测五个关键点 bbox是五个参数,前四个是2个坐标点参数,最后一个是得分 landmark由10个参数(5个坐标点)
        ret = detector_mtcnn.detect_face(im, det_type=0)
        if ret is None:
            # return None
            # 如果mtcnn没检测到,就是用retinaface检测
            bbox, landmark = detector_retinaface.detect(im, threshold=0.5, scales=[im_scale])
            # # 如果还没有检测到,放宽要求进行在次检测
            # if bbox.shape[0] == 0:
            #     bbox, landmark = detector_retinaface.detect(im, threshold=0.05, scales=[im_scale * 0.75, im_scale, im_scale * 2.0])
            #     print('refine', im.shape, bbox.shape, landmark.shape)
        else:
            bbox, landmark = ret
    
        # 判断是否检测到了,检测到进行根据五个特征点相似变换
        nrof_faces = bbox.shape[0]
        if nrof_faces > 0:
            det = bbox[:, 0:4] # 存储2个坐标点用于计算bbox大小
            img_size = np.asarray(im.shape)[0:2] # 原图尺寸
            bindex = 0
            # 如果一张图检测到多个人脸,通过bbox大小以及离中心的程度来选择人脸
            if nrof_faces > 1:
                bounding_box_size = (det[:, 2] - det[:, 0]) * (det[:, 3] - det[:, 1]) # 人脸bbox尺寸
                img_center = img_size / 2 # 图像中心点坐标
                offsets = np.vstack([(det[:, 0] + det[:, 2]) / 2 - img_center[1],
                                     (det[:, 1] + det[:, 3]) / 2 - img_center[0]]) # 计算bbox中心点离图像中心点的距离
                offset_dist_squared = np.sum(np.power(offsets, 2.0), 0) # 平方
                bindex = np.argmax(bounding_box_size - offset_dist_squared * 2.0)  # 选择最合适的人脸bbox
            # _bbox = bbox[bindex, 0:4] # bbox
            if ret == None:
                _landmark = landmark[bindex]  # 特征点 retinaface
            else:
                _landmark = [[landmark[bindex][j], landmark[bindex][j + 5]] for j in range(5)] # 特征点 mtcnn
                _landmark = np.array(_landmark, dtype=float)
            # 选取参考点,进行相似性变换
            warped = face_align.norm_crop(im, landmark=_landmark, image_size=image_size, mode=align_mode)
            return warped
        else:
            return None
    
    if __name__ == '__main__':
        # 创建输出文件夹
        if not os.path.isdir(output_root):
            os.mkdir(output_root)
        # 检测器初始化
        detector_mtcnn = MtcnnDetector(model_folder=model_folder, ctx=mx.gpu(gpu_id),
                                       num_worker=1, accurate_landmark=True, threshold=[0.6, 0.7, 0.8])
        detector_retinaface = RetinaFace(det_prefix, 0, gpu_id, network='net3')
        # 处理 input_root下存放文件夹
        for subfolder in tqdm(os.listdir(input_root)): # 读取input_root文件夹下的文件夹名称
            # 读取到的是文件夹,然后创建它
            if not os.path.isdir(os.path.join(output_root, subfolder)):
                os.mkdir(os.path.join(output_root, subfolder))
            # 读取文件夹下的图片,进行处理
            for image_name in os.listdir(os.path.join(input_root, subfolder)):
                print("Processing\t{}".format(os.path.join(input_root, subfolder, image_name))) # 打印信息
                # 如果报错说明没有检测到人脸
                try:
                    warped_face = get_norm_crop(os.path.join(input_root, subfolder, image_name)) # 检测并对齐
                    if image_name.split('.')[-1].lower() not in ['jpg', 'jpeg']:  # 加后缀.jpg
                        image_name = '.'.join(image_name.split('.')[:-1]) + '.jpg'
                    cv2.imwrite(os.path.join(output_root, subfolder, image_name), warped_face) # 保存
                except Exception:
                    print("{} is discarded due to exception!".format(os.path.join(input_root, subfolder, image_name)))
                    continue
    
    

    3 总结

    本方式使用insightface的mtcnn加相似性变换,如果mtcnn没有找到人脸,就使用retinaface处理,如果还没找到就提示信息。
    该方法应该与那些处理好的数据集是一个检测对齐处理方式,用lfw数据集测试完全一致。处理后的人脸为112×112大小。

    展开全文
  • FaceTools处理过的LFW数据集,都是对齐后的图片,其中有些是FaceTools对齐不了的,对齐了的有12000多张图片
  • 自适应监督下降方法的姿态鲁棒人脸对齐算法.pdf
  • 粗到精细的自动编码器网络(CFAN),用于实时人脸对齐
  • C++实现人脸对齐

    2021-05-06 20:30:33
    一、为什么需要人脸对齐、 二、相似性变换 三、代码实现 一、为什么需要人脸对齐 MTCNN可以进行人脸landmark的输出。设想这样一种情况,图片中的脸相对于图片是斜的。如果不进行人脸对齐,人脸识别的精度会明显...

    目录

    一、为什么需要人脸对齐

    二、相似性变换

    三、代码实现


    一、为什么需要人脸对齐

              MTCNN可以进行人脸landmark的输出。设想这样一种情况,图片中的脸相对于图片是斜的。如果不进行人脸对齐,人脸识别的精度会明显的降低。

    二、相似性变换

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,159
精华内容 3,663
关键字:

人脸对齐