--neozng1@hnu.edu.cn
5.5.2. 统计特征和global-based方法
5.5.2.1. 基本模型
早期的计算机视觉任务(即深度网络出现之前)最关键的部分仍然是特征工程,即特征的提取和表示。以分类任务为例,我们需要找到一个好的特征表示,然后利用分类器(常常是SVM)进行类别区分。下面这张图很好地展现了识别的通用方法:
若能够提取到对于某些变换具有不变性的特征,对于识别的准确度将会大大提升。最常见的不变特征包括亮度不变、对比度不变、尺度不变、旋转不变。而对于在 5.1 中反复提及的特征的级别,我们可以提出以下的关系图:
进一步抽象,我们还可以得到所谓的语义信息(semantic info),即用人类的知识描述的可以抽象出某种概念(concept)的特征。像素级的显然是最低的特征层级,通过对像素进行操作如卷积、聚类、形态学处理等,我们可以得到稍微高级一些的特征如纹理、边缘(可以回看介绍CNN的部分);再往上就是形状、轮廓;最后逐渐上升到概念如苹果、汽车等。越高级的特征往往拥有更好的可分性,因为它们只属于少数几个不同的类别,而不像低级特征一样,为许多不同类别的物体所共有。但是高级特征却缺乏细节信息,这也是CNN中常用FPN进行特征融合的原因。
在本节余下的内容就将介绍在CNN和Transformer出现之前我们是如何提取并表示特征然后由此实现各种计算机视觉的任务的。通过这部分的学习相信你也可以找到深度学习方法和传统方法之间的联系,并更好地融会贯通。
最原始的图像识别/分类方法就是对像素级的特征进行匹配,没错,我们说的就是模板匹配。首先获得一张目标的图像作为模板,然后将此模板在输入图像上进行滑动,并逐窗口计算相似性。模板匹配利用的就是最低级的像素级特,显然是没有任何的不变性的,即使目标和模板有微小的不同,计算得到的方差都大得惊人。
5.5.2.2. 直方图特征
那么如果将特征稍微提升一个层级试试呢?这就是下面要说的直方图描述子。我们将一幅图像分割为数个网格,并将网格中的像素取平均得到的值进行统计,得到一个直方图。得到的直方图可以看作是一个离散分布,亦或是一个特征向量:
这样,我们就可以利用SVM或与anchor vector(参考向量)的内积来获取衣服图像的分类了。从三张熊猫的图片中我们可以发下,虽然它的头发生了轻微的转动,但是统计直方图总体上保持一致,是中间低两边高的形式,计算两个直方图的KL散度或欧氏距离,显然也不会差太多。稍微想想你就能发现,直方图统计拥有良好的旋转不变性和较小的平移不变性。
若是有颜色的图片,只需要分别统计RGB的直方图,将三者concatenate就得到了其特征向量。若希望拥有光照不变性,最简单的方法就是对直方图进行归一化/标准化,因为直方图统计的恰恰是gloabal feature,因此全局的亮度变化对于归一化后的特征不会产生太大的影响。对于不同角度顺逆光拍摄的照片,还可以恰当地使用前面介绍的直方图均衡化方法提高不同图片之间的差异性,防止直方图出现聚集。
不过,这种特征的缺点也很明显:它显然还是太过低级了,并且要求在分类的时候目标恰好占满整个画幅以弥补其不具有尺幅不变性的缺点,若没有占满则会引入大量的无意义的背景信息(虽然有时候背景特征是很关键的一个部分,可以提供和前景有关的语义特征和潜在信息,这种低级的统计特征显然无法捕获到两者的关联)。
5.5.2.3. gradient-based feature
顺着直方图的思路,还可以使用什么稍微高级一点的统计特征?联想图像处理中常用于获取边缘和纹理的方法:求梯度——梯度直方图(histogram of gradient)的方法就呼之欲出了。我们可以首先提取全图的梯度得到梯度图(一般在此之前先做一次高斯滤波,因为微分算子对噪声非常敏感),然后将梯度的方向划分为若干个bins(如每隔45度一个格点),最后增加该位置梯度位于对应方向上bin的值。
梯度直方图和一般的直方图的不同在于,梯度包含方向和模值,因此无法像像素值直方图一样用一维的向量来表示。当然,可以使用二维直方图进行统计,不过这会带来不同直方图间方差过大的问题。因此,我们采用这样的方法,将梯度的模值累加到属于其方向的bin内,得到梯度直方图。
例子如下,求梯度后得到方向(左侧)和模值(右侧),如左上角的(10,1),其落在0-40°的区间,故将其值累加到该bin中。
和像素值直方图一样,可以进行归一化,得到的向量就可以作为特征向量用于训练分类器了。虽然使用的特征比原来稍微高级了一些,但是缺少尺度不变性以及容易受到背景影响的缺点还是没有得到改善。那么应该如何区分背景信息和前景信息,提取最重要的特征呢?我们将在下章介绍local-distribution的时候再提。
5.5.2.4. PCA-face
这里再介绍一种经典的全局特征方法,PCA-face。看这个名字大概就能猜出他的过程:利用训练集中的数据进行主成分分析,然后将输入在top-k个分量上进行投影得到特征向量,并用该特征向量和不同的人脸计算内积选取距离最小的那个作为分类输出。不过稍有不同的是,它巧妙地将一张图分解为均值和残差部分,首先得到整个训练集的协方差矩阵,然后对协方差矩阵进行特征分解并取最大的k个特征向量作为basis,这样就可以把输入减去均值之后在“脸基”上进行投影得到输入图片的特征向量(注意此特征向量和特征分解中的特征向量含义不同)。
一张 m ∗ n m*n m∗n的图像本身作为二维输入,首先将其展平成一维的向量,计算所有 t t t张图像展开后的向量的均值,再将所有向量减去均值便得到单张图像的残差。随后使用 t t t个 m ∗ n m*n m∗n的向量计算 m n ∗ m n mn*mn mn∗mn维的协方差矩阵,即 1 t ∑ i t x i x i T \frac{1}{t}\sum_i^t \mathbf{x_i}\mathbf{x_i^T} t1∑itxixiT。因此特征向量仍然是一个长为 m ∗ n m*n m∗n的向量,将其切分成原来的形状就得到图像。
特征分解得到的对应最大的那些特征值的向量就是那些最能凸显不同样本的特征,即数据集中的样本在该分量上的差异最大。因此选择这些向量作为face basis,使得输入在这些基上的投影有最大的差异程度,从而区分不同的人脸。这是将传统机器学习算法应用到cv的一个典型实例,其中蕴含的特征工程的核心思想非常值得学习。同样,这种方法本质上还是基于像素级特征实现的,其特征也没有什么不变性,只有当人脸的大小一致并且都处于图像的正中央才能取得比较好的效果,这里提到它主要是为了介绍其实现思路。