基於Landmark的人臉對齊以及裁剪方法


 利用Landmarks進行人臉對齊裁剪是人臉檢測中重要的一個步驟。效果如下圖所示:

基本思路為:

a.人臉檢測

  人臉的檢測不必多說了,基本Cascade的方式已經很不錯了,或者用基於HOG/FHOG的SVM/DPM等。這些在OpenCVDLIB都有。

 

b.在檢測到的人臉上進行Landmarks檢測,獲得一系列的Landmark點

  對齊算法很多,特別是前幾年人臉對齊獲得了巨大的成功。

  [1].One Millisecond Face Alignment with an Ensemble of Regression Trees by Vahid Kazemi and Josephine Sullivan, CVPR 2014

  [2].人臉對齊SDM原理----Supervised Descent Method and its Applications to Face Alignment

 

c.利用檢測到的Landmarks和模板的Landmarks,計算仿射矩陣H;然后利用H,直接計算得到對齊后的圖像。

  直接上代碼:

#include <opencv2/opencv.hpp>
using namespace cv;
//原始圖像大小
#define IMAGE_WIDTH 640
#define IMAGE_HEIGHT 480
//輸出的圖像大小(裁剪后的)
#define IMAGE_WIDTH_STD 90
#define IMAGE_HEIGHT_STD 90

#define LANDMARK_SIZE 8//對齊點的個數
#define LANDMARK_SIZE_DOUBLE 16//對齊點個數的兩倍

Point2f srcTri[LANDMARK_SIZE];//對齊點的Point2f數組,檢測到的人臉對齊點,注意這里是基於原始圖像的坐標點
Point2f destTri[LANDMARK_SIZE];//對齊點的Point2f數組,模板的Landmarks,注意這是一個基於輸出圖像大小尺寸的坐標點
                               //對齊點的double數組
double template_landmark[LANDMARK_SIZE_DOUBLE] = {
    0.0792396913815, 0.339223741112, 0.0829219487236, 0.456955367943,
    0.0967927109165, 0.575648016728, 0.122141515615, 0.691921601066,
    0.168687863544, 0.800341263616, 0.239789390707, 0.895732504778,
    0.325662452515, 0.977068762493, 0.422318282013, 1.04329000149,
    0.531777802068, 1.06080371126, 0.641296298053, 1.03981924107,
    0.738105872266, 0.972268833998, 0.824444363295, 0.889624082279,
    0.894792677532, 0.792494155836, 0.939395486253, 0.681546643421,
    0.96111933829, 0.562238253072, 0.970579841181, 0.441758925744
};


int main()
{
    VideoCapture vcap;
    if (!vcap.open(0))
    {
        return 0;
    }

    for (int i = 0; i < LANDMARK_SIZE; i++)
    {
        srcTri[i] = Point2f(template_landmark[i * 2] * 90 + IMAGE_HEIGHT / 2, template_landmark[i * 2 + 1] * 90 + IMAGE_WIDTH / 2);
        destTri[i] = Point2f(template_landmark[i * 2] * IMAGE_HEIGHT_STD, template_landmark[i * 2 + 1] * IMAGE_WIDTH_STD);
    }
    //Mat warp_mat = getAffineTransform( srcTri, destTri );//使用仿射變換,計算H矩陣
    Mat warp_mat = cv::estimateRigidTransform(srcTri, destTri, false);//使用相似變換,不適合使用仿射變換,會導致圖像變形
    Mat frame;
    Mat warp_frame(200, 200, CV_8UC3);
    while (1)
    {
        vcap >> frame;
        warpAffine(frame, warp_frame, warp_mat, warp_frame.size());//裁剪圖像

        imshow("frame", frame);//顯示原圖像
        imshow("warp_frame", warp_frame);//顯示裁剪后得到的圖像

        waitKey(10);
    }
    return 0;
}

 

 效果圖:

注意以上效果非真實的對齊裁剪的效果。實際的對齊裁剪可以做的很好。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM