Insightface: C++ face alignment

Created on 15 Aug 2018  ·  13Comments  ·  Source: deepinsight/insightface

is there a c++ version of face alignment? thank you

Most helpful comment

@nttstar Thank you for your response, I have check the dir of cpp-align, it seems that there is only a header file FacePreprocess.h, it implements similar transformation(without key facial points), but how could I used it face alignment?

I have searched for a long time, and implement the face alignment as follow:

cv::Mat align_face(const cv::Mat& src, const FaceLandmark& landmark, int width, int height) {

const int N = landmark.points_.size();
std::vector<cv::Point2f> detect_points;
if (N != 5) {
    detect_points = {
        landmark.points_[ReferenceID[0]],
        landmark.points_[ReferenceID[1]],
        landmark.points_[ReferenceID[2]],
        landmark.points_[ReferenceID[3]],
        landmark.points_[ReferenceID[4]],
    };
}
else {
    detect_points = landmark.points_;
}

const int ReferenceWidth = 112;
const int ReferenceHeight = 112;

int wex;
if (ReferenceHeight == 112)
    wex = 8;
std::vector<cv::Point2f> reference_points = {
    cv::Point2f{ 30.29459953f,  51.69630051f + wex },
    cv::Point2f{ 65.53179932f,  51.50139999f + wex },
    cv::Point2f{ 48.02519989f,  71.73660278f + wex },
    cv::Point2f{ 33.54930115f,  92.3655014f + wex },
    cv::Point2f{ 62.72990036f,  92.20410156f + wex }

};
for (auto& e : reference_points) {
    e.x += (width - ReferenceWidth) / 2.0f;
    e.y += (height - ReferenceHeight) / 2.0f;
}
cv::Mat tfm = get_similarity_transform(detect_points, reference_points);
cv::Mat aligned_face;
warpAffine(src, aligned_face, tfm, cv::Size(width, height));
return aligned_face;

}

it was taken out from sphereface, which the face image is 96x112, but insightface use 112x112, so I have to add a shift on it, it seems solve the problem, but the result of this alignment is not as good as your python code, so I have to use your cpp-align to keep the same accuracy, but I dont know how to use your ccp-align code because the facial landmark information is not used in your code.

All 13 comments

Yes, check cpp-align dir

@nttstar Thank you for your response, I have check the dir of cpp-align, it seems that there is only a header file FacePreprocess.h, it implements similar transformation(without key facial points), but how could I used it face alignment?

I have searched for a long time, and implement the face alignment as follow:

cv::Mat align_face(const cv::Mat& src, const FaceLandmark& landmark, int width, int height) {

const int N = landmark.points_.size();
std::vector<cv::Point2f> detect_points;
if (N != 5) {
    detect_points = {
        landmark.points_[ReferenceID[0]],
        landmark.points_[ReferenceID[1]],
        landmark.points_[ReferenceID[2]],
        landmark.points_[ReferenceID[3]],
        landmark.points_[ReferenceID[4]],
    };
}
else {
    detect_points = landmark.points_;
}

const int ReferenceWidth = 112;
const int ReferenceHeight = 112;

int wex;
if (ReferenceHeight == 112)
    wex = 8;
std::vector<cv::Point2f> reference_points = {
    cv::Point2f{ 30.29459953f,  51.69630051f + wex },
    cv::Point2f{ 65.53179932f,  51.50139999f + wex },
    cv::Point2f{ 48.02519989f,  71.73660278f + wex },
    cv::Point2f{ 33.54930115f,  92.3655014f + wex },
    cv::Point2f{ 62.72990036f,  92.20410156f + wex }

};
for (auto& e : reference_points) {
    e.x += (width - ReferenceWidth) / 2.0f;
    e.y += (height - ReferenceHeight) / 2.0f;
}
cv::Mat tfm = get_similarity_transform(detect_points, reference_points);
cv::Mat aligned_face;
warpAffine(src, aligned_face, tfm, cv::Size(width, height));
return aligned_face;

}

it was taken out from sphereface, which the face image is 96x112, but insightface use 112x112, so I have to add a shift on it, it seems solve the problem, but the result of this alignment is not as good as your python code, so I have to use your cpp-align to keep the same accuracy, but I dont know how to use your ccp-align code because the facial landmark information is not used in your code.

I also don't know how to use ccp-align code, and do you know now? @anguoyang

感谢感谢,解决了~

@anguoyang

It seems that your solution is wrong, because you have to add 8 to X coordinates of reference points as mentioned here:
https://github.com/tpys/face-everthing/issues/14#issuecomment-381918606

@anguoyang 你好。对于这个“cv::Mat align_face(const cv::Mat& src, const FaceLandmark& landmark, int width, int height)”我有几个问题:

  1. src是原图像,还是抠出来的人脸图像?
  2. FaceLandmark的数据结构是什么?
  3. width和height分别代表什么?是检测到的人脸框大小,还是112*112?
  4. sphereface的对齐代码链接在哪?
    谢谢!

@anguoyang 你好。对于这个“cv::Mat align_face(const cv::Mat& src, const FaceLandmark& landmark, int width, int height)”我有几个问题:

  1. src是原图像,还是抠出来的人脸图像?
  2. FaceLandmark的数据结构是什么?
  3. width和height分别代表什么?是检测到的人脸框大小,还是112*112?
  4. sphereface的对齐代码链接在哪?
    谢谢!

@anguoyang 你好。对于这个“cv::Mat align_face(const cv::Mat& src, const FaceLandmark& landmark, int width, int height)”我有几个问题:

  1. src是原图像,还是抠出来的人脸图像?
  2. FaceLandmark的数据结构是什么?
  3. width和height分别代表什么?是检测到的人脸框大小,还是112*112?
  4. sphereface的对齐代码链接在哪?
    谢谢!

@MirrorYuChen 你解决了吗,能帮我回答以上问题吗?

你可以参考我的ncnn-example项目里面,有个align模块的代码,觉得有用记得给star:
https://github.com/MirrorYuChen/ncnn_example

我这里计算的时候,src是原图,如果想用截取出来的图,在计算关键点坐标时,需要减去人脸左上角点坐标~

然后加不加8这个偏移量,取决于你人脸识112x112还是112x96~上面已经将的很清楚了~

@MirrorYuChen 谢谢,我先试试,不懂的还要问您。

@MirrorYuChen 解决了,谢谢老哥。方便加个微信吗13969756973

已经添加好友~

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AnhVPB picture AnhVPB  ·  4Comments

springtime-cn picture springtime-cn  ·  4Comments

mdv3101 picture mdv3101  ·  5Comments

Alloshee picture Alloshee  ·  3Comments

zys1994 picture zys1994  ·  3Comments