人脸识别首先需要获取识别对象的人脸照片。这些照片在计算机中存储的常见格式是以“.jpg”结尾的jpg格式文件,下面以此文件格式为例进行讲解。一张彩色照片在计算机中通过RGB三原色显示色彩,其中,
R表示红色(Red);
G表示绿色(Green);
B表示蓝色(Blue)。
人眼能够分辨的颜色都可以通过这三类颜色生成,这是三原色的名称来源。也就是说,通过调整这三种原色的比例,计算机可以存储和显示世界上千变万化的颜色。
这三种颜色的变化范围一般取为[0,255]。0表示这种原色不存在,而255表示这种原色最强。之所以采用这个范围,是因为255恰好可以用一个字节来表示,也就是可以用8位的二进制数11111111来表示。按照第二章讲的方法可以很方便地使用Python观察这种对应关系。
In[5]:0b11111111
Out[5]:255
还有一些软件用“三原色强度/255”这种“比例”来定义颜色。例如,(166,170,15)表示RGB的强度,这表示了图像上一个点的颜色;如果换作用小数表示的方式,就变成了(0.650 980 392 156 862 8,0.666 666 666 666 666 6,0.058 823 529 411 764 705)。这两种表示方法给出的点的颜色是一样的。
一张彩色图片使用上述表示方式就转换成了三个表格,这些表格叫作图片的通道,分别是R通道、G通道、B通道。如果有一个4×4(长×宽)大小的图片,就一共有16个像素(4×4),每个像素都有三个分量(R,G,B),它们对应的表格如表8-2所示。从表中可以看出,第(1,1)个像素 RGB的强度分别是(187,187,187),第(3,3)个像素RGB 的强度分别是(205,167,187)等。
表8-2 三通道示例
没有彩色信息的黑白图像称为灰度图像。存储这种形式的图片无须RGB通道这样的三个表格,只需要一个表示黑白强度的表(矩阵)就可以把它表示出来。这时候0表示纯黑,而255表示纯白,中间的数值表示该点的灰度介于纯黑和纯白之间。
彩色图片也可以转换成灰度图片,这种转换可以通过一个通用的函数来进行。
Gray(x,y)=f(r(x,y),g(x,y),b(x,y))
这里Gray(x,y)表示坐标为(x,y)的点的灰度;r(x,y)表示坐标为(x,y)的点的R通道强度(比例);g(x,y)表示坐标为(x,y)的点的G通道强度(比例);b(x,y)表示坐标为(x,y)的点的B通道强度(比例)。
在Python中有现成的模块可以用来显示或转换图片。本教材使用PIL模块,如果没有安装,需要先在命令行模式下使用pip install进行安装。
pip install PIL
通过以下命令调用PIL的Image组件,其中用到的图片文件可以在教材资源平台下载。
In[6]:from PIL import Image
In[7]:im=Image.open('Bin.jpg')
#打开图片
In[8]:im.show()
#显示图像
In[9]:grayim=im.convert('L')
#将图像转化为灰度图
In[10]:grayim.show()
#显示灰度图
图像数据可以看成是一个数组。所谓数组就是按顺序排列的一组数。在Python中,数组用下列形式表示。
(x1,x2,...,xn)
其中xi(1≤i≤n)可以是数值也可以是一个数组。在Python中可以使用numpy模块查看数组形式的图片数据。
In[11]:import numpy as np
#使用numpy包
In[12]:imarray=np.array(im)
#将图像转化成数组表示
In[13]:imarray
#显示图像的数据
Out[13]:
array([[[ 28,38,27],
[ 28,38,27],
[ 28,38,27],
...,
...,
[ 82,86,113],
[ 84,88,115],
[ 82,86,113]]],dtype=uint8)
In[14]:imarray.shape
#给出图像数据的形状
Out[14]:(2333,1654,3)
从上述示例可以看到,转化成数组后,图像数据有长、宽、通道三个维度,图片中一共有2 333×1 654个点,其中[28,38,27]表示该点的三个颜色强度分别为28、38、27。
为了提高人脸识别的效率,在获取人脸照片后,一般需要先对照片进行裁剪,只保留脸部的图片信息,如图8-2所示。这个过程叫作脸部检测(Face Detection)。经过脸部检测后,计算机在识别中不必对整张图片进行匹配,只需要考虑脸部信息的匹配即可,所以可以大大减少数据比对的工作量。
图8-2 脸部检测和裁剪
脸部检测可以使用Harr-like特征完成。该特征有以下四类。
①边缘特征(Edge Features);
②线特征(Line Features);
③中心环绕特征(Center-Surround Features);
④对角线特征(Special Diagonal Line Feature Used In)。
这四类特征都是关于图像局部区域像素分布的描述,使用特定算法对图片各个区域进行扫描,获取与人脸具有相似特征的区域,就可以实现人脸检测了(图8-3)。
图8-3 四类像素分布特征
人脸检测其实是一个二分类的问题,即是人脸,非人脸。
可以使用本教材讲过的决策树[1]实现这种分类,按照如下流程训练分类器。
输入图像—图像预处理—提取特征—训练分类器(二分类)—得到训练好的模型(Harr-like+决策树)。
使用训练好的分类器,按照如下流程进行脸部检测。
输入图像—图像预处理—提取特征—导入训练好的模型—二分类(是不是人脸)。
接下来假设脸部检测已经完成,并已经对照片根据检测结果进行了裁剪,即接下来需要处理的照片是只包含脸部的照片。人脸识别将把未知照片与已有照片进行对比,从已有照片中找出与未知照片最相似的那一个,从而实现判定未知照片是谁的照片。例如,经过对比后得到表8-3。
表8-3 脸部相似排序示例
从表中可以看出,输入的新照片与已有的照片数据库中张三的照片相似程度最高,据此可以判定,被识别的这张人脸是张三的。
为了实施这个识别方法,需要解决的一个关键问题是,如何比较人脸的相似程度。
判断两张照片的相似性,可以通过如下三种方式进行。
(1)距离相似性
使用第五章讲过的欧式距离,距离越近,相似程度越高。
以灰度图像为例,假设进行对比的两张照片都有n×m个像素,则像素灰度所对应的矩阵为
它们的距离定义为
(2)余弦相似性
这也是在第五章讲过的一种衡量相似性的方法。为了计算余弦相似性,需要将图片以向量形式描述(一行或者一列数据)。两张灰度图片X和Y,此时写成如下形式。
x=(x1,1,x1,2,···,x1,m,x2,1,···,x2,m,···,xn,1,···,xn,m)
Y=(Y1,1,Y1,2,···,Y1,m,Y2,1,···,Y2,m,···,Yn,1,···,Yn,m)
按照第五章给出的计算公式
进行计算。计算出的余弦值越大,则相似性越高。
(3)结合直方图和上述两种距离计算相似性
直方图是一种可以将图片信息压缩表示的工具,使用直方图,可以提取图像的一些特征。对人脸照片进行直方图统计有细颗粒度和粗颗粒度两种方式,可以根据具体情况选用。下面以灰度图为例。
①细颗粒度。计算不同灰度值的像素数占总像素数的比例。因为灰度值介于[0,255],所以最终得到包含256个数值的特征。
②粗颗粒度。将[0,255]划分成多个子区间,然后统计直方图。例如,每8个灰度作为一个区间,一共划分成32个区间,进行统计后得到32个特征;如果每16个灰度作为一个区间,则最终会得到16个特征。获取直方图后,就可以使用1或2中的方法比较相似度了。
作为练习,读者可以分别使用这三种方法比较如图8-4所示的两张图片的相似性。
图8-4