非刚性人脸跟踪(3)

2019-09-01 18:37

Mat shape_mode::procruster(交错未加工的数据,按列(作为列) const Mat &X;//

const int itol ,//尝试迭代的最大次数 const float ftol)//收敛公差 {

int N=X.cols,n=X.rows/2; Mat Co,P=X.clone();//复制 for(int i=0;i

Mat p=P.col(i);//第i个形状

float mx=0,my=0;//计算块的中心 for(int j=0;j

mx+=p.fl(2*j); my+=p.fl(2*j+1); }

mx/=n;my/=n; }

for(int j=0;j

p.fl(2*j)-=mx;p.fl(2*j+1)-=my; } }

for(int iter=0;iter

Mat C=P*Mat::ones(N,1,CV_32F)/N;//计算归一化 normlize(C,C);//权威形状

if(iter>0) {if(norm(C,Co)

Mat R=this->rot_scale_align(P.col(i),C); for(int j=0;j

float x=P.fl(2*j,i),y=P.fl(2*j+1,i); P.fl(2*j,i)=R.fl(0,0)*x+R.fl(0,1)*y; P.fl(2*j+1,i)=R.fl(1,0)*x+R.fl(1,1)*y; } }

}return P;//返回procruste对齐的形状

}

这个算法开始通过每一个形状示例块的中心,接着通过一个迭代处理,即交替的计算权威的形状,因为所有图像的归一化均值,并且旋转和尺度化到最佳匹配的权威形状。估计的权威形状的标准化步骤需要固定尺度问题和防止将所有的形状缩小到0.这个尺度的选择是随意的,这里精选来迫使权威形状矢量C的长度到1.0,因为这个OpenCV的normalize函数的默认行为。计算面内旋转和尺度,最好通过下面的rot_scale_align函数使每一个形状的示例和当前估计的权威形状相一致。:

