Smooth landmarks on significant face position or pose changes
This commit is contained in:
parent
ec0d5090fc
commit
74402be3ca
@ -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++)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user