特征点对齐的方法

特征点对齐的方法:

//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;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值