/// <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);
        }
예제 #2
0
        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;
            }
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
 public GlintData()
 {
     Glints = new GlintConfiguration(10);
 }
예제 #5
0
 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;
        }
예제 #7
0
        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;
        }
예제 #8
0
        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;
        }
예제 #9
0
        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;
                    }
                }
            }
        }