in packages/ekyc-api/src/ekyc-api/Utils/LivenessChecker.cs [443:590]
private async Task<bool> CompareFacialLandmarks(SessionObject session, FaceDetail nosePointingFace,
FaceDetail selfieFace)
{
AWSXRayRecorder.Instance.BeginSubsegment("LivenessChecker::VerifyImageLiveness");
/* var npfMouthRight = nosePointingFace.Landmarks.FirstOrDefault(a => a.Type == LandmarkType.MouthRight);
var npfMouthLeft = nosePointingFace.Landmarks.FirstOrDefault(a => a.Type == LandmarkType.MouthLeft);
var npfNose = nosePointingFace.Landmarks.FirstOrDefault(a => a.Type == LandmarkType.Nose);
var npfLeftEye = nosePointingFace.Landmarks.FirstOrDefault(a => a.Type == LandmarkType.EyeLeft);
var npfRightEye = nosePointingFace.Landmarks.FirstOrDefault(a => a.Type == LandmarkType.EyeRight);
var selfieMouthRight = selfieFace.Landmarks.FirstOrDefault(a => a.Type == LandmarkType.MouthRight);
var selfieMouthLeft = nosePointingFace.Landmarks.FirstOrDefault(a => a.Type == LandmarkType.MouthLeft);
var selfieNose = selfieFace.Landmarks.FirstOrDefault(a => a.Type == LandmarkType.Nose);
var selfieLeftEye = selfieFace.Landmarks.FirstOrDefault(a => a.Type == LandmarkType.EyeLeft);
var selfieRightEye = selfieFace.Landmarks.FirstOrDefault(a => a.Type == LandmarkType.EyeRight);
if (npfMouthLeft == null)
throw new Exception("Unable to find the left corner of the mouth for the nose pointing image.");
if (npfMouthRight == null)
throw new Exception("Unable to find the right corner of the mouth for the nose pointing image.");
if (npfNose == null)
throw new Exception("Unable to find the nose for the nose pointing image.");
if (npfRightEye == null)
throw new Exception("Unable to find the right eye for the nose pointing image.");
if (npfLeftEye == null)
throw new Exception("Unable to find the left eye for the nose pointing image.");
if (selfieMouthRight == null)
throw new Exception("Unable to find the right corner of the mouth for the selfie.");
if (selfieMouthLeft == null)
throw new Exception("Unable to find the left corner of the mouth for the selfie");
if (selfieNose == null)
throw new Exception("Unable to find the nose for the selfie.");
if (npfRightEye == null)
throw new Exception("Unable to find the right eye for the selfie.");
if (npfLeftEye == null)
throw new Exception("Unable to find the left eye for the selfie.");
// Nose point calculation
double npfMouthLeftAndNoseDegrees = GetTangentDegreesBetweenLandmarks(npfMouthLeft, npfNose);
double npfMouthRightAndNoseDegrees = GetTangentDegreesBetweenLandmarks(npfMouthRight,
npfNose);
double npfLeftEyeAndNoseDegrees = GetTangentDegreesBetweenLandmarks(npfNose, npfLeftEye);
double npfRightEyeAndNoseDegrees = GetTangentDegreesBetweenLandmarks(npfNose, npfRightEye);
// Selfie calculation
double selfieMouthLeftAndNoseDegrees = GetTangentDegreesBetweenLandmarks(selfieMouthLeft, selfieNose);
double selfieMouthRightAndNoseDegrees = GetTangentDegreesBetweenLandmarks(selfieMouthRight,
selfieNose);
double selfieLeftEyeAndNoseDegrees = GetTangentDegreesBetweenLandmarks(selfieNose, selfieLeftEye);
double selfieRightEyeAndNoseDegrees = GetTangentDegreesBetweenLandmarks(selfieNose, selfieRightEye);*/
Console.WriteLine(
$"Session Nose Pointing Coordinates: X - {session.nosePointAreaLeft}, Y - {session.nosePointAreaTop}");
Console.WriteLine(
$"Selfie Face: Yaw - {selfieFace.Pose.Yaw}, Pitch - {selfieFace.Pose.Pitch}, Roll - {selfieFace.Pose.Roll}");
Console.WriteLine(
$"Nose Point Face: Yaw - {nosePointingFace.Pose.Yaw}, Pitch - {nosePointingFace.Pose.Pitch}, Roll - {nosePointingFace.Pose.Roll}");
// Top left quadrant
if (session.nosePointAreaLeft.Value <= 0.5f && session.nosePointAreaTop.Value <= 0.5)
{
var poseFit = nosePointingFace.Pose.Yaw < selfieFace.Pose.Yaw &&
nosePointingFace.Pose.Pitch > selfieFace.Pose.Pitch;
if (!poseFit)
return false;
/*
// We expect the tangent of the left of the mouth to the nose to be smaller
if (npfMouthRightAndNoseDegrees >= selfieMouthRightAndNoseDegrees)
return false;
// We expect the tangent of the left eye to the nose to be smaller
if (npfLeftEyeAndNoseDegrees >= selfieLeftEyeAndNoseDegrees)
return false;
*/
}
// Top right quadrant
if (session.nosePointAreaLeft > 0.5f && session.nosePointAreaTop <= 0.5f)
{
var poseFit = nosePointingFace.Pose.Yaw >= selfieFace.Pose.Yaw &&
nosePointingFace.Pose.Pitch >= selfieFace.Pose.Pitch;
if (!poseFit)
return false;
/*
// We expect the tangent of the right of the mouth to the nose to be smaller
if (npfMouthLeftAndNoseDegrees >= selfieMouthLeftAndNoseDegrees)
return false;
// We expect the tangent of the left eye to the nose to be smaller
if (npfLeftEyeAndNoseDegrees >= selfieLeftEyeAndNoseDegrees)
return false;
*/
}
// Bottom left quadrant
if (session.nosePointAreaLeft <= 0.5f && session.nosePointAreaTop > 0.5f)
{
var poseFit = nosePointingFace.Pose.Yaw < selfieFace.Pose.Yaw &&
nosePointingFace.Pose.Pitch < selfieFace.Pose.Pitch;
if (!poseFit)
return false;
}
// Bottom right quadrant
if (session.nosePointAreaLeft > 0.5f && session.nosePointAreaTop >= 0.5f)
{
var poseFit = nosePointingFace.Pose.Yaw >= selfieFace.Pose.Yaw &&
nosePointingFace.Pose.Pitch < selfieFace.Pose.Pitch;
if (!poseFit)
return false;
}
AWSXRayRecorder.Instance.BeginSubsegment("LivenessChecker::CompareFacialLandmarks");
return true;
}