前面一篇文章我们生成了脸部特征的线性形状模型,本章来学习一下显示线性形状的代码。
线性模型类的结构如下:
class shape_model
{ //2d linear shape model public: Mat p; //parameter vector (kx1) CV_32F,参数向量 Mat V; //shape basis (2nxk) CV_32F, line subspace,线性子空间 Mat e; //parameter variance (kx1) CV_32F 参数方差 Mat C; //connectivity (cx2) CV_32S 连通性...
}
我们生成的线性形状模型用矩阵V表示,它是152*18,前四列是旋转缩放矩阵R,接着是保留的14副特征图像。
通过下面的代码计算平移和缩放:
float scale = calc_scale(smodel.V.col(0),200); float tranx = n*150.0/smodel.V.col(2).dot(Mat::ones(2*n,1,CV_32F)); float trany = n*150.0/smodel.V.col(3).dot(Mat::ones(2*n,1,CV_32F));
参数p的计算如下,最后通过draw_shape函数求得生成的模型,并显示出来:
for(int k = 4; k < smodel.V.cols; k++) { for(int j = 0; j < int(val.size()); j++) { Mat p = Mat::zeros(smodel.V.cols,1,CV_32F); p.at<float>(0) = scale; p.at<float>(2) = tranx; p.at<float>(3) = trany; p.at<float>(k) = scale*val[j]*3.0*sqrt(smodel.e.at<float>(k)); p.copyTo(smodel.p); img = Scalar::all(255); char str[256]; sprintf(str,"mode: %d, val: %f sd",k-3,val[j]/3.0); draw_string(img,str); vector<Point2f> q = smodel.calc_shape(); draw_shape(img,q,smodel.C); //s = V*p imshow("shape model",img); if(waitKey(10) == 'q') return 0; } }
显示结果如下图: