付 波 徐 超 赵熙临 郑 璇
(湖北工业大学太阳能高校利用及储能运行控制湖北省重点实验室 湖北 武汉 430068)
随着技术发展,人脸识别已成为当前计算机技术领域的一个研究热点[1],并逐渐融入社会生活,目前已经广泛应用到安全监测、目标跟踪等方面。该技术通过提取人的脸部特征点,利用统计学原理获得特征表达,建立人脸特征模板与被测者的人脸进行特征匹配,从而确定被测者的身份信息。
对于人脸部特征的提取,当前较成熟的技术是LBP算法。LBP算法最早由 Ojala等[2-3]在1994年提出,通过比较3×3模板中心像素与其邻域像素的大小,得到邻域像素的二进制代码,从而得到LBP特征,该算法原理简单、计算量小,但容易缺失局部纹理细节。赵建民等[4]在局部二值模式的纹理提取基础上,引进一种新型局部三值模式(LTP)纹理特征提取方法,此方法对光照变化和噪声更加鲁棒,但其编码存在不确定性,在其灰度范围内不具有严格的单调不变性。王宪等[5]提出了基于分块的完备局部二值模式 (CLBP)人脸识别算法,该算法对原始人脸图像进行分块处理,对每一分块的图像进行局部差异值和中心像素灰度值分析,加强了中心像素与邻域像素的联系,但计算复杂、耗时长。
本文提出的最值平均LBP算法,取3×3模板九个像素值的方差,若方差在限定范围内,将中心像素周围八个像素的最大值与最小值的平均值作为阈值进行比较,否则取九个像素的中值作为阈值进行比较,避免了LBP出现部分因中心像素值偏大或偏小以致湮没细节的现象,保留更多局部细节。然后运用PCA对特征矩阵维数进行降维,提取有效信息,利用K近邻分类算法对不同人脸进行识别分类,实验结果证明了该算法的有效性。
如图1所示,局部二值模式将图像中某像素点灰度值与其邻域像素点灰度值逐一比较。
图1中灰色区域为阈值, Δ为起始点,→为方向。图1(a)是某像素点3×3移动模板,将中心像素灰度值设定为阈值,若邻域8个像素值大于等于阈值,将该邻域像素值设置为1,反之为0。设置起始点后,可得一个8位二进制数,如图1(b)所示。从起始点按(顺时针方向)设置后各像素权重,如图1(c)所示,将中心像素点周围的11110001二进制数转化为十进制数,即是该中心像素点的LBP值(LBP=1+16+32+64+128=241),如图1(d)所示。其公式为:
(1)
式中:s是标记中心像素周围八个近邻像素点,Ps代表其像素值,Pj代表中心像素点的像素值,LBPpj表示LBP码,t(r)是符号函数。提取人脸的LBP特征图像如图2所示,其中图2(a)为原始人脸灰度图像,图2(b)为LBP特征图像。
(a) 原始灰度图 (b) LBP特征图图2 特征提取
为了提取更多有效的特征信息,将人脸图像进行均等分块,并将每个分块的LBP特征进行直方图统计[6],然后串连成特征向量,得到直方图矢量,本文使用3×3分块模式,如图3所示。
LBP算法原理简单,计算量较小,并且在各像素相对位置不发生变化的情况下,LBP值对于像素值单调变化具有不变性,有利于特征纹理描述。
为了了解细节特征,利用方差[7]测试了3×3模板像素值的波动范围。当波动较小时,特征较平缓,容易出现中心像素偏大或偏小;当波动较大时,特征变化加大,容易形成噪声。为此提出了最值平均法。最值平均法取3×3模板九个像素的方差,若方差在限定范围内,将中心像素周围八个像素的最大值与最小值的平均值作为阈值进行比较,避免因中心像素值偏大或偏小以致湮没细节的现象,否则取九个像素的中值[8]作为阈值,与周围八个像素值进行比较,减少噪声的影响,重新计算LBP码,以更新中心像素值。
该算法流程如下:
1) 针对某像素构造3×3模板,计算模板中九个像素的方差V,其公式为:
(2)
式中:M为九个像素的平均值,Pj为模板九个像素值;
2) 设定阈值a,判断V是否小于阈值a;
3) 若步骤2返回为真,取中心像素邻域8像素的最大值Ymax,最小值Ymin,将Ma=(Ymax+Ymin)/2设为3×3模板的阈值;
4) 若步骤2返回为假,将九个像素的中值作为阈值Ma;
5) 将模板中的8邻域像素值与Ma比较得到二进制图像;
6) 将该二进制图像转化为LBP码,得到新的LBP特征图。(步骤5、步骤6)的计算与式(1)的计算相同)
对图2(a)采用最值平均法计算LBP特征如图4所示。
图4 最值平均法特征图
与图2(b)对比可见,图4的纹理特征较图2(b)更清晰,保留了更多的图像局部的细节特征,提高了纹理特征的提取效果,有利于实现对微小纹理特征的识别。
基于将PCA与K近邻相结合,本文提出了基于最值平均的人脸识别LBP算法,其算法流程如图5所示。
图5 流程图
本文的特征提取算法是将LBP进行改进的最值平均算法,其算法编程如下所示:
for i=2:m-1
//排列3×3模板像素
for j=2:n-1
k=1;
p=i-1;
for q=j-1:j+1
y(k)=img(p,q);
k=k+1;
end
p=i;
y(k)=img(p,j+1);
k=k+1;
p=i+1;
for q=j-1:j+1
y(k)=img(p,q);
k=k+1;
end
d=y(k-1);
y(k-1)=y(k-3);
y(k-3)=d;
p=i;
for q=j-1:j
y(k)=img(p,q);
k=k+1;
end
y1=y(1:8);
W=var(y);
//计算方差