コード例 #1
0
        public List <PointInfo> GetClosestCorrections(float[] cursor_position)
        {
            if (!Helpers.AreCoordinatesSane(cursor_position))
            {
                return(null);
            }
            List <PointInfo> retval = new List <PointInfo>();

            cache.ChangeCursorPosition(cursor_position);
            calibration_window?.OnCursorPositionUpdate(cursor_position);

            if (cache.ClosestPoints == null)
            {
                return(null);
            }

            foreach (var point_info in cache.ClosestPoints)
            {
                retval.Add(new PointInfo
                {
                    correction = Corrections[point_info.index],
                    distance   = point_info.distance,
                    vector_from_correction_to_cursor = point_info.vector_from_correction_to_cursor,
                    weight = 1,
                });
            }

            MoveClosestPointBack();

            return(retval);
        }
コード例 #2
0
        public Point GetShift(float[] cursor_position)
        {
            if (cursor_position.Length != calibration_mode.additional_dimensions_configuration.CoordinatesCount)
            {
                return(new Point(0, 0));
            }

            var closest_corrections = shift_storage.GetClosestCorrections(cursor_position);

            if (closest_corrections == null)
            {
                Debug.Assert(shift_storage.Corrections.Count() == 0 || !Helpers.AreCoordinatesSane(cursor_position));
                return(new Point(0, 0));
            }


            float sum_of_reverse_distances = 0;

            foreach (var index in closest_corrections)
            {
                sum_of_reverse_distances += (1 / index.distance);
            }


            ApplyShades(closest_corrections);

            foreach (var correction in closest_corrections)
            {
                correction.weight = correction.weight / correction.distance / sum_of_reverse_distances;
            }

            Helpers.NormalizeWeights(closest_corrections);

            var result = Helpers.GetWeightedAverage(closest_corrections);

            if (shift_storage.calibration_window != null)
            {
                var lables = new List <Tuple <string /*text*/, System.Windows.Point> >();
                foreach (var correction in closest_corrections)
                {
                    lables.Add(new Tuple <string, System.Windows.Point>((int)(correction.weight * 100) + "%",
                                                                        new System.Windows.Point(
                                                                            correction.correction.сoordinates[0],
                                                                            correction.correction.сoordinates[1])));
                }
                shift_storage.calibration_window.UpdateCorrectionsLables(lables);
                shift_storage.calibration_window.UpdateCurrentCorrection(new EyeTrackerErrorCorrection(cursor_position, result));
            }

            return(result);
        }
コード例 #3
0
        public void AddShift(float[] cursor_position, Point shift)
        {
            if (!Helpers.AreCoordinatesSane(cursor_position))
            {
                return;
            }
            cache.ChangeCursorPosition(cursor_position);
            var closest_shifts = cache.ClosestPoints;

            if (closest_shifts != null && closest_shifts[0].distance < calibration_mode.zone_size)
            {
                cache.FreeIndex(closest_shifts[0].index);
                Corrections.RemoveAt(closest_shifts[0].index);
                if (closest_shifts.Count > 1 && closest_shifts[1].distance < calibration_mode.zone_size)
                {
                    Debug.Assert(closest_shifts[1].index != closest_shifts[0].index);
                    if (closest_shifts[1].index > closest_shifts[0].index)
                    {
                        closest_shifts[1].index--;
                    }
                    cache.FreeIndex(closest_shifts[1].index);
                    Corrections.RemoveAt(closest_shifts[1].index);
                }
            }
            else if (Corrections.Count >= calibration_mode.max_zones_count)
            {
                Debug.Assert(Corrections.Count == calibration_mode.max_zones_count);
                // Remove least recently used item from the front of |Corrections|.
                cache.FreeIndex(0);
                Corrections.RemoveAt(0);
            }

            if (cache.AllocateIndex() != Corrections.Count)
            {
                throw new Exception("Logic error");
            }
            cache.SaveToCache(cursor_position, Corrections.Count);
            Corrections.Add(new EyeTrackerErrorCorrection(cursor_position, shift));

            OnShiftsChanged();
        }
