特征点对齐的方法

特征点对齐的方法:

//landmarks[i].first表示X坐标;landmark[i].second表示Y坐标
bool FaceNormalizer::normalize(const Mat inputFaceImage, const vector< pair<double, double> > landmarks, Mat &outputFaceImage, vector< pair<double, double> > &newLandmarks)
{
   double eyeXdis = landmarks[1].first-landmarks[0].first;
   double eyeYdis = landmarks[1].second-landmarks[0].second;
   double angle = atan(eyeYdis/eyeXdis);
   double degree = angle*180/CV_PI;//角度

   //rotate image and corresponding points to make the eyes horizontal even
   for(int i=0; i<landmarks.size(); i++) {
      pair<double,double> pt;
      pt.first = (landmarks[i].first - landmarks[0].first)*cos(angle) + (landmarks[i].second - landmarks[0].second)*sin(angle)+ landmarks[0].first;
      pt.second = (landmarks[i].second - landmarks[0].second)*cos(angle) - (landmarks[i].first - landmarks[0].first)*sin(angle)+ landmarks[0].second;
      newLandmarks.push_back(pt);//新的标记点

   }
   Mat rotMat = getRotationMatrix2D(Point2f(landmarks[0].first,landmarks[0].second), degree, 1.0);//landmarks[0].first,landmarks[0].second为旋转中心点,degree为旋转角度
   //printf("%d %d\n", inputFaceImage.cols, inputFaceImage.rows);
   warpAffine(inputFaceImage, outputFaceImage, rotMat, Size(inputFaceImage.cols, inputFaceImage.rows));//仿射变换

   //crop face region from the image
   double eyeDist = abs((newLandmarks[0].first - newLandmarks[1].first));
   double eyeCenterX = (newLandmarks[0].first + newLandmarks[1].first)/2 + int(eyeDistanceX*eyeDist);
   double eyeCenterY = (newLandmarks[0].second + newLandmarks[1].second)/2 + int(eyeDistanceUp*eyeDist);
   int leftbound = int((eyeCenterX - eyeDistanceX*eyeDist));
   int rightbound = int((eyeCenterX + eyeDistanceX*eyeDist));
   int topbound = int((eyeCenterY - eyeDistanceUp*eyeDist));
   int bottombound = int((eyeCenterY + eyeDistanceDown*eyeDist));
   copyMakeBorder(outputFaceImage, outputFaceImage, int(eyeDistanceUp*eyeDist), int(eyeDistanceDown*eyeDist),
      int(eyeDistanceX*eyeDist), int(eyeDistanceX*eyeDist), BORDER_CONSTANT, Scalar(0));//复制图像并且制作边界
/*
   if (leftbound < 0 || topbound < 0 || rightbound >=outputFaceImage.cols || bottombound >=outputFaceImage.rows) {
      cerr<<"Error: face out of bound!\n";
      return false;
   }
   */
   for(int i=0; i<newLandmarks.size(); i++)
   {  
      newLandmarks[i].first = newLandmarks[i].first - leftbound + int(eyeDistanceX*eyeDist);
      newLandmarks[i].second =  newLandmarks[i].second - topbound + int(eyeDistanceUp*eyeDist);
   }
   outputFaceImage = outputFaceImage(Rect(leftbound, topbound, rightbound-leftbound, bottombound-topbound));      
   //outputFaceImage = outputFaceImage;//(Rect(leftbound, topbound, rightbound-leftbound, bottombound-topbound));      
   return true;
}


你可能感兴趣的:(人脸识别,人脸对齐)