# 人脸对齐

403人阅读 评论(0)

// find affine transformation between two pointsets (use least square matching)
bool computeAffine(const vector<Point2f> &srcPoints, const vector<Point2f> &dstPoints, Mat &transf)
{
// sanity check
if ((srcPoints.size() < 3) || (srcPoints.size() != dstPoints.size()))
return false;

// container for output
transf.create(2, 3, CV_32F);

// fill the matrices
const int n = (int)srcPoints.size(), m = 3;
Mat A(n,m,CV_32F), xc(n,1,CV_32F), yc(n,1,CV_32F);
for(int i=0; i<n; i++)
{
float x = srcPoints[i].x, y = srcPoints[i].y;
float rowI[m] = {x, y, 1};
Mat(1,m,CV_32F,rowI).copyTo(A.row(i));
xc.at<float>(i,0) = dstPoints[i].x;
yc.at<float>(i,0) = dstPoints[i].y;
}

// solve linear equations (for x and for y)
Mat aTa, resX, resY;
mulTransposed(A, aTa, true);
solve(aTa, A.t()*xc, resX, DECOMP_CHOLESKY);
solve(aTa, A.t()*yc, resY, DECOMP_CHOLESKY);

// store result
memcpy(transf.ptr<float>(0), resX.data, m*sizeof(float));
memcpy(transf.ptr<float>(1), resY.data, m*sizeof(float));

return true;
}

int faceAlign(Mat src, Mat &output, vector<Point2f> pointSrc)
{
if(!src.data)
{
cout << "image not read properly" << endl;
return -1;
}

// Dimensions of output image
int w = 200;
int h = 200;

vector<Point2f> pointDst;

pointDst.push_back(Point2f( 64, 100)); //左眼角
pointDst.push_back(Point2f( 136, 100)); //右眼角
pointDst.push_back(Point2f(100,130)); //鼻尖
pointDst.push_back(Point2f(68,150));  //左嘴角
pointDst.push_back(Point2f(132,150)); //右嘴角

// Calculate similarity transform
Mat tform;
computeAffine(pointSrc, pointDst, tform);

// Apply transform to input image
Mat AffineImg = Mat::zeros(h, w, CV_32FC3);
warpAffine(src, AffineImg, tform, AffineImg.size());

output = AffineImg;
imshow("img", AffineImg);
//waitKey();
return 1;
}

个人资料
等级：
访问量： 20万+
积分： 3027
排名： 1万+
最新评论