Mat shape_model::rot_scale_align(

cosnt Mat &src,//[x1;y1;,,,,xn;yn]原形状示例 const Mat &dst//目的形状 {

//构造线性系统

int n=src.rows/2;float 1=0,b=0,d=0; for(int i=0;i

d+=src.fl(2*i)*src.fl(2*i)+src.fl(2*i+1)*src.fl(2*i+1); a+= src.fl(2*i)*dst.fl(2*i )+src.fl(2*i+1)*dst.fl(2*i+1); b+= src.fl(2*i)*dst.fl(2*i+1)-src.fl(2*i+1)*dst.fl(2*i ); }

a/=d;b/=d;//解决线性系统

return (Mat_float(2,2)<

这个函数最小化下面的旋转和权威形状的不同的最小二乘。数学上可以表示如下:

这里最小二乘问题的解决采用闭合形式的解决,在下面的图像等式的右手边。注意而不是用来解决尺度和面内旋转的,在尺度化2D选择矩阵中他们是非线性的关系(尺度和面内选择),我们解决变量(a,b)。这个变量与尺度和旋转矩阵相关,如下:

Procureste对原始注释形状数据分析的可视化效果在下面的图像中阐述。每一个面部特征用唯一的颜色显示。转换标准化之后,人脸的结构开始显现出来,这里人脸特征簇的位置围绕他们均值的位置。迭代尺度和旋转标准化过程之后,特征簇变的更加紧凑并且他们的分布变

的由面部变形导致的变化更具有代表性。最后一点是重要的,因为这些变形我们将在接下来的部分尝试模型化。因此,Procruster分析的角色可以被认为是对原始数据的操作,这个操作将得到更好的人脸局部变形模型用来学习。

线性形状模型

面部变形模型的目的是找到一个紧凑的参数化代表,即人脸的形状在交叉身份和表情之间是怎么样变化的。采用不同复杂度水平,有很多方法可以达到这个目的。这些方法中最简单的是使用一个面部几何的线性表示。尽管它简单,特别地,当数据集中的人脸大部分是前向姿势时,它已经展示了精确地捕获面部变形的空间。它与它的非线性部分相比还有个优点是推断它表示的参数是一个非常简单和廉价的操作。这在跟踪期间,通过配置它来约束搜索过程是很重要的。

线性地模型化面部形状的主要思想在下面的图像阐述。这里,一个人脸形状,它有N个人脸特征组成,在2N维空间模型化为一个单点。线性模型化的目标是找到嵌入在这个2N维空间的低维超平面,所有人脸形状的点都位于2N维空间(即图像中绿色的点)。因为这个超平面仅跨度完整2N维空间的一个子集,它通常被称为子空间。子空间维数越低,人脸表示更加紧凑并且约束 更加强,这个约束强加于跟踪过程。这经常导致鲁棒性更高的跟踪。 然而,子空间维度的选择上要注意,以使有足够的容量张成所有人脸空间,但在张成的空间里又没有太多的非人脸形状(即图像中红色的点)。当从单个人模型化数据时,这应当被标识。获得人脸变化性的子空间通常比模式化多个身份有更高的紧凑性。这就是为什么指定人跟踪器的执行效果要比一般人好。

寻找最低维子空间(张成一个数据集)的过程成为主成份分析(PCA)。OpenCV实现了计算PCA的类,然而,它需要预先指定保留的子空间维数。因为这往往是很难确定的先验,常见的启发式是基于它所占的总的变化的分数比例来选择它。在shape_model::train函数中,PCA的实现如下:

SVD svd(dY*dY.t());

int m=min(min(kmax,N-1),n-1); float vsum=0;

for(int i=0;i

v+=svd.w.fl(k);

if(v/vsum>=frac){k++;break;} }

if(k>m) k=m;

Mat D=svd.u(Rect(0,0,k,2*n));

这里,dy变量的每一列表示减去均值的Procrustes对齐形状。因此,奇异值分解SVD有效的应用到形状数据的协方差矩阵(即,dY.t()*dY)。OpenCV的SVD类的w成员存储着数据变化性的主要方向的变量,从最大到最小排序。一个选择子空间维数的普通方法是选择保存数据总能量分数frac的方向最小集(即占总能量的比例为frac),这是通过svd.w.记录表示的,因为这些记录是从最大的到最小的排序的,它充分地用来评估子空间,通过用变化性方向的最大值k来评估能量。他们自己的方向存储在SVD类的u成员内。svd.w和svd.u成分一般分别被成为特征谱和特征矢量。这两个成分的可视化如下图表:

注释:

注意特征谱的迅速下降表明,包含在数据中的主要变化可以用低维子空间进行模型化。

局部——全局的组合表示

图像帧中形状是通过局部变形和全局转换组合产生的。数学上,这个参数化是不确定的,因为这种转变的组成导致一个非线性的函数,该函数没有闭合形式的解。绕过这个问题的一个普通的方法是把全局转换模型为一个线性子空间并且把它添加到变形子空间。为了得到一个固定的形状,可以用一个子空间模式化一个类似的转换。如下:

在shape_model类中,这个子空间的 通过calc_rigid_basis函数产生,来至产生这个子空间的形状(即前面等式中x和y成分)是Procuses对齐形状值(即,权威的形状)。另外用前面提到的形式构造子空间,矩阵的每一列归一化为单位长度。在shape_model::train函数中,先前部分描述的dy是通过映射附属于刚性运动数据成分计算得到的。如下: Mat R=this->calc_rigid_basis(Y);//计算刚性子空间 Mat P=R.t()*Y;Mat dy=Y-R*P//产生出的刚性 注意这个投影是通过简单的矩阵乘法实现的。这可能是因为刚性子空间列已经进行了长度归一化。这并没有改变模型张开的空间,并且仅意味着R.t()*R等价与单位矩阵。


非刚性人脸跟踪(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:东北师范大学《算法分析与设计》18秋在线作业1

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: