人脸对齐

来源:互联网 发布:防范网络诈骗标语 编辑:程序博客网 时间:2024/05/16 09:39

人脸相关应用的重要预处理,very useful!

// 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;}
原创粉丝点击