/// <summary> /// Calculates the optimal valid configuration and eliminates the rest of the blobs. /// It uses the number of light sources. /// </summary> public GlintConfiguration GetValidConfiguration(Blobs blobs, GTPoint initialLocation) { var validConfig = new GlintConfiguration(4); var candidateGlintCenters = new Matrix <double>(blobs.Count, blobs.Count); Matrix <int> distMatrixThr; var combinations = new List <Point>(); var validConfigurations = new List <GlintConfiguration>(); var indicesValidConfigs = new List <int>(); distMatrixThr = GetDistanceMatrix(blobs, MinDistBetweenGlints, MaxDistBetweenGlints); for (int i = 0; i < distMatrixThr.Rows; i++) { combinations.AddRange(GetCombinations(distMatrixThr.GetRow(i).Clone(), i)); } if (combinations.Count > 0) { validConfig = FilterConfigsByDistance(blobs, combinations, initialLocation); } else { validConfig = new GlintConfiguration(1); } return(validConfig); }
public GlintConfiguration(GlintConfiguration src) { count = src.Count; centers = new GTPoint[count]; blobs = new Blobs(); for (int i = 0; i < count; i++) { centers[i] = new GTPoint(src.centers[i]); blobs.BlobDir[i] = new Blob(); blobs.BlobDir[i] = src.blobs.BlobDir.ElementAt(i).Value; } }
public GlintData() { Glints = new GlintConfiguration(10); }
/// <summary> /// Calculates the optimal valid configuration and eliminates the rest of the blobs. /// It uses the number of light sources. /// </summary> public GlintConfiguration GetValidConfiguration(Blobs blobs, GTPoint initialLocation) { var validConfig = new GlintConfiguration(4); var candidateGlintCenters = new Matrix<double>(blobs.Count, blobs.Count); Matrix<int> distMatrixThr; var combinations = new List<Point>(); var validConfigurations = new List<GlintConfiguration>(); var indicesValidConfigs = new List<int>(); distMatrixThr = GetDistanceMatrix(blobs, MinDistBetweenGlints, MaxDistBetweenGlints); for (int i = 0; i < distMatrixThr.Rows; i++) { combinations.AddRange(GetCombinations(distMatrixThr.GetRow(i).Clone(), i)); } if (combinations.Count > 0) validConfig = FilterConfigsByDistance(blobs, combinations, initialLocation); else validConfig = new GlintConfiguration(1); return validConfig; }
public override bool Calibrate() { if (numOutliersRemovedLeft == 0 && numOutliersRemovedRight == 0) RemoveOutliers(); // Only works sometimes, tried fixing it.. if (NumImages == 0) { //throw new ArgumentException("numImages=0 in Calibrate()"); IsCalibrated = false; return false; } #region Initialize variabels CalibrationDataLeft = new CalibrationData(); CalibrationDataRight = new CalibrationData(); var targets = new Matrix<double>(NumImages, 3); var designMatrixLeft = new Matrix<double>(NumImages, 6); var designMatrixRight = new Matrix<double>(NumImages, 6); var rowLeft = new double[6]; var rowRight = new double[6]; int k = 0; #endregion #region Build matrices foreach (CalibrationTarget ct in CalibrationTargets) { for (int j = 0; j < ct.NumImages; j++) { #region Left if (j < ct.pupilCentersLeft.Count && j < ct.glintsLeft.Count) { GTPoint pupilCenterLeft = ct.pupilCentersLeft.ElementAt(j); GlintConfiguration glintsLeft = ct.glintsLeft.ElementAt(j); if (pupilCenterLeft != null && glintsLeft != null && glintsLeft.Count > 0) { targets[k, 0] = ct.targetCoordinates.X; targets[k, 1] = ct.targetCoordinates.Y; double xLeft = pupilCenterLeft.X - glintsLeft.AverageCenter.X; double yLeft = pupilCenterLeft.Y - glintsLeft.AverageCenter.Y; rowLeft[0] = 1; rowLeft[1] = xLeft; rowLeft[2] = yLeft; rowLeft[3] = xLeft*yLeft; rowLeft[4] = xLeft*xLeft; rowLeft[5] = yLeft*yLeft; for (int r = 0; r < 6; r++) designMatrixLeft[k, r] = rowLeft[r]; } } #endregion #region Right if (Settings.Instance.Processing.TrackingMode == TrackingModeEnum.Binocular) { if (ct.pupilCentersRight.Count - 1 > j && ct.glintsRight.Count - 1 > j) { GTPoint pupilCenterRight = ct.pupilCentersRight.ElementAt(j); GlintConfiguration glintsRight = ct.glintsRight.ElementAt(j); if (pupilCenterRight != null && glintsRight != null && glintsRight.Count > 0) { double xRight = pupilCenterRight.X - glintsRight.AverageCenter.X; double yRight = pupilCenterRight.Y - glintsRight.AverageCenter.Y; rowRight[0] = 1; rowRight[1] = xRight; rowRight[2] = yRight; rowRight[3] = xRight*yRight; rowRight[4] = xRight*xRight; rowRight[5] = yRight*yRight; for (int r = 0; r < 6; r++) { designMatrixRight[k, r] = rowRight[r]; } } } } #endregion k++; } } #endregion #region SolveLeastSquares CalibrationDataLeft.CoeffsX = new Matrix<double>(6, 1); CalibrationDataLeft.CoeffsY = new Matrix<double>(6, 1); CalibrationDataLeft.CoeffsX = Operations.SolveLeastSquares(designMatrixLeft, targets.GetCol(0)); CalibrationDataLeft.CoeffsY = Operations.SolveLeastSquares(designMatrixLeft, targets.GetCol(1)); if (Settings.Instance.Processing.TrackingMode == TrackingModeEnum.Binocular) { CalibrationDataRight.CoeffsX = new Matrix<double>(6, 1); CalibrationDataRight.CoeffsY = new Matrix<double>(6, 1); CalibrationDataRight.CoeffsX = Operations.SolveLeastSquares(designMatrixRight, targets.GetCol(0)); CalibrationDataRight.CoeffsY = Operations.SolveLeastSquares(designMatrixRight, targets.GetCol(1)); } #endregion #region Calculated est. gaze coordinates (per image) // For each image we calculate the estimated gaze coordinates foreach (CalibrationTarget ct in CalibrationTargets) { // We might be recalibrating so clear estGazeCoords first ct.estimatedGazeCoordinatesLeft.Clear(); ct.estimatedGazeCoordinatesRight.Clear(); for (int j = 0; j < ct.NumImages; j++) { #region Left if (ct.pupilCentersLeft.Count - 1 >= j && ct.glintsLeft.Count - 1 >= j) { var pupilCenterLeft = new GTPoint(0, 0); var glintConfigLeft = new GlintConfiguration(new Blobs()); if (ct.pupilCentersLeft.ElementAt(j) != null) pupilCenterLeft = ct.pupilCentersLeft[j]; if (ct.glintsLeft.ElementAt(j) != null) glintConfigLeft = ct.glintsLeft[j]; if (pupilCenterLeft.Y != 0) ct.estimatedGazeCoordinatesLeft.Add(GetGazeCoordinates(EyeEnum.Left, pupilCenterLeft, glintConfigLeft)); } #endregion #region Right if (Settings.Instance.Processing.TrackingMode == TrackingModeEnum.Binocular) { if (ct.pupilCentersRight.Count - 1 > j && ct.glintsRight.Count - 1 > j) { var pupilCenterRight = new GTPoint(0, 0); var glintConfigRight = new GlintConfiguration(new Blobs()); if (ct.pupilCentersRight.ElementAt(j) != null) pupilCenterRight = ct.pupilCentersRight[j]; if (ct.glintsRight.ElementAt(j) != null) glintConfigRight = ct.glintsRight[j]; if (pupilCenterRight.Y != 0) ct.estimatedGazeCoordinatesRight.Add(GetGazeCoordinates(EyeEnum.Right, pupilCenterRight, glintConfigRight)); } } #endregion } ct.CalculateAverageCoords(); ct.averageErrorLeft = Operations.Distance(ct.meanGazeCoordinatesLeft, ct.targetCoordinates); if (Settings.Instance.Processing.TrackingMode == TrackingModeEnum.Binocular) ct.averageErrorRight = Operations.Distance(ct.meanGazeCoordinatesRight, ct.targetCoordinates); } CalibrationDataLeft.Calibrated = true; CalculateAverageErrorLeft(); CalculateDegreesLeft(); if (Settings.Instance.Processing.TrackingMode == TrackingModeEnum.Binocular) { CalibrationDataRight.Calibrated = true; CalculateAverageErrorRight(); CalculateDegreesRight(); } #endregion IsCalibrated = true; return IsCalibrated; }
public GTPoint GetGazeCoordinates(EyeEnum eye, GTPoint pupilCenter, GlintConfiguration glintConfig) { var row = new Matrix<double>(6, 1); var screenCoordinates = new Matrix<double>(2, 1); var gazedPoint = new GTPoint(); double X, Y; try { X = pupilCenter.X - glintConfig.AverageCenter.X; Y = pupilCenter.Y - glintConfig.AverageCenter.Y; row[0, 0] = 1; row[1, 0] = X; row[2, 0] = Y; row[3, 0] = X*Y; row[4, 0] = X*X; row[5, 0] = Y*Y; if (eye == EyeEnum.Left) { gazedPoint.X = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataLeft.CoeffsX.Ptr); gazedPoint.Y = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataLeft.CoeffsY.Ptr); } else { gazedPoint.X = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataRight.CoeffsX.Ptr); gazedPoint.Y = CvInvoke.cvDotProduct(row.Ptr, CalibrationDataRight.CoeffsY.Ptr); } } catch (Exception ex) { Console.Out.WriteLine("Calibration.cs, exception in GetGazeCoordinates(), message: " + ex.Message); } return gazedPoint; }
private void DrawGlints(GlintConfiguration glints, int lineLenght) { if (glints != null) { for (int i = 0; i < glints.Count; i++) { Point gcPoint = new Point(Convert.ToInt32(glints.Centers[i].X), Convert.ToInt32(glints.Centers[i].Y)); switch (Settings.Instance.Visualization.VideoMode) { case VideoModeEnum.Normal: gray.Draw(new Cross2DF(gcPoint, lineLenght, lineLenght), new Gray(Settings.Instance.Visualization.GlintCrossGray), 1); break; case VideoModeEnum.Processed: processed.Draw(new Cross2DF(gcPoint, lineLenght, lineLenght), new Bgr(Settings.Instance.Visualization.GlintCrossColor), 1); break; } } } }