Face Alignment by 3000 FPS系列学习总结(一)

广播

如今的opencv已经提供了LBF的训练和测试代码,推荐阅读
《使用OpenCV实现人脸关键点检测》


face alignment 流程图

train阶段

测试阶段

预处理

裁剪图片

  1. tr_data = loadsamples(imgpathlistfile, 2);
    说明: 本函数用于将原始图片取ground-truth points的包围盒,然后将其向左上角放大一倍。然后截取此部分图像,同时变换ground-truth points.hou,然后为了节省内存,使用了缩放,将其缩放在150*150的大小内,作为我们后续处理的图像及ground-truth points。
    截取前示意图:

    截取后示意图:

    缩放后示意图:

    注意: loadsamples的第二个参数是2,表明需要进行缩放,但是测试时,并没有进行缩放,参数为1.
    To do list:本函数使用的真实特征点的包围盒截取的图像,在实际作用时,肯定不能去真实特征点截取图像了。我们应该改为人脸检测框代替这个真实特征点的包围盒,如果检测不到,再用真实特征点的包围盒替代.
function Data = loadsamples(imgpathlistfile, exc_setlabel)
%LOADSAMPLES Summary of this function goes here
%   Function: load samples from dbname database
%   Detailed explanation goes here
%   Input: 
%        dbname: the name of one database
%        exc_setlabel: excluded set label
%   Output:
%        Data: loaded data from the database
%   基本步骤:
%      1. 载入图片,取ground_truth shape的包围盒,然后放大一倍,截取图像。
%       同时相应地变换shape.
%      2.  为了防止图片过大,我们把图像控制在150*150内.
%      3.  用matlab自带的人脸检测求解或者直接拿bbox代替bbox_facedet
%      4.  后面还为了防止train文件下夹杂了test的图片,做了排除处理.
%imgpathlist = textread(imgpathlistfile, '%s', 'delimiter', '\n');Data = cell(length(imgpathlist), 1);setnames = {'train' 'test'};% Create a cascade detector object.
% faceDetector = vision.CascadeObjectDetector();
% bboxes_facedet = zeros(length(imgpathlist), 4);
% bboxes_gt      = zeros(length(imgpathlist), 4);
% isdetected = zeros(length(imgpathlist), 1);parfor i = 1:length(imgpathlist)img = im2uint8(imread(imgpathlist{i}));Data{i}.width_orig    = size(img, 2);Data{i}.height_orig   = size(img, 1);% Data{i}.img      = img% shapepath = strrep(imgpathlist{i}, 'png', 'pts');%这一句和下一句是一样的用途shapepath = strcat(imgpathlist{i}(1:end-3), 'pts');Data{i}.shape_gt = double(loadshape(shapepath));    % Data{i}.shape_gt = Data{i}.shape_gt(params.ind_usedpts, :);% bbox     =  bounding_boxes_allsamples{i}.bb_detector; %Data{i}.bbox_gt = getbbox(Data{i}.shape_gt); % [bbox(1) bbox(2) bbox(3)-bbox(1) bbox(4)-bbox(2)]; %shape的包围盒% cut original image to a region which is a bit larger than the face% bounding boxregion = enlargingbbox(Data{i}.bbox_gt, 2.0);  %将true_shape的包围盒放大一倍,形成更大的包围盒,以此裁剪人脸,也有通过人脸检测框放大的region(2) = double(max(region(2), 1)); %防止放大后的region超过图像,这样一旦超过坐标会变成负数。因此取了和1的最大值.region(1) = double(max(region(1), 1));bottom_y = double(min(region(2) + region(4) - 1, Data{i}.height_orig)); %同理防止过高,过宽right_x = double(min(region(1) + region(3) - 1, Data{i}.width_orig));img_region = img(region(2):bottom_y, region(1):right_x, :);Data{i}.shape_gt = bsxfun(@minus, Data{i}.shape_gt, double([region(1) region(2)])); %68*2的矩阵减去一个向量% to save memory cost during trainingif exc_setlabel == 2ratio = min(1, sqrt(single(150 * 150) / single(size(img_region, 1) * size(img_region, 2)))); %如果图像小于150*150,则不用缩放,否则缩放到150*150以内img_region = imresize(img_region, ratio);Data{i}.shape_gt = Data{i}.shape_gt .* ratio;end Data{i}.ori_img=img;Data{i}.lefttop=[region(1) region(2)]; %自己补充的Data{i}.bbox_gt = getbbox(Data{i}.shape_gt);Data{i}.bbox_facedet = getbbox(Data{i}.shape_gt); %应该改为人脸检测框% perform face detection using matlab face detector%{bbox = step(faceDetector, img_region);if isempty(bbox)% if face detection is failed        isdetected(i) = 1;Data{i}.bbox_facedet = getbbox(Data{i}.shape_gt);elseint_ratios = zeros(1, size(bbox, 1));for b = 1:size(bbox, 1)area = rectint(Data{i}.bbox_gt, bbox(b, :));int_ratios(b) = (area)/(bbox(b, 3)*bbox(b, 4) + Data{i}.bbox_gt(3)*Data{i}.bbox_gt(4) - area);            end[max_ratio, max_ind] = max(int_ratios);if max_ratio < 0.4  % detection failisdetected(i) = 0;elseData{i}.bbox_facedet = bbox(max_ind, 1:4);isdetected(i) = 1;% imgOut = insertObjectAnnotation(img_region,'rectangle',Data{i}.bbox_facedet,'Face');% imshow(imgOut);end   end%}% recalculate the location of groundtruth shape and bounding box% Data{i}.shape_gt = bsxfun(@minus, Data{i}.shape_gt, double([region(1) region(2)]));% Data{i}.bbox_gt = getbbox(Data{i}.shape_gt);if size(img_region, 3) == 1Data{i}.img_gray = img_region;else% hsv = rgb2hsv(img_region);Data{i}.img_gray = rgb2gray(img_region);end    Data{i}.width    = size(img_region, 2);Data{i}.height   = size(img_region, 1);
endind_valid = ones(1, length(imgpathlist));
parfor i = 1:length(imgpathlist)if ~isempty(exc_setlabel)ind = strfind(imgpathlist{i}, setnames{exc_setlabel});  %strfind是找imgpathlist{i}中含有setnames{exc_setlabel}='test'的地址if ~isempty(ind) % | ~isdetected(i)ind_valid(i) = 0;endend
end% learn the linear transformation from detected bboxes to groundtruth bboxes
% bboxes = [bboxes_gt bboxes_facedet];
% bboxes = bboxes(ind_valid == 1, :);Data = Data(ind_valid == 1); %找到含有test的地址,并排除出去,保证Data都是train_dataendfunction shape = loadshape(path)
% function: load shape from pts file
file = fopen(path);if ~isempty(strfind(path, 'COFW'))shape = textscan(file, '%d16 %d16 %d8', 'HeaderLines', 3, 'CollectOutput', 3);
elseshape = textscan(file, '%d16 %d16', 'HeaderLines', 3, 'CollectOutput', 2);
end
fclose(file);shape = shape{1};
endfunction region = enlargingbbox(bbox, scale)region(1) = floor(bbox(1) - (scale - 1)/2*bbox(3));
region(2) = floor(bbox(2) - (scale - 1)/2*bbox(4));region(3) = floor(scale*bbox(3));
region(4) = floor(scale*bbox(4));% region.right_x = floor(region.left_x + region.width - 1);
% region.bottom_y = floor(region.top_y + region.height - 1);
end

示意图:

对一幅图片,实际上我们感兴趣的就是人脸区域,至于其他部分是无关紧要的。因此出于节省内存的原因,我们需要裁剪图片。前面已经讲述了裁剪的方法。从坐标系的角度来看,实际上是从原始坐标系转化到以扩充后的盒子为基础的坐标系。即如图蓝色的为原始坐标系,就是一张图片的坐标系。红色的为后来裁剪后的坐标系,而黑色框为人脸框(可以是人脸检测获得的,也可以是ground_truth points的包围盒)。那么坐标系的变化,简单而言可以写作:

shapes_gt˜=shapes_gt[Region(1),Region(2)]shapes_gt~=shapes_gt−[Region(1),Region(2)]

上式就是原来的shape经过裁剪后的坐标。后来还加上了缩放,即:

shapes_gt˜=shapes_gt˜.Ratioshapes_gt~=shapes_gt~.∗Ratio

左右翻转图片

train_model.m 第60行

% Augmentate data for traing: assign multiple initial shapes to each
% image(为每一张图片增加多个初始shape)
Data = Tr_Data; % (1:10:end);
Param = params;if Param.flipflag % if conduct flippingData_flip = cell(size(Data, 1), 1);for i = 1:length(Data_flip)Data_flip{i}.img_gray    = fliplr(Data{i}.img_gray);%左右翻转Data_flip{i}.width_orig  = Data{i}.width_orig;Data_flip{i}.height_orig = Data{i}.height_orig;    Data_flip{i}.width       = Data{i}.width;Data_flip{i}.height      = Data{i}.height; Data_flip{i}.shape_gt    = flipshape(Data{i}.shape_gt);        Data_flip{i}.shape_gt(:, 1)  =  Data{i}.width - Data_flip{i}.shape_gt(:, 1);Data_flip{i}.bbox_gt        = Data{i}.bbox_gt;Data_flip{i}.bbox_gt(1)     = Data_flip{i}.width - Data_flip{i}.bbox_gt(1) - Data_flip{i}.bbox_gt(3);       Data_flip{i}.bbox_facedet        = Data{i}.bbox_facedet;Data_flip{i}.bbox_facedet(1)     = Data_flip{i}.width - Data_flip{i}.bbox_facedet(1) - Data_flip{i}.bbox_facedet(3);   endData = [Data; Data_flip];
end

