今天同学让我帮忙制作一个人脸表情识别的样本库,当中主要是对人脸进行裁剪,这里用到了一个相对较新的Matlab人脸检測方法Face Parts Detection。网上百度了一下发现关于Matlab人脸检測的代码和资源并不多。故此专门撰写一篇博客来具体介绍这个人脸检測方法的用途。

  一、下载相应的工具包

  首先下载相应的工具包。matlab最方便的地方莫过于此了。直接下载、配置简单、而且能够查看源代码,这里给出相应的工具包下载地址:Face Parts Detection工具包

  点击“Download Zip”下载button開始下载,下载完毕后解压,得到例如以下文件:

  二、配置工具包

  下载完毕后開始配置工具箱。首先须要强调一点,这种方法须要依赖两个Matlab图像处理方面的工具箱Image Processing ToolboxComputer Vision System Toolbox。差点儿全部版本号的Matlab都默认集成了Image Processing工具箱。但对于Computer Vision System工具箱仅仅有相对较高版本号(Matlab2013及以上)的Matlab版本号才进行了集成,因此假设在程序运行过程中提示缺少相应的工具箱,则须要手动进行配置Computer Vision System。

  假设Matlab已经配置好了以上两个工具箱,接下来開始配置Face Parts Detection工具包,方法极其简单,仅仅需在Set Path对话框中将当前工具箱的目录(这里是Face_detection_Parts目录)路径加入到系统的搜索路径就可以:

  三、进行批量人脸检測

  工具箱配置完毕后開始利用其进行人脸检測。

  3.1、批量读取图片

  首先,须要对数据库中的图像进行批量读取,读取完之后再进行人脸检測。首先给出批量读取的代码。稍后解释:

clear;
stImageFilePath = 'E:\CAS-PEAL-R1(1)\CAS-PEAL-R1\FRONTAL\Expression\';
stImageSavePath = 'E:\Face_Detection\';
dirImagePathList = dir(strcat(stImageFilePath,'*.tif')); %读取该目录下全部图片的路径(字符串格式)
iImageNum = length(dirImagePathList); %获取图片的总数量
if iImageNum > 0 %批量读入图片,进行五官检測,再批量检測
for i = 1 : iImageNum
iSaveNum = int2str(i);
stImagePath = dirImagePathList(i).name;
mImageCurrent = imread(strcat(stImageFilePath,stImagePath));
end
end

  这里採用dir()函数的方法来读取目录下全部文件的文件名称,dirImagePathList(i).name中保存了目录下的全部文件的名称。

有关Matlab中dir()函数的使用方法大家能够參考网络资料。

stImageFilePath变量保存了当前图片所在目录的路径(这里为E:\CAS-PEAL-R1(1)\CAS-PEAL-R1\FRONTAL\Expression\),stImageSavePath变量指定了裁剪之后的人脸图像的保存路径。

这里须要注意的一点就是保存裁剪结果的目录须要事先创建好(或者在程序中通过mkdir等函数来提前创建)。通过strcat()函数来推断当前图像名称中是否包括“.tif”来确定其是否为图像文件(这里的数据库中的图像文件都是tif格式的),

  3.2、编写人脸检測函数

  批量读取图像完毕后。開始进行人脸检測,这里选择将人脸检測封装为一个脚本文件方便调用。这里暂且将其命名为face_segment.m文件。

  首先,须要推断当前图像的通道数,由于Face Parts Detection方法仅仅能针对三通道图像进行人脸检測,假设当前图像为灰度图(单通道图)。则须要先将其转换为三通道矩阵形式:

%%%%%%%%%%%%%%%%%%%%将灰度图变为三通道图%%%%%%%%%%%%%%%%%%%%
if(size(mImageSrc,3) == 1)
mImage2detect(:,:,1) = mImageSrc;
mImage2detect(:,:,2) = mImageSrc;
mImage2detect(:,:,3) = mImageSrc;
else
mImage2detect = mImageSrc;
end

  然后開始调用工具箱进行人脸检測。就两句代码就可以(可见作者将程序封装得何其之好):

