public void Test_0330_QLCalibration_Save_Load()
        {
            int     calibrationId;
            QLError error = QuickLink2API.QLCalibration_Create(0, out calibrationId);

            Assert.AreEqual(QLError.QL_ERROR_OK, error);

            // Try to load non-existent calibration data into the container.
            // Check that the correct error is returned.
            string fakeCalibrationFilename = System.IO.Path.Combine(QLHelper.ConfigDirectory, "qlcalibrationFake.qlc");

            error = QuickLink2API.QLCalibration_Load(fakeCalibrationFilename, ref calibrationId);
            Assert.AreNotEqual(QLError.QL_ERROR_OK, error);

            // Try to load a previously saved calibration file into the container.
            // Check that the correct error is returned.
            error = QuickLink2API.QLCalibration_Load(Test_SetUp.Helper.CalibrationFilename, ref calibrationId);
            Assert.AreNotEqual(QLError.QL_ERROR_INVALID_PATH, error, "Calibration file not found.  You may need to run the SetupDevice example first.");
            Assert.AreEqual(QLError.QL_ERROR_OK, error);

            // Save the calibration to a different path and check that the two files are the same
            string duplicateCalibrationFilename = System.IO.Path.Combine(QLHelper.ConfigDirectory, "qlcalibrationDuplicate.qlc");

            if (System.IO.File.Exists(duplicateCalibrationFilename))
            {
                System.IO.File.Delete(duplicateCalibrationFilename);
            }
            error = QuickLink2API.QLCalibration_Save(duplicateCalibrationFilename, calibrationId);
            Assert.AreEqual(QLError.QL_ERROR_OK, error);
            string calibration1 = System.IO.File.ReadAllText(Test_SetUp.Helper.CalibrationFilename);
            string calibration2 = System.IO.File.ReadAllText(duplicateCalibrationFilename);

            Assert.AreEqual(calibration1, calibration2);
            System.IO.File.Delete(duplicateCalibrationFilename);
        }
        public void Test_0360_QLDevice_ApplyCalibration()
        {
            int     calibrationId;
            QLError error = QuickLink2API.QLCalibration_Create(0, out calibrationId);

            Assert.AreEqual(QLError.QL_ERROR_OK, error);

            error = QuickLink2API.QLCalibration_Load(Test_SetUp.Helper.CalibrationFilename, ref calibrationId);
            Assert.AreNotEqual(QLError.QL_ERROR_INVALID_PATH, error, "Calibration file not found.  You may need to run the SetupDevice example first.");
            Assert.AreEqual(QLError.QL_ERROR_OK, error);

            error = QuickLink2API.QLDevice_ApplyCalibration(Test_SetUp.Helper.DeviceId, calibrationId);
            Assert.AreEqual(QLError.QL_ERROR_OK, error);
        }
        public void Test_0340_QLCalibration_AddBias()
        {
            int     calibrationId;
            QLError error = QuickLink2API.QLCalibration_Create(0, out calibrationId);

            Assert.AreEqual(QLError.QL_ERROR_OK, error);

            error = QuickLink2API.QLCalibration_Load(Test_SetUp.Helper.CalibrationFilename, ref calibrationId);
            Assert.AreNotEqual(QLError.QL_ERROR_INVALID_PATH, error, "Calibration file not found.  You may need to run the SetupDevice example first.");
            Assert.AreEqual(QLError.QL_ERROR_OK, error);

            error = QuickLink2API.QLCalibration_AddBias(calibrationId, QLEyeType.QL_EYE_TYPE_LEFT, .2f, .2f);
            Assert.AreEqual(QLError.QL_ERROR_OK, error);

            error = QuickLink2API.QLCalibration_AddBias(calibrationId, QLEyeType.QL_EYE_TYPE_RIGHT, .2f, .2f);
            Assert.AreEqual(QLError.QL_ERROR_OK, error);
        }