示意图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259052.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

macbook 移动硬盘无法写入_如何升级MacBook笔记本的SSD硬盘-菜鸟折腾系列一

2010 年的时候买了 09 年末的 MACBOOK 小白&#xff0c;由于技术发展&#xff0c;软件越来越吃硬件内存&#xff0c;现在2G 内存别提基本的工作了&#xff0c;连开机都有困难&#xff0c;每次一点就一个风火轮&#xff0c;基本就是一块 13 寸的板砖了。。。众所周知 HDD 机械硬…

face alignment by 3000 fps系列学习总结(二)

准备初始数据 mean_shape mean_shape就是训练图片所有ground_truth points的平均值.那么具体怎么做呢&#xff1f;是不是直接将特征点相加求平均值呢&#xff1f; 显然这样做是仓促和不准确的。因为图片之间人脸是各式各样的&#xff0c;收到光照、姿势等各方面的影响。因此…

parasoft Jtest 使用教程:功能配置之查找错误

2019独角兽企业重金招聘Python工程师标准>>> parasoft Jtest介绍和试用>>> 今天开始为大家带来parasoft Jtest功能配置板块教程&#xff0c;也是系列教程中最重要的一部分。 通过运行Jtest的BugDetective和使用最重要的一套规则来进行编码标准静态分析&…

kmp入门小结

void get_next(char *s) {int len strlen(s);int j 0; int k -1;while (j < len){if (k -1 || s[j] s[k]){j; k; next[j] k;}else k next[k];} } 设t next[i]; next[i] 表示的是 i之前最大的t满足 s[0...t-1] s[i-t...i-1] 比如 0123 4 0123 5 &#xff0c;next[…

基于visual Studio2013解决面试题之0807strstr函数

&#xfeff;&#xfeff;&#xfeff;题目解决代码及点评/*写strstr函数简单的遍历去查找吧 */#include <iostream> #include <stdio.h>const char *my_strstr(const char *str, const char *sub_str) {// 遍历for(int i 0; str[i] ! \0; i){int tem i; //tem保…

aop在项目中的实际运用_mypy在实际项目中的应用

我认为静态类型似乎被吹捧过高了。尽管如此&#xff0c;mypy极低的侵入性能带来许多好处。关于如何在现有的Python项目中添加类型&#xff0c;以下是我的一些想法&#xff0c;大致按重要性排序。首先确保mypy成功运行 Mypy上手时两个很常见的问题有&#xff1a;1.Mypy没有作为构…

face alignment by 3000 fps系列学习总结(三)

训练 我们主要以3000fps matlab实现为叙述主体。 总体目标 我们需要为68个特征点的每一个特征点训练5棵随机树&#xff0c;每棵树4层深&#xff0c;即为所谓的随机森林。 开始训练 分配样本 事实上&#xff0c;对于每个特征点&#xff0c;要训练随机森林&#xff0c;我们需…

HDU 2049 不容易系列之(4)——考新郎( 错排 )

链接&#xff1a;传送门思路&#xff1a;错排水题&#xff0c;从N个人中选出M个人进行错排&#xff0c;即 C(n,m)*d[m]补充&#xff1a;组合数C(n,m)能用double计算吗&#xff1f;第二部分有解释 Part 1. 分别求出来组合数的分子和分母然后相除/******************************…

linux服务器选ubantu或centos_如何通过SSH连接阿里云上的Linux系统

首先SSH是啥&#xff0c;维基一下&#xff1a;Secure Shell&#xff08;安全外壳协议&#xff0c;简称SSH&#xff09;是一种加密的网络传输协议&#xff0c;可在不安全的网络中为网络服务提供安全的传输环境[1]。SSH通过在网络中创建安全隧道来实现SSH客户端与服务器之间的连接…