%%%%%%%%%%%%%%%%%%%%对图像进行人脸检測%%%%%%%%%%%%%%%%%%%%
FaceDetector = buildDetector();
[bbox,bbimg,faces,bbfaces] = detectFaceParts(FaceDetector,mImage2detect,2);

  对于bbox,bbimg,faces,bbfaces这四个检測结果的具体含义,在detectFaceParts.m文件的开头部分作者给出了具体的解释,我们这里仅仅用到bbox这个变量。它里面分别保存了所检測出的人脸区域(一个矩形框)的左上角坐标以及宽度和高度。

  检測完毕之后。再统一将图像转换为灰度图,保证格式的统一。方便保存:

%%%%%%%%%%%%%%%%%%%%输入图像灰度化%%%%%%%%%%%%%%%%%%%%
if 1 ~= size(mImageSrc,3)
mImageSrc = rgb2gray(mImageSrc);
mImageSrc = double(mImageSrc);
elseif 1 == size(mImageSrc,3)
mImageSrc = double(mImageSrc);
end

  接下来開始对人脸区域进行切割。这个有两种切割策略,一种是直接使用检測到的人脸框bbox对原图进行截取,在不可控的採集条件下仅仅能用这样的方法来切割人脸。另外一种策略是针对人脸框bbox首先确定人脸区域的中心点,然后再以中心点为基准向四周依照一定比例进行外扩,这样的方法仅适合採集条件严格可控、人脸大致对齐的人脸数据库,恰好我们所处理的数据库满足这样的要求。因此在这里採用另外一种策略进行人脸区域切割,代码例如以下:

%%%%%%%%%%%%%%%%%%%%得到人脸区域框的中心点%%%%%%%%%%%%%%%%%%%%
recFace.x = bbox(1,1);
recFace.y = bbox(1,2);
recFace.width = bbox(1,3);
recFace.height = bbox(1,4); ptFaceCenter.x = recFace.x + recFace.width / 2;
ptFaceCenter.y = recFace.y + recFace.height / 2; %%%%%%%%%%%%%%%%%%%%以中心点为基准进行外扩(即对人脸选框进行调整)%%%%%%%%%%%%%%%%%%%%
recFace.x = ptFaceCenter.x - recFace.width * 0.4;
recFace.y = ptFaceCenter.y - recFace.height * 0.35;
recFace.width = recFace.width * 0.8 ;
recFace.height = recFace.height * 0.8 ; mFaceResult = uint8(imcrop(mImageSrc,[recFace.x,recFace.y,recFace.width,recFace.height]));

  这里仅仅涉及到了简单的几何知识,因此不再赘述。确定好人脸矩形区域之后,使用imcrop()函数进行区域切割。这里给出face_segment.m文件的完整代码:

%===============================================================================
%函数名称:face_segment
%输入參数:mImageSrc,待切割的人脸图像。可能是灰度图像,也可能是彩色图像
%输出參数:mFaceResult,切割后的人脸结果,应为灰度图像
%主要步骤:1)进行人脸检測,得到脸部区域的框框
% 2)得到脸部图像框的中心点
% 3)依据中心点。对图像进行等比例外扩,得到合适大小的人脸图像
%注意事项:1)首先须要推断该图像是否为灰度图。若为灰度图,须要先将其转换为三通道彩色图
%===============================================================================
function mFaceResult = face_segment(mImageSrc)
%%%%%%%%%%%%%%%%%%%%将灰度图变为三通道图%%%%%%%%%%%%%%%%%%%%
if(size(mImageSrc,3) == 1)
mImage2detect(:,:,1) = mImageSrc;
mImage2detect(:,:,2) = mImageSrc;
mImage2detect(:,:,3) = mImageSrc;
else
mImage2detect = mImageSrc;
end %%%%%%%%%%%%%%%%%%%%对图像进行人脸检測%%%%%%%%%%%%%%%%%%%%
FaceDetector = buildDetector();
[bbox,bbimg,faces,bbfaces] = detectFaceParts(FaceDetector,mImage2detect,2); %%%%%%%%%%%%%%%%%%%%输入图像灰度化%%%%%%%%%%%%%%%%%%%%
if 1 ~= size(mImageSrc,3)
mImageSrc = rgb2gray(mImageSrc);
mImageSrc = double(mImageSrc);
elseif 1 == size(mImageSrc,3)
mImageSrc = double(mImageSrc);
end %%%%%%%%%%%%%%%%%%%%得到人脸区域框的中心点%%%%%%%%%%%%%%%%%%%%
recFace.x = bbox(1,1);
recFace.y = bbox(1,2);
recFace.width = bbox(1,3);
recFace.height = bbox(1,4); ptFaceCenter.x = recFace.x + recFace.width / 2;
ptFaceCenter.y = recFace.y + recFace.height / 2; %%%%%%%%%%%%%%%%%%%%以中心点为基准进行外扩(即对人脸选框进行调整)%%%%%%%%%%%%%%%%%%%%
recFace.x = ptFaceCenter.x - recFace.width * 0.4;
recFace.y = ptFaceCenter.y - recFace.height * 0.35;
recFace.width = recFace.width * 0.8 ;
recFace.height = recFace.height * 0.8 ; mFaceResult = uint8(imcrop(mImageSrc,[recFace.x,recFace.y,recFace.width,recFace.height]));
end

  四、人脸批量保存

  在完毕人脸检測函数之后,開始对人脸进行检測切割和批量保存,这里直接给出代码:

clear;
stImageFilePath = 'E:\CAS-PEAL-R1(1)\CAS-PEAL-R1\FRONTAL\Expression\';
stImageSavePath = 'E:\Face_Detection\';
dirImagePathList = dir(strcat(stImageFilePath,'*.tif')); %读取该目录下全部图片的路径(字符串格式)
iImageNum = length(dirImagePathList); %获取图片的总数量
if iImageNum > 0 %批量读入图片,进行五官检測,再批量检測
for i = 1 : iImageNum
iSaveNum = int2str(i);
stImagePath = dirImagePathList(i).name;
mImageCurrent = imread(strcat(stImageFilePath,stImagePath));
mFaceResult = face_segment(mImageCurrent);
imwrite(mFaceResult,strcat(stImageSavePath,iSaveNum,'.bmp')); end end

  这段代码的逻辑相对简单。调用strcat()字符串拼接函数来完毕检測结果的自己主动命名,考虑到版权问题,这里不粘贴终于的人脸切割结果,但程序亲測可用,没有问题。

  五、注意事项

  1、OpenCv人脸检測函数

  进行人脸检測是Matlab并非唯一选择,OpenCv也相同封装的人脸检測函数,只是OpenCv中封装的人脸检測函数是基于AdaBoost算法。相对经典而古老。性能不如本文中所介绍的人脸检測算法,而且OpenCv在读取tif格式的图像文件时显得异常麻烦。

  2、原理介绍

  在这篇博文中我们仅仅介绍了Face Parts Detection算法的具体使用方法,至于去人脸检測原理,将来有时间了我再专门写博文进行介绍。

  3、打不开MathWork官网的话我能够给发邮箱

  假设出现不能正常登陆MathWork站点,无法下载工具箱的情况。能够给我发邮件,我会抓时间提供相应的工具箱

  4、灰度图不等于单通道图

  在这里再强调一个小问题。就是灰度图与单通道图的关系,理论上来说这两个名词全然属于不同的概念。灰度图不一定是单通道图。由于三个通道的RGB值均相等的三通道图在视觉上相同变现为灰度图。只是单通道图肯定是灰度图。

