保留已经定位区域MATLAB,基于HSV肤色提取与连通区域过滤的人脸定位算法(Matlab)...

概述

本篇记录了利用基于HSV颜色模型的肤色提取与连通区域过滤实现图片的人脸定位,附带知识的介绍略烦多,附带Matlab相关程序代码。

一、预备知识

图像预处理

1.1 灰度化

在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫灰度值,因此,灰度图像每个像素只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。一般有分量法 最大值法平均值法加权平均法四种方法对彩色图像进行灰度化。

Matlab:Matlab:Matlab:

I = imread('img.jpg');

I2 = rgb2gray(I);

subpolt(1,2,1),imshow(I),title('原图');

subpolt(1,2,2),imshow(I2),title('灰度化');

1.2 锐化滤波

应用锐化可以快速聚焦模糊边缘,提高图像中某一部位的清晰度或者焦距程度,使图像特定区域的色彩更加

鲜明。

Matlab:Matlab:Matlab:

I = imread('img.jpg');

I2 = double(rgb2gray(I));

H = [0 1 0,1 -41,0 1 0];

J = conv2(I2,H,'same');

K = I2-J;

subplot(1,2,1),imshow(rgb2gray(I)),title('原图灰度化');

subplot(1,2,2),imshow(K,[]),title('锐化滤波');

1.3 中值滤波

中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。

中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号处理技术,中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替,让周围的像素值接近的真实值,从而消除孤立的噪声点。

Matlab:Matlab:Matlab:

I = imread('img.jpg');

I2 = medfilt2(rgb2gray(I),[9 9]); %9×9中值滤波

subplot(1,2,1),imshow(rgb2gray(I)),title('原图灰度化');

subplot(1,2,2),imshow(I2,[]),title('9×9中值滤波');

1.4 二值化

图像的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。

Matlab:Matlab:Matlab:

I = imread('img.jpg');

I2 = rgb2gray(I);%灰度化

thresh = graythresh(I2); %从原图确定二值化阈值;

I3 = im2bw(I2,thresh);%二值化

subplot(1,2,1),imshow(I2),title('原图灰度化');

subplot(1,2,2),imshow(I3),title('二值化');

1.5 形态学操作(腐蚀、膨胀、开操作、闭操作)

点我学习详细原理

几种颜色模型

2.1 RGB模型

最典型、最常用的面向硬件设备的彩色模型是三基色模型,即RGB模型。电视、摄像机和彩色扫描仪都是根据RGB模型工作的。RGB颜色模型建立在笛卡尔坐标系统里,其中三个坐标轴分别代表R、G、B,如图1所示,RGB模型是一个立方体,原点对应黑色,离原点最远的顶点对应白色。RGB是加色,是基于光的叠加的,红光加绿光加蓝光等于白光。应用于显示器这样的设备。

RGB颜色空间的主要缺点是不直观,从R、G、B的值中很难知道该值所代表颜色的认知属性,因此RGB颜色空间不符合人对颜色的感知心理。另外,RGB颜色空间是最不均匀的颜色空间之一,两种颜色之间的知觉差异不能采用该颜色空间中两个颜色点之间的距离来表示。

2.2 YCrCb模型

YCbCr模型中,Y是指亮度分量,Cb指蓝色色度分量,而Cr指红色色度分量。人的肉眼对视频的Y分量更敏感,因此在通过对色度分量进行子采样来减少色度分量后,肉眼将察觉不到的图像质量的变化。YCbCr模型常用与肤色检测中。

RGB转换YCbCr公式:

Y=0.299R+0.587G+0.114BY=0.299R+0.587G+0.114BY=0.299R+0.587G+0.114B

Cb=0.564(B−Y)Cb=0.564(B-Y)Cb=0.564(B−Y)

Cr=0.713(R−Y)Cr=0.713(R-Y)Cr=0.713(R−Y)

YCbCr转换RGB公式:

R=Y+1.402CrR=Y+1.402CrR=Y+1.402Cr

G=Y−0.344Cb−0.714CrG=Y-0.344Cb-0.714CrG=Y−0.344Cb−0.714Cr

B=Y+1.772CbB=Y+1.772CbB=Y+1.772Cb

2.3 HSV模型

HSV模型比HSI模型更与人类对颜色的感知接近。H代表色调,S代表饱和度,V代表亮度值。HSV模型的坐标系统可以是圆柱坐标系统,但一般用六棱锥来表示,如图3所示,与HSI模型比较相似。可以通过比较HSI、HSV与RGB空间的转换公式,来比较HSI与HSV的区别。