paypal之nodejs 框架 Kraken-js 源码分析

本文是基于 kraken-js 0.6.1 版本的 关于如何使用kraken-js 可以去看看官网的使用文档 点击这里 。kraken-js 是基于express之上的&#xff0c;目的在于让工程师更多的去关注代码逻辑&#xff0c;少关注自身的开发环境&#xff0c;所以他将express所有的一些公用的配置都写在了…

go build 参数_Go语言 通过go bulid -tags 实现编译控制

Go语言提供的build tag 条件编译特性&#xff0c;顾名思义&#xff0c;只有在特定条件下才会构建对应的代码。比如下面的源文件只有在设置debug构建标志时才会被构建&#xff1a;// build debugpackage mainvar buildMode "debug"可以用以下命令构建&#xff1a;go …

selinux 的管理

第十单元selinux 的管理一 显示及更改 SELINUX 模式getenforce ###显示selinux模式setenforce 0|1 ##0指permissive警告&#xff0c;1 表示 enforcing强制###vim /etc/sysconfig/selinux ###修改selinux开机状态###注&#xff1a;disable表示关闭&…

ubuntu15.10下安装opencv2.4.9python上调用opencv库

对于centos&#xff0c;可以参考&#xff1a;Install OpenCV-Python in Fedora 如果IPP难以下载可以在cmake时禁掉它&#xff0c;只需&#xff1a;cmake -DWITH_IPPOFF OpenCV3.3CUDA9.0 安装过程中遇到的问题&#xff0c;解析&#xff1a; https://blog.csdn.net/u014613745/a…

键盘改键软件_一秒五键,一键三招,万种光污染,杜伽K310樱桃轴机械键盘感受...

机械键盘我一直用的青轴&#xff0c;或者各种其他名字但其实本质就是青轴的。喜欢青轴那种清脆的声音&#xff0c;在我听来如同山间小溪流水般的叮咚。不过这声音在夜间分外的具有穿透力&#xff0c;更会在人身体不好的时候难以承受&#xff0c;所以每每用过之后却又不得不换回…

codeigniter钩子的使用

CodeIgniter 的钩子功能&#xff0c;使得我们可以在不修改系统核心文件的基础上&#xff0c;来改变或增加系统的核心运行功能。可是钩子究竟该怎么用呢&#xff1f;虽然不是很难&#xff0c;不过很多刚用ci的朋友可能还是不明白怎么用。 通过本文的简单实例&#xff0c;大家一下…

powerdesigner画关系图_想画好手绘,这些图你一定要画一下!

画好手绘除了对透视要深入了解掌握以及线条运用把握之外&#xff0c;还有很重要的就是要对空间物体的关系、比例、光影关系都要理解透彻。大体快可分割成多个x小体块。其实当年学习的绘画基础也是画好手绘的基础&#xff0c;画手绘依然需要去理解整体画面的空间黑白灰、物体穿插…

internetreadfile读取数据长度为0_【完结】TensorFlow2.0 快速上手手册

大家好&#xff0c;这是专栏《TensorFlow2.0》的第五篇文章&#xff0c;我们对专栏《TensorFlow2.0》进行一个总结。我们知道全新的TensorFlow2.0 Alpha已经于2019年3月被发布&#xff0c;新版本对TensorFLow的使用方式进行了重大改进&#xff0c;为了满足各位AI人对TensorFlow…

Facial Landmark Detection(人脸特征点检测)

原文地址&#xff1a;http://www.learnopencv.com/facial-landmark-detection/#comment-2471797375 作为计算机视觉研究员&#xff0c;我们很早就开始研究人脸。人脸分析领域最广为人知的就是人脸识别&#xff08;face recognition&#xff09;.但是为了识别一幅图像中的人脸&…

Java中的Error和Exceptiond的异同点

Error和Exception的异同点&#xff1a; &#xff08;1&#xff09;Error类和Exception类都继承超类Java.lang.Throwable &#xff08;2&#xff09;Error&#xff1a;一般指与虚拟机相关的问题&#xff0c;如系统崩溃&#xff0c;内存溢出等。对于这类错误&#xff0c;仅靠程序…

superviseddescent (SDM C++11实现)环境配置

今天试着用了一下SDM的C11实现&#xff0c;本来以为挺简单的&#xff0c;可是配置环境还是花了一些时间。为了给自己留下一些记忆&#xff0c;特把配置过程记录下来。 这个实现是C11的版本&#xff0c;是一个通用版本&#xff0c;里面包含了很多的功能&#xff0c;比如函数的最…