public Vector2 Predict(PoseAndEyeAndFace data) { var camera = new CoordinateSystem(); var displayNormRealign = UnitVector3D.YAxis; var displayXPositiveRealign = UnitVector3D.XAxis; var refHeadPositionRaw = Point3D.Centroid(Samples.Select(r => r.HeadPose.Position).Select(r => r.ToMathNetPoint3D())); var refHeadPosition = ConvertPointFromOpenFaceSpaceToMathNetSpace(refHeadPositionRaw); var refHeadRotationRaw = Point3D.Centroid(Samples.Select(r => r.HeadPose.Angle).Select(r => r.ToMathNetPoint3D())); var refHeadRotation = ConvertAngelFromOpenFaceSpaceToMathNetSpace(refHeadRotationRaw); var refHeadRotationCoord = camera .RotateCoordSysAroundVector(UnitVector3D.XAxis, Angle.FromRadians(refHeadRotation.X)) .RotateCoordSysAroundVector(UnitVector3D.ZAxis, Angle.FromRadians(refHeadRotation.Z)) .RotateCoordSysAroundVector(UnitVector3D.YAxis, Angle.FromRadians(refHeadRotation.Y)); var refHeadRotationAlign = CoordinateSystem.CreateMappingCoordinateSystem(camera, refHeadRotationCoord); var refHeadRotationUnalign = CoordinateSystem.CreateMappingCoordinateSystem(refHeadRotationCoord, camera); var displayWidth = HeadDisplayDistance * Tan(FieldOfViewWidthSingleSideAngle) * 2; var displayHeight = displayWidth / DisplayAspectRatio; var displaySize = new Vector2D(displayWidth, displayHeight); var refDisplayNorm = displayNormRealign.TransformBy(refHeadRotationUnalign).Normalize(); var refDisplayXPositive = displayXPositiveRealign.TransformBy(refHeadRotationUnalign).Normalize(); var refDisplayCentroid = refHeadPosition + HeadDisplayDistance * refDisplayNorm; var refDisplayPlane = new MathNet.Spatial.Euclidean.Plane(refDisplayCentroid, refDisplayNorm); var headPosition = ConvertPointFromOpenFaceSpaceToMathNetSpace(data.Pose.Position.ToMathNetPoint3D()); var headRotation = ConvertAngelFromOpenFaceSpaceToMathNetSpace(data.Pose.Angle.ToMathNetPoint3D()); var headRotationCoord = camera .RotateCoordSysAroundVector(UnitVector3D.XAxis, Angle.FromRadians(headRotation.X)) .RotateCoordSysAroundVector(UnitVector3D.ZAxis, Angle.FromRadians(headRotation.Z)) .RotateCoordSysAroundVector(UnitVector3D.YAxis, Angle.FromRadians(headRotation.Y)); var headRotationAlign = CoordinateSystem.CreateMappingCoordinateSystem(camera, headRotationCoord); var headRotationUnalign = CoordinateSystem.CreateMappingCoordinateSystem(headRotationCoord, camera); var displayNorm = displayNormRealign.TransformBy(headRotationUnalign).Normalize(); var displayXPositive = displayXPositiveRealign.TransformBy(headRotationUnalign).Normalize(); var displayCentroid = headPosition + HeadDisplayDistance * displayNorm; var displayPlane = new MathNet.Spatial.Euclidean.Plane(displayCentroid, displayNorm); var calibPoints = Samples.Select(r => CalibPointOnDisplay(displayCentroid, displayNorm, displayXPositive, displaySize, r.Display.ToMathNetPoint2D())).ToArray(); var calibRays = calibPoints.Select(p => new Ray3D(headPosition, p - headPosition)).ToArray(); var transformedCalibPoints = calibRays.Select(r => (Point3D)r.IntersectionWith(refDisplayPlane)).ToArray(); var transformedRelatives = transformedCalibPoints.Select(p => RelativeToDisplay(refDisplayCentroid, refDisplayNorm, refDisplayXPositive, displaySize, p)).ToArray(); var pupilDistances = Samples.Select(r => PupilCornerDistance(r.Gaze, r.HeadPose)).ToArray(); var inputX = pupilDistances.Select(d => d.X).ToArray(); var outputX = transformedRelatives.Select(p => p.X).ToArray(); var polynomialX = Polynomial.Fit(inputX, outputX, Order); var inputY = pupilDistances.Select(d => d.Y).ToArray(); var outputY = transformedRelatives.Select(p => p.Y).ToArray(); var polynomialY = Polynomial.Fit(inputY, outputY, Order); var distance = PupilCornerDistance(data.Eye, data.Pose); var x = polynomialX.Evaluate(distance.X); var y = polynomialY.Evaluate(distance.Y); return(new Vector2((float)x, (float)y)); }
public Vector2 Predict(PoseAndEyeAndFace data) { var record = new RegressionRecord(data); var predX = predictorX.Predict(record); var predY = predictorY.Predict(record); return(new Vector2(predX.Value, predY.Value)); }
public GazeToDisplayCoordinateMappingRecord(PoseAndEyeAndFace headPoseAndGaze, Vector2 display) : this(headPoseAndGaze.Eye, headPoseAndGaze.Pose, headPoseAndGaze.Face, display) { }