RGB空间转换HSV空间:

F=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪arccos{(R−G)+(R−B)2(R−G)2+(R−B)(G−B)√}2π−arccos(R−G)+(R−B)2(R−G)2+(R−B)(G−B)√B≤GB>GF=\left\{\begin{array}{rcl}\arccos\{\frac{(R-G)+(R-B)}{2\sqrt{(R-G)^2+(R-B)(G-B)}}\} & & {B \leq G}\\2\pi-\arccos{\frac{(R-G)+(R-B)}{2\sqrt{(R-G)^2+(R-B)(G-B)}}} & & {B > G}\\\end{array} \right.F=⎩⎨⎧​arccos{2(R−G)2+(R−B)(G−B)​(R−G)+(R−B)​}2π−arccos2(R−G)2+(R−B)(G−B)​(R−G)+(R−B)​​​B≤GB>G​

S=max(R,G,B)−min(R,G,B)max(R,G,B)S=\frac{\max(R,G,B)-\min(R,G,B)}{\max(R,G,B)}S=max(R,G,B)max(R,G,B)−min(R,G,B)​

V=max(R,G,B)255V=\frac{\max(R,G,B)}{255}V=255max(R,G,B)​

连通区域

在图像中,最小的单位是像素,每个像素周围有8个邻接像素,常见的邻接关系有2种:4邻接与8邻接。4邻接一共4个点,即上下左右,如下左图所示。8邻接的点一共有8个,包括了对角线位置的点,如下右图所示。

如果像素点A与B邻接,我们称A与B连通,于是我们不加证明的有如下的结论:

如果A与B连通,B与C连通,则A与C连通。

在视觉上看来,彼此连通的点形成了一个区域,而不连通的点形成了不同的区域。这样的一个所有的点彼此连通点构成的集合,我们称为一个连通区域。

下面这符图中,如果考虑4邻接,则有3个连通区域;如果考虑8邻接,则有2个连通区域。(注:图像是被放大的效果,图像正方形实际只有4个像素)。

二、图像人脸粗提取

1) HSV空间的肤色分割

彩色图像在RGB空间中描述,三基色不仅代表颜色,还代表了亮度,由于周围环境光照的改变。进行处理时,先把图像在RGB空间转换成HSV空间,在HSV空间进行阈值分割。

设:

I=I{R,G,B}I=I\{R,G,B\}I=I{R,G,B}

是一幅彩色人脸图像点阵,经过HSV肤色分割得到分割图

I2=I{H,S,V}I_2=I\{H,S,V\}I2​=I{H,S,V}

Matlab:skin.mMatlab: skin.mMatlab:skin.m

% 根据当前点的Cb Cr值判断是否为肤色

function result = skin(Y,Cb,Cr)

% 参数

a = 25.39;

b = 14.03;

ecx = 1.60;

ecy = 2.41;

sita = 2.53;

cx = 109.38;

cy = 152.02;

xishu = [cos(sita) sin(sita);-sin(sita) cos(sita)];

% 如果亮度大于230,则将长短轴同时扩大为原来的1.1倍

if(Y > 230)

a = 1.1*a;

b = 1.1*b;

end

% 根据公式进行计算

Cb = double(Cb);

Cr = double(Cr);

t = [(Cb-cx);(Cr-cy)];

temp = xishu*t;

value = (temp(1) - ecx)^2/a^2 + (temp(2) - ecy)^2/b^2;

% 大于1则不是肤色,返回0;否则为肤色,返回1

if value > 1

result = 0;

else

result = 1;

end

2) 边缘强化

在彩色测试图的R、G、B通道中,人脸肤色的像素多数集中在B通道,而且B通道含的背景像素最少,所以单选择在B通道进行边缘强化处理.

彩色人脸图像点阵III的BBB通道:

I1=I{0,0,B}I_1=I\{0,0,B\}I1​=I{0,0,B}

用一种高频增强算子

H=⎡⎣⎢0−10−12−10−10⎤⎦⎥H=\left[\begin{array}{ccc}0&-1&0\\-1&2&-1\\0&-1&0\end{array}\right]H=⎣⎡​0−10​−12−1​0−10​⎦⎤​

与BBB通道分量I1I_1I1​进行卷积锐化出边界图I3I_3I3​

用锐化后的边界图I3I_3I3​和HSV肤色分割图I2I_2I2​逻辑上相与得到边缘强化图I4I_4I4​。