コード例 #4
0
        public Point GetShift(float[] cursor_position)
        {
            if (cursor_position.Length != calibration_mode.additional_dimensions_configuration.CoordinatesCount)
            {
                return(new Point(0, 0));
            }
            // |GetClosestCorrections| is computationaly heavy. We call it once and create copies for V0 and V1 parts of this function.
            List <ShiftsStorage.PointInfo> closest_corrections_v0 = new List <ShiftsStorage.PointInfo>(calibration_mode.considered_zones_count);
            List <ShiftsStorage.PointInfo> closest_corrections_v1 = new List <ShiftsStorage.PointInfo>(calibration_mode.considered_zones_count_v1);
            {
                var closest_corrections = shift_storage.GetClosestCorrections(cursor_position);
                if (closest_corrections == null || closest_corrections.Count() == 0)
                {
                    Debug.Assert(shift_storage.Corrections.Count() == 0 || !Helpers.AreCoordinatesSane(cursor_position));
                    return(new Point(0, 0));
                }
                for (int i = 0; i < closest_corrections.Count; i++)
                {
                    var correction = closest_corrections[i];
                    if (i < calibration_mode.considered_zones_count)
                    {
                        closest_corrections_v0.Add(new ShiftsStorage.PointInfo {
                            correction = correction.correction,
                            distance   = correction.distance,
                            weight     = correction.weight,
                            vector_from_correction_to_cursor = correction.vector_from_correction_to_cursor
                        });
                    }
                    if (i < calibration_mode.considered_zones_count_v1)
                    {
                        closest_corrections_v1.Add(new ShiftsStorage.PointInfo
                        {
                            correction = correction.correction,
                            distance   = correction.distance,
                            weight     = correction.weight,
                            vector_from_correction_to_cursor = correction.vector_from_correction_to_cursor
                        });
                    }
                }
            }
            // V0 part (average of closest error corrections weighted by distance):
            float sum_of_reverse_distances = 0;

            foreach (var index in closest_corrections_v0)
            {
                sum_of_reverse_distances += (1 / index.distance);
            }

            foreach (var correction in closest_corrections_v0)
            {
                correction.weight = 1 / correction.distance / sum_of_reverse_distances;
            }

            // V1 part (same as V0 plus shading)
            sum_of_reverse_distances = 0;
            foreach (var index in closest_corrections_v1)
            {
                sum_of_reverse_distances += (1 / index.distance);
            }
            ApplyShades(closest_corrections_v1);
            foreach (var correction in closest_corrections_v1)
            {
                correction.weight = correction.weight / correction.distance / sum_of_reverse_distances;
            }
            Helpers.NormalizeWeights(closest_corrections_v1);

            // Compute ratio of V0/V1 infuence on final result.
            Debug.Assert(calibration_mode.correction_fade_out_distance > 0);
            var   vector_from_correction_to_cursor = closest_corrections_v1[0].vector_from_correction_to_cursor;
            float XYdistance = (float)Math.Sqrt(
                vector_from_correction_to_cursor[0] * vector_from_correction_to_cursor[0] +
                vector_from_correction_to_cursor[1] * vector_from_correction_to_cursor[1]);
            // Longer the distance lower the factor.
            float v0_vs_v1_factor = 1.0f - (float)Math.Pow(
                XYdistance / calibration_mode.correction_fade_out_distance, 4);

            if (v0_vs_v1_factor < 0)
            {
                v0_vs_v1_factor = 0;
            }

            // Merge v0 and v1 to single set using the computed factor.
            List <ShiftsStorage.PointInfo> v1_v0_hybrid_corrections = new List <ShiftsStorage.PointInfo>();

            foreach (var correction in closest_corrections_v1)
            {
                correction.weight = v0_vs_v1_factor * correction.weight;
                v1_v0_hybrid_corrections.Add(correction);
            }

            foreach (var correction in closest_corrections_v0)
            {
                correction.weight = (1 - v0_vs_v1_factor) * correction.weight;
                int i = 0;
                for (; i < v1_v0_hybrid_corrections.Count; i++)
                {
                    if (correction.correction == v1_v0_hybrid_corrections[i].correction)
                    {
                        v1_v0_hybrid_corrections[i].weight += correction.weight;
                        break;
                    }
                }
                if (i == v1_v0_hybrid_corrections.Count)
                {
                    v1_v0_hybrid_corrections.Add(correction);
                }
            }

            var result = Helpers.GetWeightedAverage(v1_v0_hybrid_corrections);

            if (shift_storage.calibration_window != null)
            {
                var lables = new List <Tuple <string /*text*/, System.Windows.Point> >();
                foreach (var correction in v1_v0_hybrid_corrections)
                {
                    lables.Add(new Tuple <string, System.Windows.Point>((int)(correction.weight * 100) + "%",
                                                                        new System.Windows.Point(
                                                                            correction.correction.сoordinates[0],
                                                                            correction.correction.сoordinates[1])));
                }
                shift_storage.calibration_window.UpdateCorrectionsLables(lables);
                shift_storage.calibration_window.UpdateCurrentCorrection(new EyeTrackerErrorCorrection(cursor_position, result));
            }

            return(result);
        }