opencv 仿射變換 根據眼睛座標進行人臉對齊 計算變換後對應座標
阿新 • • 發佈:2019-01-09
- //根據眼睛座標對影象進行仿射變換
- //src - 原影象
- //landmarks - 原影象中68個關鍵點
- Mat getwarpAffineImg(Mat &src, vector<Point2f> &landmarks)
- {
- Mat oral;src.copyTo(oral);
- for (int j = 0; j < landmarks.size(); j++)
- {
- circle(oral, landmarks[j], 2, Scalar(255, 0, 0));
- }
- //計算兩眼中心點,按照此中心點進行旋轉, 第31個為左眼座標,36為右眼座標
- Point2f eyesCenter = Point2f( (landmarks[31].x + landmarks[36].x) * 0.5f, (landmarks[31].y + landmarks[36].y) * 0.5f );
- // 計算兩個眼睛間的角度
- double dy = (landmarks[36].y - landmarks[31].y);
- double dx = (landmarks[36].x - landmarks[31].x);
- double angle = atan2(dy, dx) * 180.0/CV_PI; // Convert from radians to degrees.
- //由eyesCenter, andle, scale按照公式計算仿射變換矩陣,此時1.0表示不進行縮放
- Mat rot_mat = getRotationMatrix2D(eyesCenter, angle, 1.0);
- Mat rot;
- // 進行仿射變換,變換後大小為src的大小
- warpAffine(src, rot, rot_mat, src.size());
- vector<Point2f> marks;
- //按照仿射變換矩陣,計算變換後各關鍵點在新圖中所對應的位置座標。
- for (int n = 0; n<landmarks.size(); n++)
- {
- Point2f p = Point2f(0, 0);
- p.x = rot_mat.ptr<double>(0)[0] *landmarks[n].x + rot_mat.ptr<double>(0)[1] * landmarks[n].y + rot_mat.ptr<double>(0)[2];
- p.y = rot_mat.ptr<double>(1)[0] * landmarks[n].x + rot_mat.ptr<double>(1)[1] * landmarks[n].y + rot_mat.ptr<double>(1)[2];
- marks.push_back(p);
- }
- //標出關鍵點
- for (int j = 0; j < landmarks.size(); j++)
- {
- circle(rot, marks[j], 2, Scalar(0, 0, 255));
- }
- return rot;
- }