I4=I3∧I2I_4=I_3∧I_2I4​=I3​∧I2​

4)中值滤波

中值滤波能够快速滤除一些细小的、零散的区域,对边缘强化图I4I_4I4​进行中值滤波处理能够清除图中细碎的背景得到I5I_5I5​。

三、连通区初步过滤条件

连通区的相关介绍和连通区的提起在上文已经有所介绍,下图是提取连通区的效果:

脸区域形状上大体与椭圆相似,而中值滤波后的边缘强化图中除了人脸的椭圆区域外,还有一些其它形状的区域,这些其它的形状基本上是非人脸区域。这些区域基本可以分为三角区域、矩形区域、细长的和弯曲的区域和面积相对较小的区域等4种。

针对这4种区域,分别采用面积密度、长宽比、致密度和面积滤波等4种几何形状特征的方法进行背景清除。

1) 面积密度

区域的面积与其最小外接矩形的面积的比值:

M=area(i)A(i)MERM=\frac{area(i)}{A_{MER}^{(i)}}M=AMER(i)​area(i)​

当区域为矩形时,比值(M)最大为1;当区域为圆形区域时,比值为π4\frac{\pi}{4}4π​;当区域为细长的、弯曲的物体时,比例变小。

当选取比值(M)= 0.4时,即可除去细长弯曲的区域和细长倾斜的区域。其中

area(i)=∑rowx=1∑coly=1l(x,y)area(i)=\sum_{x=1}^{row}\sum_{y=1}^{col}l(x,y)area(i)=x=1∑row​y=1∑col​l(x,y)

AMER=(lowi−topi)(righti−lefti)A_{MER}=(low_i-top_i)(right_i-left_i)AMER​=(lowi​−topi​)(righti​−lefti​)

对于二值图而言,1表示物体,0表示背景,面积就是统计每一个连通区域L(x,y)=1L(x,y)= 1L(x,y)=1的个数。

2) 长宽比

利用区域最小外接矩形长和宽的比例清除一些不符合正常的人脸比例的区域。

N=lowi−topirighti−leftiN=\frac{low_i-top_i}{right_i-left_i}N=righti​−lefti​lowi​−topi​​

3) 致密度

利用致密度可以除去一些近似矩形和三角形的区域,保留与人脸椭圆有相似性的区域。

N=c2iareaiN=\frac{c_i^2}{area_i}N=areai​ci2​​

通过实验资料,r设定阈值小于4或大于16就可以滤除一些矩形和三角区域。

4) 面积滤波

采用相对重要性滤波的方法来滤除较小的面积区域。用肤色最大的面积与整幅图的面积相比,然后设定一个阈值®,当面积比小于某个值,就把某些面积较小的区域滤除。

S=row×colS=row \times colS=row×col

R=Max(area)SR=\frac{Max(area)}{S}R=SMax(area)​

根据测试资料,将阈值R设为0.1,当R≥10%时,把面积小于95的区域滤除;当R≤10%时,把面积小于70的区域滤除。

连通区提取效果:

应用粗过滤条件后的人脸区域定位效果如图:

Matab:facedetection.mMatab: facedetection.mMatab:facedetection.m

function facedetection(img_name)

% 读取RGB图像

I = imread(img_name);

% 转换为灰度图像

gray = rgb2gray(I);

% 将图像转化为YCbCr颜色空间

YCbCr = rgb2ycbcr(I);

% 获得图像宽度和高度

heigth = size(gray,1);

width = size(gray,2);

% 根据肤色模型将图像二值化

for i = 1:heigth

for j = 1:width

Y = YCbCr(i,j,1);

Cb = YCbCr(i,j,2);

Cr = YCbCr(i,j,3);

if(Y < 80)

gray(i,j) = 0;

else

if(skin(Y,Cb,Cr) == 1)

gray(i,j) = 255;

else

gray(i,j) = 0;

end

end

end

end

% 二值图像形态学处理

SE=strel('arbitrary',eye(5));

%gray = bwmorph(gray,'erode');

% imopen先腐蚀再膨胀

gray = imopen(gray,SE);

% imclose先膨胀再腐蚀

%gray = imclose(gray,SE);

imshow(gray);

% 取出图片中所有包含白色区域的最小矩形

[L,num] = bwlabel(gray,8);

STATS = regionprops(L,'BoundingBox');

% 存放经过筛选以后得到的所有矩形块

n = 1;

result = zeros(n,4);

figure,imshow(I);

hold on;

for i = 1:num

