Smooth landmarks on significant face position or pose changes

This commit is contained in:
Alexander Biryukov 2018-06-04 08:24:21 +05:00
parent ec0d5090fc
commit 74402be3ca
4 changed files with 16 additions and 22 deletions

View File

@ -11,8 +11,6 @@
//#define USE_PREDICTION //#define USE_PREDICTION
#define SMOOTH_LANDMARKS
cv::Point flipVertical(cv::Point point) { cv::Point flipVertical(cv::Point point) {
return cv::Point(point.x, 720 - point.y); return cv::Point(point.x, 720 - point.y);
} }
@ -53,21 +51,19 @@ FaceStruct::FaceStruct(const std::array<cv::Point2f, LANDMARK_POINT_COUNT>& from
ApplyPreds(fromPreds, 0.0, cameraMatrix, distortionCoefficients); ApplyPreds(fromPreds, 0.0, cameraMatrix, distortionCoefficients);
} }
void FaceStruct::CalcFromPreds(double similarity, cv::Mat& cameraMatrix, cv::Mat& distortionCoefficients) void FaceStruct::CalcFromPreds(bool noticeablyChanged, cv::Mat& cameraMatrix, cv::Mat& distortionCoefficients)
{ {
#ifdef SMOOTH_LANDMARKS
for(size_t i = 0; i < LANDMARK_POINT_COUNT; i++) { for(size_t i = 0; i < LANDMARK_POINT_COUNT; i++) {
if(similarity < 0.01) { if(noticeablyChanged) {
landmarkSmoothers[i * 2].reset();
landmarkSmoothers[i * 2 + 1].reset();
} else {
preds[i] = Vector2f( preds[i] = Vector2f(
landmarkSmoothers[i * 2].responsiveAnalogReadSimple(preds[i](0)), landmarkSmoothers[i * 2].responsiveAnalogReadSimple(preds[i](0)),
landmarkSmoothers[i * 2 + 1].responsiveAnalogReadSimple(preds[i](1)) landmarkSmoothers[i * 2 + 1].responsiveAnalogReadSimple(preds[i](1))
); );
} else {
landmarkSmoothers[i * 2].reset();
landmarkSmoothers[i * 2 + 1].reset();
} }
} }
#endif
float minX = preds[0](0); float minX = preds[0](0);
float maxX = preds[0](0); float maxX = preds[0](0);
@ -150,10 +146,10 @@ void FaceStruct::CalcFromPreds(double similarity, cv::Mat& cameraMatrix, cv::Mat
size = {maxX- minX, maxY - minY}; size = {maxX- minX, maxY - minY};
} }
void FaceStruct::ApplyPreds(const std::array<cv::Point2f, LANDMARK_POINT_COUNT>& fromPreds, double similarity, cv::Mat& cameraMatrix, cv::Mat& distortionCoefficients) void FaceStruct::ApplyPreds(const std::array<cv::Point2f, LANDMARK_POINT_COUNT>& fromPreds, bool noticeablyChanged, cv::Mat& cameraMatrix, cv::Mat& distortionCoefficients)
{ {
InnerApplyPreds(fromPreds); InnerApplyPreds(fromPreds);
CalcFromPreds(similarity, cameraMatrix, distortionCoefficients); CalcFromPreds(noticeablyChanged, cameraMatrix, distortionCoefficients);
} }
void FaceStruct::InnerApplyPreds(const std::array<cv::Point2f, LANDMARK_POINT_COUNT>& fromPreds) void FaceStruct::InnerApplyPreds(const std::array<cv::Point2f, LANDMARK_POINT_COUNT>& fromPreds)
@ -491,10 +487,7 @@ void TMyApplication::InnerUpdate(size_t dt)
{ {
if (faceLandmarkArr[index].valid) if (faceLandmarkArr[index].valid)
{ {
faceStruct[index].ApplyPreds(faceLandmarkArr[index].landmarkArr, faceLandmarkArr[index].similarity, cameraMatrix, distortionCoefficients); faceStruct[index].ApplyPreds(faceLandmarkArr[index].landmarkArr, faceLandmarkArr[index].noticeablyChanged, cameraMatrix, distortionCoefficients);
std::ostringstream similarityText;
similarityText << std::setprecision(3) << faceLandmarkArr[index].similarity;
cv::putText(renderImage, similarityText.str(), cv::Point(50, index * 60 + 60), cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar(255, 255, 255));
for (size_t i = 0; i < LANDMARK_POINT_COUNT; i++) for (size_t i = 0; i < LANDMARK_POINT_COUNT; i++)
{ {

View File

@ -52,8 +52,8 @@ struct FaceStruct
FaceStruct(); FaceStruct();
FaceStruct(const std::array<cv::Point2f, LANDMARK_POINT_COUNT>& fromPreds, cv::Mat& cameraMatrix, cv::Mat& distortionCoefficients); FaceStruct(const std::array<cv::Point2f, LANDMARK_POINT_COUNT>& fromPreds, cv::Mat& cameraMatrix, cv::Mat& distortionCoefficients);
void CalcFromPreds(double similarity, cv::Mat& cameraMatrix, cv::Mat& distortionCoefficients); void CalcFromPreds(bool noticeablyChanged, cv::Mat& cameraMatrix, cv::Mat& distortionCoefficients);
void ApplyPreds(const std::array<cv::Point2f, LANDMARK_POINT_COUNT>& fromPred, double similarity, cv::Mat& cameraMatrix, cv::Mat& distortionCoefficientss); void ApplyPreds(const std::array<cv::Point2f, LANDMARK_POINT_COUNT>& fromPred, bool noticeablyChanged, cv::Mat& cameraMatrix, cv::Mat& distortionCoefficientss);
void InnerApplyPreds(const std::array<cv::Point2f, LANDMARK_POINT_COUNT>& fromPreds); void InnerApplyPreds(const std::array<cv::Point2f, LANDMARK_POINT_COUNT>& fromPreds);
}; };

View File

@ -248,7 +248,7 @@ void FaceLandmarkDetector::FindLandmarkThreadProc(size_t threadIndex)
localOutputLandmarks.faceRect = localInputFace.faceRect; localOutputLandmarks.faceRect = localInputFace.faceRect;
localOutputLandmarks.frameIndex = localInputFace.frameIndex; localOutputLandmarks.frameIndex = localInputFace.frameIndex;
localOutputLandmarks.similarity = localInputFace.similarity; localOutputLandmarks.noticeablyChanged = localInputFace.noticeablyChanged;
localOutputLandmarks.valid = true; localOutputLandmarks.valid = true;
} }
else else
@ -450,10 +450,11 @@ void FaceLandmarkDetector::InnerSeparateFacesToBuckets(std::vector<cv::Rect>& fa
} }
} }
inOutBucketArr[j].similarity = calcSimilarity(inOutBucketArr[j].faceFrame, facesBelongsToSpace[j][lastIndex].second);
inOutBucketArr[j].faceRect = facesBelongsToSpace[j][lastIndex].first; inOutBucketArr[j].faceRect = facesBelongsToSpace[j][lastIndex].first;
inOutBucketArr[j].faceFrame = facesBelongsToSpace[j][lastIndex].second; inOutBucketArr[j].faceFrame = facesBelongsToSpace[j][lastIndex].second;
inOutBucketArr[j].noticeablyChanged =
calcSimilarity(inOutBucketArr[j].faceFrame, facesBelongsToSpace[j][lastIndex].second) > 0.01 ||
lastDistance > 100.0;
facesBelongsToSpace[j].erase(facesBelongsToSpace[j].begin() + lastIndex); facesBelongsToSpace[j].erase(facesBelongsToSpace[j].begin() + lastIndex);

View File

@ -35,7 +35,7 @@ struct FaceIntermediateStruct
cv::Mat faceFrame; cv::Mat faceFrame;
int frameIndex; int frameIndex;
double similarity = 0.0; bool noticeablyChanged = false;
}; };
@ -47,7 +47,7 @@ struct FaceLandmarkStruct
std::array<cv::Point2f, LANDMARK_POINT_COUNT> landmarkArr; std::array<cv::Point2f, LANDMARK_POINT_COUNT> landmarkArr;
int frameIndex; int frameIndex;
double similarity = 0.0; bool noticeablyChanged = false;
}; };