根据对齐点将人脸进行旋转
#include <cv.h>
#include <highgui.h>
#include <fstream>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat_<double> LoadGroundTruthShape(string filename);
int main0()
{
Mat img = imread("D:\\image_070.jpg"); // read img
Mat_<double> shape = LoadGroundTruthShape("D:\\image_070.pts"); //read shape
for (int j = 0; j <68; j++){
circle(img, Point2d(shape(j, 0), shape(j, 1)), 3, Scalar(255, 255, 255), -1, 8, 0);
}
// two points on the position of eyes
circle(img, Point2d(shape(38, 0), shape(38, 1)), 3, Scalar(0, 255, 255), -1, 8, 0);
circle(img, Point2d(shape(44, 0), shape(44, 1)), 3, Scalar(0, 255, 255), -1, 8, 0);
// the eye_center point of two eyes
Point2d eyesCenter = Point2d((shape(38, 0) + shape(44, 0)) * 0.5f, (shape(38, 1) + shape(44, 1)) * 0.5f);
// the nose center
Point2d noseCenter = Point2d(shape(33, 0), shape(33, 1));
circle(img, noseCenter, 3, Scalar(0, 0, 255), -1, 8, 0);
// calculate the angle
double dy = shape(44, 1) - shape(38, 1);
double dx = shape(44, 0) - shape(38, 0);
double angle = atan2(dy, dx) * 180.0 / CV_PI;
std::cout << "angle=" << angle << endl;
// rotation matrix
Mat rot_mat = getRotationMatrix2D(noseCenter, angle, 0.5);
Mat rot;
// affine tranform
warpAffine(img, rot, rot_mat, img.size());
// compute new landmark
vector<Point2f> marks;
for (int n = 0; n<68; n++)
{
Point2f p = Point2f(0, 0);
p.x = rot_mat.ptr<double>(0)[0] * shape(n, 0) + rot_mat.ptr<double>(0)[1] * shape(n, 1) + rot_mat.ptr<double>(0)[2];
p.y = rot_mat.ptr<double>(1)[0] * shape(n, 0) + rot_mat.ptr<double>(1)[1] * shape(n, 1) + rot_mat.ptr<double>(1)[2];
marks.push_back(p);
}
// plot new landmark
for (int j = 0; j < 68; j++)
{
circle(rot, marks[j], 2, Scalar(255, 0, 0));
}
imwrite("D:\\res.jpg", rot);
imshow("img", img);
imshow("rot", rot);
waitKey(0);
destroyAllWindows();
return 0;
}
Mat_<double> LoadGroundTruthShape(string filename){
Mat_<double> shape(68, 2);
ifstream fin;
string temp;
fin.open(filename);
getline(fin, temp);
getline(fin, temp);
getline(fin, temp);
for (int i = 0; i<68; i++){
fin >> shape(i, 0) >> shape(i, 1);
}
fin.close();
return shape;
}