数字图像处理是计算机科学专业的一门基础学科,而其中人脸识别及分割又是其中最为经典不可缺失的一部分。本文采用MATLAB-VISION包中强大的图像识别功能,对目标图像进行人脸识别。VISION中的级联分类器具有识别人脸,嘴巴,鼻子,左右眼等功能。并且准确度高,能在较为复杂的环境下识别出目标。
程序:
一.人脸识别及分割系统的设计
1.1系统总述
目前,人脸识别的方法有很多,研究的方法也不同,所以有不同的分类方法。根据我们所读入图像中人脸的角度不同,可分为正脸,侧脸的人脸识别。根据合个器官的肤色和形状不同,我们可有基于几何特征和基于肤色的人脸识别。根据读入图像的色彩不同,我们可有彩色和灰度图像的人脸识别。这里我们采用MATLAB-VISION中的trainCascadeObjectDetector分类器对图像进行识别,识别图像为PHOTO1并且将识别出的部分用红色的矩形框出来,便于编程者直观的调试程序。接下来,将图像用函数print();写入本地设为PHOTO2。再次读取刚才写入的图像,与原图对比,此时的图像在所识别的区域加上了一个红色的矩形框。接下来提取红色分量,形成一个只有矩形是红色背景全部为黑色的照片,同样保存。设为PHOTO3,读取PHOTO3,将红色矩形框全部填充再次保存为PHOTO4.
最后我们读取PHOTO1和PHOTO4,将这两幅图像进行点乘。便得到我们的目标图像。
二.各部分模块设计
2.1级联分类器的介绍
函数名称:TrainCasadeObjectDetector
函数功能:训练级联分类器
函数原型:
trainCasadeObjectDetector(outputXLMFilenname,positiveInstance,negativeImage;)
2.2识别目标
算法思想大体如下:
先调用MATLAB-VISION中CascadeObjectDetector级联分类器,用函数imread();读取图像,将图像转换为灰度图像,计算机识别出的目标并不能直观的展现给用户,这里我们采用将识别出的区域用红色的矩形框起来,以便于直观展示给用户。
部分代码参考如下:
for i =1:size(face_dtect,1)
rectangle('Position',face_dtect(i,:),'LineWidth',4,'LineStyle','-','EdgeColor','r');
end
rectangle();可通过形参设置显示框的线条宽度,种类,和颜色。这里我们设置线条的宽度为4,显示颜色为红色,并且用直线显示。
提取色彩分量:
先介绍一下HSV颜色模型:
HSV模型的三维表示从RGB立方体演化而来。设想从RGB沿立方体对角线的白色顶点向黑色顶点观察,就可以看到立方体的六边形外形。六边形边界表示色彩,水平轴表示纯度,明度沿垂直轴测量。[i]
这里我们以鼻子为例。首先读取图像,将GRB图像转换为HSV图像。将HSV图像中的红色分量提取出来设为S,再通过graythresh函数找到图片的一个合适的阈值,通过im2bw将灰度图像转化为二值图像。
部分代码参考如下:
shibie=imread('shibiebizi.png');
hsv=rgb2hsv(shibie);
s=hsv(:,:,2);
bw=im2bw(s,graythresh(s));
se=strel('disk',5);
bw2=imclose(bw,se);
bw3=bwareaopen(bw2,200);
figure(6);
imshow(bw3);
print(gcf,'-dpng','tiqubizi.png'); %保存为png格式的图片到当前路径
2.3填充区域
这里是将前面提取出的红色分量矩形进行填充,再进行后续步骤,先介绍一下填充的函数
Bwlabel();
L = bwlabel(BW,n)
返回一个和BW大小相同的L矩阵,包含了标记了BW中每个连通区域的类别,这里采用更为精确的8连通算法。
[L,num] = bwlabel(BW,n)这里num返回的就是BW中连通区域的个数。
部分代码参考如下:
tianchong =imread('tiqubizi.png')
J=tianchong(:,:,1);
K=J>30;%阈值分割,30通过工作空间观察得到
[L,num] = bwlabel(K,8);%8连通块标记
F=L>1;%除去周边区域
F(339,269)=1;%在工作空间中找到使最大目标不连通的点,赋值,使之连通
BW2 = imfill(F,'holes');%填充区域
imwrite(BW2,'tianchongbizi.png','png')%用imwrite写没有白边
2.4分割目标
将填充好的图像和原图点乘,二值图像中0代表黑色,1代表白色。所以处理后的图像只显示白色矩形中的原图。如果原图是灰度图像我们直接点乘,如果是RGB真彩色图像,我们要把图像中的R,G,B分量单独提取出来分别与原图点乘。
部分代码参考如下:
yuantu=imread('zheng.png');
figure(7);
imshow(yuantu)
print(gcf,'-dpng','whitephoto.png') %保存为png格式的图片到当前路径
yuantu_baibian=imread('whitephoto.png');
yan_tianchong= imread('tianchongbizi.png');
I= yuantu_baibian;
R= I(:,:,1);
G= I(:,:,2);
B= I(:,:,3);
m_BG=yan_tianchong;
m_BG=im2bw(m_BG,0.2);%阈值根据实际条件自行设置
%figure(5);imshow(m_BG,[]);
m_BG= uint8(m_BG);
R=R.*m_BG;
G=G.*m_BG;
B=B.*m_BG;
I(:,:,1)=R;
I(:,:,2)=G;
I(:,:,3)=B;
figure(9);imshow(I,[]);
imwrite(I,'Nose.png','png')%用imwrite写没有白边
2.5保存图像接
可以用 save(),imwrite(),或者printf();把图像保存在本地。
[i]HSV_百度百科