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