box = STATS(i).BoundingBox;

x = box(1); %矩形坐标x

y = box(2); %矩形坐标y

w = box(3); %矩形宽度w

h = box(4); %矩形高度h

% 宽度和高度的比例

ratio = h/w;

ux = uint8(x);

uy = uint8(y);

if ux > 1

ux = ux - 1;

end

if uy > 1

uy = uy - 1;

end

% 可能是人脸区域的矩形应满足以下条件:

% 1、高度和宽度必须都大于20,且矩形面积大于400

% 2、高度和宽度比率应该在范围(0.6,2)内

% 3、函数findeye返回值为1

if w < 20 || h < 20 || w*h < 400

continue

elseif ratio < 2 && ratio > 0.6 && findeye(gray,ux,uy,w,h) == 1

% 记录可能为人脸的矩形区域

result(n,:) = [ux uy w h];

n = n+1;

end

end

% 对可能是人脸的区域进行标记

if size(result,1) == 1 && result(1,1) > 0

rectangle('Position',[result(1,1),result(1,2),result(1,3),result(1,4)],'EdgeColor','r');

else

% 如果满足条件的矩形区域大于1则再根据其他信息进行筛选

for m = 1:size(result,1)

m1 = result(m,1);

m2 = result(m,2);

m3 = result(m,3);

m4 = result(m,4);

% 标记最终的人脸区域

if m1 + m3 < width && m2 + m4 < heigth

rectangle('Position',[m1,m2,m3,m4],'EdgeColor','r');

end

end

end

四、连通区深度过滤

对于上图可以看出,经过上述的背景消除算法滤除背景时,发现中间人物的手部区域与脸部特征近似,使用简单的粗过滤方法可能难以过滤完全。容易出现将手部误认定为脸部的可能,为了消除手部的干扰,在此定位结果的基础上采用几何匹配算法,将找不到眼睛的区域进行过滤,这样便可消除手部的影响,从而精确的将人脸定位。

基于几何匹配算法的眼部搜索

将一对连通区从图像区域中提取出来(设为X和Y)

规定X在Y的左边;X与Y连线倾角在[−π4,π4][-\frac{\pi}{4},\frac{\pi}{4}][−4π​,4π​]之间

设评价函数为EEE,计算它们作为一对眼睛的评价函数EEE,如果EEE超过一定的阈值, 那么认为这一对连通区所框选的对象很可能是一对眼睛。

定义评价函数:

E=exp{−4.8[0.4(S1−S2)2+0.2(S1+S2−1)2+0.2(θ1−θ)2+0.2(θ2−θ)2]}E=exp\{-4.8[0.4(S_1-S_2)^2+0.2(S_1+S_2-1)^2+0.2(\theta_1-\theta)^2+0.2(\theta_2-\theta)^2]\}E=exp{−4.8[0.4(S1​−S2​)2+0.2(S1​+S2​−1)2+0.2(θ1​−θ)2+0.2(θ2​−θ)2]}

类似的,可以探索嘴部的评价函数,最终有三个连通区提取到了眼嘴特征,定位如下:

不难得到经过深度过滤后的人脸定位结果:

Matlab:findeye.mMatlab: findeye.mMatlab:findeye.m

% 判断二值图像中是否含有可能是眼睛的块

% bImage----二值图像

% x---------矩形左上角顶点X坐标

% y---------矩形左上角顶点Y坐标

% w---------矩形宽度

% h---------矩形长度

% 如果有则返回值eye等于1,否则为0

function eye = findeye(bImage,x,y,w,h)

% 根据矩形相关属性得到二值图像中矩形区域中的数据

% 存放矩形区域二值图像信息

part = zeros(h,w);

% 二值化

for i = y:(y+h)

for j = x:(x+w)

if bImage(i,j) == 0

part(i-y+1,j-x+1) = 255;

else

part(i-y+1,j-x+1) = 0;

end

end

end

[L,num] = bwlabel(part,8);

% 如果区域中有两个以上的矩形则认为有眼睛

if num < 2

eye = 0;

else

eye = 1;

end

五、参考文章

六、深入阅读

[1] 张朝阳,潘保昌,郑胜林,彭绍湖. 基于消除背景的人脸定位方法. 广东工业大学学报.24(2):91-106,2007

[2] 倪健,董强,管国栋. 基于几何特征的人脸定位算法的改进.《微计算机信息》(测 控 自 动 化).22(5-1):241-242,2006

--- END ---

你可能感兴趣的:(保留已经定位区域MATLAB)