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.pswp.cn/news/259052.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/259052.shtml
英文地址,請注明出處:http://en.pswp.cn/news/259052.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

acm常見算法及例題

1 acm常見算法及例題2 3 初期:4 一.基本算法:5 (1)枚舉. (poj1753,poj2965)6 (2)貪心(poj1328,poj2109,poj2586)7 (3)遞歸和分治法.8 (4)遞推.9 (5)構造法.(poj3295)10 (6)模擬法.(poj1068,poj2632,poj1573,poj2993,poj2996)11 二.圖算法…

2爬蟲基礎了解

1.什么是爬蟲爬蟲&#xff0c;即網絡爬蟲&#xff0c;大家可以理解為在網絡上爬行的一直蜘蛛&#xff0c;互聯網就比作一張大網&#xff0c;而爬蟲便是在這張網上爬來爬去的蜘蛛咯&#xff0c;如果它遇到資源&#xff0c;那么它就會抓取下來。想抓取什么&#xff1f;這個由你來…

js(function(){alert(‘’‘)})

function(){alert(sss)}是個匿名函數。沒有名字。所以沒有辦法調用。在外面加個括號&#xff0c;就變成了一個值&#xff0c;值的內容是函數的引用。例如var a (function(){"nop"})a 就是對這個函數的引用。有了名字&#xff0c;之后可以調用&#xff0c;例如a()現在…

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. 分別求出來組合數的分子和分母然后相除/******************************…

級聯sql

select ID, PID, NAME,KEY from HS_DICT start with KEY HS_EXP_WORK_LOCATIONconnect by prior ID PID order by DISPLAYORDER轉載于:https://www.cnblogs.com/dazhaxie/p/3483532.html

獲取母版中的控件

1 通過findcontrol找控件ID需要在此事件中~因為Page_load中時是先內容頁加載然后才是母版頁加載 protected void Page_LoadComplete(object sender, EventArgs e) { Label2.Text "現在時間是" (Master.FindControl("Label1") as Label).Text; if (Reques…

linux服務器選ubantu或centos_如何通過SSH連接阿里云上的Linux系統

首先SSH是啥&#xff0c;維基一下&#xff1a;Secure Shell&#xff08;安全外殼協議&#xff0c;簡稱SSH&#xff09;是一種加密的網絡傳輸協議&#xff0c;可在不安全的網絡中為網絡服務提供安全的傳輸環境[1]。SSH通過在網絡中創建安全隧道來實現SSH客戶端與服務器之間的連接…

face alignment by 3000 fps系列學習總結

我們主要講一講Github上給出的matlab開源代碼《jwyang/face-alignment》的配置。 首先聲明&#xff1a;本人第一次配置的時候也是參考了csdn一個作者和github給出的說明配置成功的。其實后來想想很簡單的&#xff0c;但是可能對于初學者&#xff0c;還是有一定的困難。為此&am…

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…

【轉】jquery 注冊事件的方法

原文鏈接&#xff1a;http://outofmemory.cn/code-snippet/2123/jquery-zhuce-event-method 1.使用事件名來綁定&#xff0c;可用的事件名有 change,click,dblclick,error,focus,focusin,focusout,keydown,keypress,keyup,mousedown,mouseenter,mouseleave,mousemove,mouseout,…