1. 基本概念
标定数据data/raw_300W_release.mat,包含BBOX和关键点。训练数据约3100个,关键点顺序:x1,x2…y1, y2…。
注意,源码中把关键点称为“Pose”。
68个关键点如下:
另外定义了一个simple_face数据,包含左眼、右眼、左嘴角、右嘴角。
设原始训练样本数为N,点数为L。
2. 核心数据结构
Pr:每一行表示对于一张图像,当前形状等于训练集形状的概率分布。共有N列,N为训练样本数,第i行第j列表示第i张图像的真实形状等于第j个训练集形状的概率。
在训练时,Pr尺寸为N×N;测试时,尺寸为1×N。
currentPose:每张图像对应一个当前形状。等价于论文中的subregion center,随着每次迭代逐步向真实值靠近。
Pr和currentPose轮流更新。
3. 核心思想
首先对图像进行面内旋转对齐(trainingsetGeneration/testingsetGeneration)
每次迭代中分为如下步骤
- 把Pr当做真实概率,从Pr生成本次迭代的初始形状(traintestReg/inferenceReg)
- 利用回归器,对初始形状施加偏移,得到currentPose(traintestReg/inferenceReg)
- 根据旋转预测模型,把图像进一步矫正对齐
- 把currentPose当做真实形状,计算Pr。(traintestP/inferenceP)
较重要/创新之处包括:
- 对齐
使用了图像中部的网格HOG特征,预测面内旋转角度。和SDM相比,提高了对面内旋转鲁棒性。但测试中每次旋转要进行一次全图操作。
巧妙之处是,各使用一般样本训练了两个角度预测器,两者互为校验。
- 从概率生成初始化形状
非常有创意地使用了“当前形状等于训练集形状”的概率。缺点是测试时要存储一大批训练集形状,当然后期可以筛选使用。
在测试时,每张图片会生成多个初始化形状,扩大搜索范围。
- 用回归器偏移初始形状
和SDM类似,所用的次数更少。
在测试时,多个初始形状的偏移结果使用自适应权重进行融合。这种方法解决了回归类方法“不知道自己对不对”的问题。
- 从当前形状估计概率分布
是本文最复杂的部分。除了用形状偏差的高斯函数之外,试图引入图像本身的纹理信息。这一步骤是必须的,否则概率只和当前形状有关,和图像没有关系。
这一项的设计非常扭曲:如果点所在位置的纹理靠谱,则使用当前位置计算概率;否则用训练集中的代表性数据计算。具体参看源码详解。
4. 整个算法中使用了许多模型,为避免混淆,列表如下
|
B |
PCA |
reg_model |
svc_ |
训练 |
trainingsetGeneration |
traintestReg |
traintestReg |
traintestP |
测试 |
testingsetGeneration |
inferenceReg |
inferenceReg |
inference |
用途 |
旋转图像,归一化 |
压缩点特征 |
更新当前形状 |
把纹理引入后验概率 |
输入 |
图像中部,3*3窗口HOG |
所有点上SIFT特征 |
前述压缩后的SIFT特征 |
每个semantic点上,3尺度SIFT |
维度 |
3*3*31 = 279 |
128*68 = 8704 |
约3000维 |
3*128 |
分类器 |
TreeBagger训练的ensemble of bagged decision trees |
PCA |
HalfBaggin训练的回归器 |
libsvm中的SVC |
输出 |
图像面内旋转角度 |
压缩5%后约3000维特征 |
关键点偏移量 |
该点准确/不准确 |
下半篇将逐行解读源码。