Matlab人脸检測方法(Face Parts Detection)具体解释的更多相关文章

  1. 【从零学习openCV】IOS7下的人脸检測

    前言: 人脸检測与识别一直是计算机视觉领域一大热门研究方向,并且也从安全监控等工业级的应用扩展到了手机移动端的app,总之随着人脸识别技术获得突破,其应用前景和市场价值都是不可估量的,眼下在学习ope ...

  2. 利用opencv中的级联分类器进行人脸检測-opencv学习(1)

    OpenCV支持的目标检測的方法是利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification).注意,新版本号的C++接口除了Haar特征以外 ...

  3. Viola-Jones人脸检測

    OpenCV中有一个基于树的技术:Haar分类器,它建立了boost筛选式级联. 它能够识别出人脸和其它刚性物体. 对于检測"基本刚性"的物体(脸,汽车,自行车,人体等)这类识别任 ...

  4. OpenFace库(Tadas Baltrusaitis)中基于Haar Cascade Classifiers进行人脸检測的測试代码

    Tadas Baltrusaitis的OpenFace是一个开源的面部行为分析工具.它的源代码能够从 https://github.com/TadasBaltrusaitis/OpenFace 下载. ...

  5. OpenCv 人脸检測的学习

    近期公司要组织开发分享,可是自己还是新手真的不知道分享啥了,然后看了看前段时间研究过OpenCv,那么就分享他把. openCv就不介绍了,说下人脸检測.事实上是通过openCv里边已经训练好的xml ...

  6. 基于QT和OpenCV的人脸检測识别系统(1)

    人脸识别分为两大步骤 1.人脸检測 这个是首要实现的.你得实现人脸显示的时候把人脸框出来,当然算法非常多,另一些人眼检測鼻子检測什么的 主要用的是这个 const char *faceCascadeF ...

  7. C++开发人脸性别识别教程(10)——加入图片的人脸检測程序

    现在我们的MFC框架已经初具规模,能够读取并显示目录下的图片.在这篇博文中我们将向当中加入人脸检測的程序. 一.人脸检測算法 这里我们使用OpenCv封装的Adaboost方法来进行人脸检測,參见:C ...

  8. OpenCV人脸检測(完整源代码+思路)

    本博文IDE为vs2013 OpenCV2.49 话不多说,先看视频演示(20S演示): 例如以下: https://v.youku.com/v_show/id_XMjYzMzkxMTYyMA==.h ...

  9. 基于QT和OpenCV的人脸检測识别系统(2)

    紧接着上一篇博客的讲 第二步是识别部分 人脸识别 把上一阶段检測处理得到的人脸图像与数据库中的已知 人脸进行比对,判定人脸相应的人是谁(此处以白色文本显示). 人脸预处理 如今你已经得到一张人脸,你能 ...

随机推荐

  1. Unity 游戏框架搭建 (十九) 简易对象池

    在Unity中我们经常会用到对象池,使用对象池无非就是解决两个问题: 一是减少new时候寻址造成的消耗,该消耗的原因是内存碎片. 二是减少Object.Instantiate时内部进行序列化和反序列化 ...

  2. [MYSQL] 记一次MySQL性能调优

    最近在做数据迁移工作,已有一堆数据文件,要把这些数据文件写到MySQL 数据库里面去. MySQL数据库上架了一层服务接口,可以直接调用.博主写了一个迁移程序,放在服务器A上. *********** ...

  3. day3--远程链接Linux

    互联网上的计算机,都会有一个唯一的32位的地址,IP地址 我们访问服务器,就必须通过这个IP地址 局域网里也有预留的IP地址,192/10/172开头.局域网的IP地址也是唯一的. NAT模式,电脑宿 ...

  4. whonix官网部分翻译

    Whonix:一个高安全的方式来Surfing the Internet Whonix是一个桌面操作系统,被设计用于高级安全和隐私.It realistically addresses attacks ...

  5. Thrift全面介绍

    官网:http://thrift.apache.org   简介 Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java ...

  6. [转载] ZooKeeper原理及使用

    转载自http://www.wuzesheng.com/?p=2609 ZooKeeper是Hadoop Ecosystem中非常重要的组件,它的主要功能是为分布式系统提供一致性协调(Coordina ...

  7. SpringAware

    哈哈,终于把分布式的课程演讲给混过去了,下面开始随便自己学点东西. 正题:SpringAware--------在实际项目中,用到spring容器的本省功能资源,这是Bean必须意识到Spring容器 ...

  8. short s1 = 1; s1 = s1 + 1;有错而short s1 = 1; s1 += 1正确。为何?

    如果你认为表达式(x += i)只是表达式(x = x + i)的简写方式,这并不准确.这两个表达式都被称为赋值表达式.第二个表达式使用的是简单赋值操作符(=),而第一个表达式使用的是复合赋值操作符. ...

  9. 下一个计划 : .NET/.NET Core应用性能管理系统

    前言 最近几个月一直在研究开源的APM和监控方案,并对比使用了Zipkin,CAT,Sky-walking,PinPoint(仅对比,未实际部署),Elastic APM,TICK Stack,Pro ...

  10. SoapUI实践:自动化测试、压力测试、持续集成

    因为项目的原因,前段时间研究并使用了 SoapUI 测试工具进行自测开发的 api.下面将研究的成果展示给大家,希望对需要的人有所帮助. SoapUI 是什么? SoapUI 是一个开源测试工具,通过 ...