/** * @brief Calculate some key lines on the face * @param oLine Output output those lines * @param iShape Input the known shape * @param iFaceParts Input the faceparts * @param oSubshape Output the output subshape, namely, the line is represented by a VO_Shape * @param partIdx Input which part is it * @return void */ void VO_KeyPoint::CalcFaceKeyline( std::vector<float>& oLine, const VO_Shape& iShape, const VO_FaceParts& iFaceParts, VO_Shape& oSubshape, unsigned int partIdx) { oLine.resize(3); int dim = iShape.GetNbOfDim(); cv::Vec4f line; std::vector<unsigned int> linePoints; switch(partIdx) { case VO_FacePart::NOSTRIL: linePoints = iFaceParts.VO_GetOneFacePart(VO_FacePart::NOSTRIL).GetIndexes(); break; case VO_FacePart::MOUTHCORNERPOINTS: linePoints = iFaceParts.VO_GetOneFacePart(VO_FacePart::MOUTHCORNERPOINTS).GetIndexes(); break; case VO_FacePart::PITCHAXISLINEPOINTS: linePoints = iFaceParts.VO_GetOneFacePart(VO_FacePart::PITCHAXISLINEPOINTS).GetIndexes(); break; case VO_FacePart::EYECORNERPOINTS: linePoints = iFaceParts.VO_GetOneFacePart(VO_FacePart::EYECORNERPOINTS).GetIndexes(); break; case VO_FacePart::MIDLINEPOINTS: default: linePoints = iFaceParts.VO_GetOneFacePart(VO_FacePart::EYECORNERPOINTS).GetIndexes(); break; } oSubshape = iShape.GetSubShape(linePoints); // Explained by JIA Pei, some times, there is no linePoints, which means the specified parts are not in one of the database if(linePoints.size() >= 2 ) { cv::fitLine( oSubshape.GetTheShape(), line, CV_DIST_L2, 0, 0.001, 0.001 ); // Ax+By+C = 0 oLine[0] = -line[1]; oLine[1] = line[0]; oLine[2] = line[1]*line[2]-line[0]*line[3]; } }