Beispiel #4
0
        /// <summary>
        /// <para>
        /// Loads eye tracker device calibration from the location specified by
        /// <see cref="CalibrationFilename"/>, or performs interactive calibration--if calibration cannot
        /// be loaded from the file--and saves it to the calibration file.  Optionally, (when the
        /// <paramref name="promptToRecalibrate"/> parameter is true) this method will prompt the user to
        /// re-perform interactive calibration even when the calibration has successfully been loaded
        /// from the calibration file.
        /// </para>
        /// <para>
        /// If interactive calibration is chosen (via the <paramref name="promptToRecalibrate"/>
        /// parameter being set to true) or required (when no stored calibration file is present), the
        /// user is prompted to choose 5, 9, or 16 point calibration, choose the duration for
        /// display of each target (in milliseconds), and specify the device's distance from the user.
        /// </para>
        /// <para>
        /// During interactive calibration, the user will be given the option to view the live video
        /// stream from the device in order to adjust camera focus and orientation for best results.
        /// </para>
        /// <para>
        /// Interactive calibration may attempt to improve its results by redisplaying some targets
        /// several times immediately after the initial, ordered target sequence has been displayed.
        /// During this improvement process, warning messages may appear on the console; this is normal
        /// and informative only.
        /// </para>
        /// <para>
        /// After a successful interactive calibration procedure, the user will be shown a score and
        /// prompted to apply or discard the results.  The score is the average of the left and right
        /// scores for each target.  Each left and right score for a target is the magnitude of the
        /// distance of the projected gaze location from the center of the target.  In other words, a
        /// lower score is better.
        /// </para>
        /// </summary>
        /// <seealso cref="SetupCalibration()"/>
        /// <param name="promptToRecalibrate">
        /// When true, the user will be asked if they would like to re-perform the eye tracker device's
        /// calibration even when the calibration was successfully loaded from the calibration file.
        /// </param>
        /// <returns>
        /// <para>
        /// If calibration was loaded from file, this method returns true when the calibration has been
        /// successfully applied to the device.
        /// </para>
        /// <para>
        /// If calibration was not loaded from the device, then this method returns true when the
        /// calibration procedure has been completed, the calibration has been applied to the device, the
        /// calibration has been saved to the calibration file, and the eye tracker has been successfully
        /// stopped.
        /// </para>
        /// <para>
        /// If calibration was successfully loaded and applied from the calibration file, but the user
        /// has chosen to re-perform the calibration procedure, then true is returned if the user cancels
        /// the re-calibration before the actual calibration sequence begins, or when the newly performed
        /// calibration has been completed, the newly performed calibration has been applied to the
        /// device, the newly performed calibration has been saved to the calibration file, and the eye
        /// tracker device has been stopped.
        /// </para>
        /// <para>
        /// Otherwise, this method returns false.
        /// </para>
        /// </returns>
        /// <exception cref="DllNotFoundException">
        /// The QuickLink2 DLLs ("QuickLink2.dll," "PGRFlyCapture.dll," and "SMX11MX.dll") must be placed
        /// in the same directory as your program's binary executable; otherwise, this exception will be
        /// thrown.
        /// </exception>
        public bool SetupCalibration(bool promptToRecalibrate)
        {
            int deviceDistance;

            if (!LoadDeviceDistance(this.SettingsFilename, out deviceDistance))
            {
                return(false);
            }

            if (deviceDistance == 0)
            {
                deviceDistance = DefaultDeviceDistance;
                if (!SaveDeviceDistance(this.SettingsFilename, deviceDistance))
                {
                    return(false);
                }
            }

            if (!ApplyDeviceDistance(this.DeviceId, deviceDistance))
            {
                return(false);
            }

            bool calibrationLoadedFromFile = false;

            // Load the calibration out of a file into a new calibration container.
            int     calibrationId = -1;
            QLError error         = QuickLink2API.QLCalibration_Load(this.CalibrationFilename, ref calibrationId);

            if (error == QLError.QL_ERROR_OK)
            {
                // Apply the loaded calibration to the device.
                error = QuickLink2API.QLDevice_ApplyCalibration(this.DeviceId, calibrationId);
                if (error == QLError.QL_ERROR_OK)
                {
                    Console.WriteLine("Calibration loaded from file.");
                    if (!promptToRecalibrate || !PromptToRecalibrate())
                    {
                        // Loaded from file and no prompt for recalibration
                        // requested, or recalibration cancelled.
                        return(true);
                    }
                    calibrationLoadedFromFile = true;
                }
            }

            Console.WriteLine();
            Console.WriteLine("Beginning calibration setup.");

            bool showVideoStream;

            if (!PromptForShowVideoStream(out showVideoStream))
            {
                // Cancelled.
                return(calibrationLoadedFromFile);
            }
            else if (showVideoStream)
            {
                if (!ShowVideoStream())
                {
                    // Error.
                    return(false);
                }
            }

            Console.WriteLine();
            Console.WriteLine("[Calibration Parameters]");
            Console.WriteLine("  Press ENTER to use (default), or enter 'q' to quit.");

            int newDeviceDistance;

            if (!PromptForDeviceDistance(out newDeviceDistance))
            {
                // Cancelled.
                return(calibrationLoadedFromFile);
            }
            else if (newDeviceDistance != deviceDistance)
            {
                deviceDistance = newDeviceDistance;
                if (!SaveDeviceDistance(this.SettingsFilename, deviceDistance))
                {
                    // Error.
                    return(false);
                }
                else if (!ApplyDeviceDistance(this.DeviceId, newDeviceDistance))
                {
                    // Error.
                    return(false);
                }
            }

            QLCalibrationType calibrationType;

            if (!PromptForCalibrationType(out calibrationType))
            {
                // Cancelled.
                return(calibrationLoadedFromFile);
            }

            int targetDuration;

            if (!PromptForTargetDuration(out targetDuration))
            {
                // Cancelled.
                return(calibrationLoadedFromFile);
            }

            Console.WriteLine();
            Console.WriteLine("Beginning calibration.");

            if (!Calibrate(this.DeviceId, this.CalibrationFilename, deviceDistance, calibrationType, targetDuration))
            {
                Console.WriteLine("Calibration failed.");
                return(false);
            }
            else
            {
                Console.WriteLine("Calibration completed, applied, and saved.\n");
                return(true);
            }
        }