public void FindDarkFramesGideon_webcam_1()
 {
     using (findDarkFrames = new FindDarkFramesHelper())
     {
     #if DEBUG
         findDarkFrames.SetCustomDetectionThreshold(100, 75, 3, 0.35f, 1f);
     #endif
         FindDarkFramesHelper.TestResult tr = findDarkFrames.FindDarkFramesTest("Gideon_webcam.m4v.highlightObject.00.03.09.to.00.03.25.m4v");
         if (tr.Failed) Assert.Fail();
     }
 }
Esempio n. 2
0
        public static void DoWork()
        {
            CompletedPassesCountThisSession = 0;

            var findDarkFramesHelper = new FindDarkFramesHelper();

            InputFileCount = findDarkFramesHelper.AvailableFiles.Count();

            /*
            float ConsecutiveDarkFramesThresholdInSecondsStart = (float)0.15; //0.2;
            float ConsecutiveDarkFramesThresholdInSecondsEnd = (float)0.15; // 0.3;
            float ConsecutiveDarkFramesThresholdInSecondsIncrement = (float)0.05;

            int IndividualPixelBrightnessThresholdStart = 80; // 66;
            int IndividualPixelBrightnessThresholdEnd = 80; // 76;
            int IndividualPixelBrightnessThresholdIncrement = 2;

            int DarknessThresholdPercentageStart = 80; // 86;
            int DarknessThresholdPercentageEnd = 80; // 94;
            int DarknessThresholdPercentageIncrement = 2;
            */

            // resume where we left off
            CompletedPassesCount = Properties.Settings.Default.CompletedPassesCount;
            CompletedPassesCountAtSessionStart = CompletedPassesCount;

            int i = 0;

            for (CurrentIndividualPixelBrightnessThreshold = Properties.Settings.Default.ThresholdIndividualPixelBrightnessStart;
                CurrentIndividualPixelBrightnessThreshold <= Properties.Settings.Default.ThresholdIndividualPixelBrightnessEnd;
                CurrentIndividualPixelBrightnessThreshold += Properties.Settings.Default.ThresholdIndividualPixelBrightnessIncrement)
            {

                for (CurrentDarknessPercentageThreshold = Properties.Settings.Default.ThresholdDarkPixelsPerFrameAsPercentageStart;
                    CurrentDarknessPercentageThreshold <= Properties.Settings.Default.ThresholdDarkPixelsPerFrameAsPercentageEnd;
                    CurrentDarknessPercentageThreshold += Properties.Settings.Default.ThresholdDarkPixelsPerFrameAsPercentageIncrement)
                {

                    for (CurrentPixelScanPercentageThreshold = Properties.Settings.Default.ThresholdPixelScanPercentageStart;
                        CurrentPixelScanPercentageThreshold <= Properties.Settings.Default.ThresholdPixelScanPercentageEnd;
                        CurrentPixelScanPercentageThreshold += Properties.Settings.Default.ThresholdPixelScanPercentageIncrement)
                    {

                        int secondsSkipCurrentPass = 1; // needed because we're dealing with floats

                        for (CurrentSecondsSkipThreshold = Properties.Settings.Default.ThresholdSecondsSkipStart;
                            CurrentSecondsSkipThreshold <= Properties.Settings.Default.ThresholdSecondsSkipEnd;
                            CurrentSecondsSkipThreshold = (secondsSkipCurrentPass++) * Properties.Settings.Default.ThresholdSecondsSkipIncrement + Properties.Settings.Default.ThresholdSecondsSkipStart)
                        {

                            int consecutiveDarkFramesInSecondsCurrentPass = 1; // needed because we're dealing with floats

                            for (CurrentConsecutiveDarkFramesInSecondsThreshold = Properties.Settings.Default.ThresholdConsecutiveDarkFramesInSecondsStart;
                                CurrentConsecutiveDarkFramesInSecondsThreshold <= Properties.Settings.Default.ThresholdConsecutiveDarkFramesInSecondsEnd;
                                CurrentConsecutiveDarkFramesInSecondsThreshold = (consecutiveDarkFramesInSecondsCurrentPass++) * Properties.Settings.Default.ThresholdConsecutiveDarkFramesInSecondsIncrement + Properties.Settings.Default.ThresholdConsecutiveDarkFramesInSecondsStart)
                            {

                                CurrentPassNumber = CompletedPassesCount + 1;

                                if (CheckForCancel())
                                    break;

                                i++;

                                if (i < CompletedPassesCount + 1)
                                {
                                    continue; // resume where we left off
                                }

                                CompletedScansInThisPass = 0;

                                PassActualScore = 0;
                                PassMaxScore = 0;
                                PassFoundCount = 0;
                                PassFalsePositivesCount = 0;
                                PassMissingCount = 0;
                                PassAccurateCount = 0;
                                PassScanTime = TimeSpan.Zero;

                                //_logger = new Logging();
                                //_logger.InitLogger("Odessa_TuningLog" + CurrentPassNumber + ".txt", false, true, _tf.LogDirectory);

                                LogInfo("-------------");
                                LogInfo("Starting pass number " + CurrentPassNumber + " of " + TotalPassesCount);
                                LogInfo("CurrentIndividualPixelBrightnessThreshold: " + CurrentIndividualPixelBrightnessThreshold);
                                LogInfo("CurrentDarknessPercentageThreshold: " + CurrentDarknessPercentageThreshold);
                                LogInfo("CurrentPixelScanPercentageThreshold: " + CurrentPixelScanPercentageThreshold);
                                LogInfo("CurrentSecondsSkipThreshold: " + CurrentSecondsSkipThreshold);
                                LogInfo("CurrentConsecutiveDarkFramesInSecondsThreshold: " + CurrentConsecutiveDarkFramesInSecondsThreshold);
                                LogInfo("Total input files: " + InputFileCount);

                                // START SCANNING
                                NextInputFileNumber = 1;

                                _scanFilesQueue = new Queue<FileInfo>(findDarkFramesHelper.AvailableFiles.Values);

                                while (ScanProcessList.Count > 0 || _scanFilesQueue.Count > 0)
                                { // while there are files in this pass being scanned

                                    #region Check whether to start a new process
                                    if (ScanProcessList.Count < AllowedConcurrentScanCount && _scanFilesQueue.Count > 0)
                                    { // we've got room to start a new process

                                        FileInfo fi = _scanFilesQueue.Dequeue();

                                        var si = new ScanItem { InputFileNumber = NextInputFileNumber, ThisFileInfo = fi };

                                        LogInfo("InputFileNumber #" + si.InputFileNumber + ": Scanning " + fi.Name);

                                        // call TuningScanner
                                        var p = new Process();
                                        p.StartInfo.FileName = Path.Combine(Environment.CurrentDirectory, "TuningScannerProject.exe");
                                        p.StartInfo.Arguments = "\"" + fi.FullName + "\" " +
                                            si.InputFileNumber + " " +
                                            CurrentPassNumber + " " +
                                            CurrentIndividualPixelBrightnessThreshold + " " +
                                            CurrentDarknessPercentageThreshold + " " +
                                            CurrentPixelScanPercentageThreshold + " " +
                                            CurrentSecondsSkipThreshold + " " +
                                            CurrentConsecutiveDarkFramesInSecondsThreshold
                                            ;
                                        p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

                                        LogInfo("InputFileNumber #" + si.InputFileNumber + ": Starting with arguments: " + p.StartInfo.FileName + " " + p.StartInfo.Arguments);

                                        p.Start();
                                        p.PriorityClass = ProcessPriorityClass.Idle;

                                        // add it to our ScanProcessList so we can track it
                                        si.ThisProcess = p;
                                        ScanProcessList.Add(si);
                                        NextInputFileNumber += 1;

                                    }
                                    #endregion

                                    #region Check to see if scans have finished
                                    foreach (ScanItem si in ScanProcessList)
                                    {

                                        if (si.ThisProcess.HasExited)
                                        { // process just ended, let's analyze results.

                                            ScanProcessList.Remove(si);

                                            if (si.ThisProcess.ExitCode != 0) // 0 means success.
                                            {
                                                LogInfo("InputFileNumber #" + si.InputFileNumber + ": process did not exit successfully!");
                                                CancelTest = true;
                                                break;
                                            }

                                            // load results from output file
                                            string testResultOutputFilePath = Path.Combine(Path.GetTempPath(), "Odessa_TestResult_" + si.InputFileNumber + ".txt");
                                            LogInfo("InputFileNumber #" + si.InputFileNumber + ": Reading test results from " + testResultOutputFilePath);
                                            FileStream stream = File.Open(testResultOutputFilePath, FileMode.Open);
                                            var bformatter = new BinaryFormatter();
                                            var tr = (FindDarkFramesHelper.TestResult)bformatter.Deserialize(stream);
                                            stream.Close();

                                            // clean up test output file
                                            try
                                            {
                                                File.Delete(testResultOutputFilePath);
                                            }
                                            catch { }

                                            // add test results to pass results
                                            PassFoundCount += tr.Matched.Count;
                                            PassFalsePositivesCount += tr.FalsePositives.Count;
                                            PassMissingCount += tr.Missing.Count;
                                            PassActualScore += tr.ActualScore;
                                            PassMaxScore += tr.MaxScore;
                                            PassScanTime += tr.ScanTime;
                                            if (tr.ActualScore == tr.MaxScore)
                                                PassAccurateCount++;

                                            LogInfo("InputFileNumber #" + si.InputFileNumber + ": inputFile = " + tr.InputFile.Name);

                                            LogInfo("InputFileNumber #" + si.InputFileNumber + ": DarkTimesExpectedCount = " + tr.DarkTimesExpected.Count);
                                            foreach (string expectedDarkTime in tr.DarkTimesExpected)
                                                LogInfo("InputFileNumber #" + si.InputFileNumber + ": - " + expectedDarkTime);

                                            LogInfo("InputFileNumber #" + si.InputFileNumber + ": DarkTimesFoundCount = " + tr.DarkTimesFound.Count);
                                            foreach (string darkTimeFound in tr.DarkTimesFound)
                                                LogInfo("InputFileNumber #" + si.InputFileNumber + ": - " + darkTimeFound);

                                            LogInfo("InputFileNumber #" + si.InputFileNumber + ": MatchedCount = " + tr.Matched.Count);
                                            foreach (string time in tr.Matched)
                                                LogInfo("InputFileNumber #" + si.InputFileNumber + ": - " + time);

                                            LogInfo("InputFileNumber #" + si.InputFileNumber + ": FalsePositivesCount = " + tr.FalsePositives.Count);
                                            foreach (string time in tr.FalsePositives)
                                                LogInfo("InputFileNumber #" + si.InputFileNumber + ": - " + time);

                                            LogInfo("InputFileNumber #" + si.InputFileNumber + ": MissingCount = " + tr.Missing.Count);
                                            foreach (string time in tr.Missing)
                                                LogInfo("InputFileNumber #" + si.InputFileNumber + ": - " + time);

                                            LogInfo("InputFileNumber #" + si.InputFileNumber + ": ActualScore = " + tr.ActualScore);
                                            LogInfo("InputFileNumber #" + si.InputFileNumber + ": MaxScore = " + tr.MaxScore);
                                            LogInfo("InputFileNumber #" + si.InputFileNumber + ": ScanTime = " + tr.ScanTime.TotalSeconds + "secs");

                                            CompletedScansInThisPass += 1;

                                            break; // since we just removed an item from this collection, we can't continue this foreach

                                        }

                                    } // for each process
                                    #endregion

                                    if (CheckForCancel())
                                        break;

                                    Thread.Sleep(1000); // sleep for a second

                                }

                                if (CheckForCancel())
                                    break;

                                LogInfo("PassFoundCount = " + PassFoundCount);
                                LogInfo("PassFalsePositivesCount = " + PassFalsePositivesCount);
                                LogInfo("PassMissingCount = " + PassMissingCount);
                                LogInfo("PassMaxScore = " + PassMaxScore);
                                LogInfo("PassActualScore = " + PassActualScore);
                                LogInfo("PassAccurateCount = " + PassAccurateCount);
                                LogInfo("PassScanTime = " + PassScanTime.TotalSeconds + "secs");

                                _tuningGraphLogger = new Logging();
                                if (_tuningGraphLogger.InitLogger(Program.TUNING_RESULTS_FILENAME, true, false, _tf.LogDirectory))
                                { // log didn't exist before so let's write header
                                    WriteTuningGraphLogHeader();
                                }

                                // write out to tuning graph log
                                if (_tuningGraphLogger.WriteToLog(CurrentPassNumber + "," +
                                    CurrentIndividualPixelBrightnessThreshold + "," +
                                    CurrentDarknessPercentageThreshold + "," +
                                    CurrentPixelScanPercentageThreshold + "," +
                                    CurrentSecondsSkipThreshold + "," +
                                    CurrentConsecutiveDarkFramesInSecondsThreshold + "," +
                                    PassFalsePositivesCount + "," +
                                    PassMissingCount + "," +
                                    "=" + PassAccurateCount + "/" + InputFileCount + "," +
                                    PassScanTime.TotalSeconds + ","
                                    , false) == false)
                                { // write was't successful to our main log (probably because it was left open). let's try writing to a different log
                                    _tuningGraphLogger.CloseLogger(false);
                                    _tuningGraphLogger = null;
                                    _tuningGraphLogger = new Logging();
                                    _tuningGraphLogger.InitLogger("Odessa_TuningGraph_" + (new Random()).Next(1000) + ".csv", true, false, _tf.LogDirectory);
                                    _tuningGraphLogger.WriteToLog(CurrentPassNumber + "," +
                                        CurrentIndividualPixelBrightnessThreshold + "," +
                                        CurrentDarknessPercentageThreshold + "," +
                                        CurrentPixelScanPercentageThreshold + "," +
                                        CurrentSecondsSkipThreshold + "," +
                                        CurrentConsecutiveDarkFramesInSecondsThreshold + "," +
                                        PassFalsePositivesCount + "," +
                                        PassMissingCount + "," +
                                        "=" + PassAccurateCount + "/" + InputFileCount + "," +
                                        PassScanTime.TotalSeconds + ","
                                        , false);
                                }

                                _tuningGraphLogger.CloseLogger(false);
                                _tuningGraphLogger = null;

                                if (CheckForCancel())
                                    break;

                                CompletedPassesCount += 1;
                                CompletedPassesCountThisSession += 1;

                                // save to propertybag so we can resume later
                                Properties.Settings.Default.CurrentThresholdIndividualPixelBrightness = CurrentIndividualPixelBrightnessThreshold;
                                Properties.Settings.Default.CurrentThresholdDarkPixelsPerFrameAsPercentage = CurrentDarknessPercentageThreshold;
                                Properties.Settings.Default.CurrentThresholdPixelScanPercentage = CurrentPixelScanPercentageThreshold;
                                Properties.Settings.Default.CurrentThresholdSecondsSkip = CurrentSecondsSkipThreshold;
                                Properties.Settings.Default.CurrentThresholdConsecutiveDarkFramesInSeconds = CurrentConsecutiveDarkFramesInSecondsThreshold;
                                Properties.Settings.Default.CompletedPassesCount = CompletedPassesCount;
                                Properties.Settings.Default.Save();

                                LogInfo("CompletedPassesCount = " + CompletedPassesCount);

                                // close log and archive it
                                /* REMED out on 9/27/11 because we now save the logs to this new directory from the start
                                string OldTuningLogFilePath = Logger.LogFilePath;
                                Logger.CloseLogger();
                                Logger = null;
                                string NewTuningLogFilePath = Path.Combine(Properties.Settings.Default.TuningResultsDirectory, "Odessa_TuningLog" + CurrentPassNumber + ".txt");
                                try
                                {
                                    File.Copy(OldTuningLogFilePath, NewTuningLogFilePath, true);
                                    File.Delete(OldTuningLogFilePath);
                                }
                                catch (Exception ex)
                                {
                                    Debug.WriteLine("Error copying log file: " + ex.ToString());
                                }
                                 */

                                if (CheckForCancel())
                                    break;

                            } // for loop

                            if (CheckForCancel())
                                break;

                        } // for loop

                        if (CheckForCancel())
                            break;

                    } // for loop

                    if (CheckForCancel())
                        break;

                } // for loop

                if (CheckForCancel())
                    break;

            } // for loop

            Logger.Info("Done with massive loop!");

            findDarkFramesHelper.Dispose();

            if (CheckForCancel() == false)
                _tf.Invoke(_tf.MDelegateThreadFinished);
        }
 public void FindDarkFrames_Marius()
 {
     using (findDarkFrames = new FindDarkFramesHelper())
     {
         findDarkFrames.SetCustomDetectionThreshold(65, 55, 3, 0.35f, 1f);
         FindDarkFramesHelper.TestResult tr = findDarkFrames.FindDarkFramesTest("GOPR8417_marius.MP4");
         if (tr.Failed) Assert.Fail();
     }
 }
 public void FindDarkFramesTubing_1()
 {
     using (findDarkFrames = new FindDarkFramesHelper())
     {
         findDarkFrames.SetCustomDetectionThreshold(70, 80, 3, 0.35f, 0.3f);
         FindDarkFramesHelper.TestResult tr = findDarkFrames.FindDarkFramesTest("tubing GO019316 highlight #10 - 11.50 to 12.00.MP4");
         if (tr.Failed) Assert.Fail();
     }
 }
Esempio n. 5
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="args">Engine parameters</param>
        static void Main(string[] args)
        {
            Environment.ExitCode = -1; // assume fail until we reach end

            var findDarkFramesHelper = new FindDarkFramesHelper();

            string currentFileName;
            int currentPassNumber;
            int processIndex;
            int thresholdIndividualPixelBrightness;
            int thresholdDarkPixelsPerFrameAsPercentage;
            int thresholdPixelScanPercentage;
            float thresholdSecondsSkip;
            float thresholdConsecutiveDarkFramesInSeconds;

            try
            {
                currentFileName = args[0];
                processIndex = int.Parse(args[1]);
                currentPassNumber = int.Parse(args[2]);

                thresholdIndividualPixelBrightness = int.Parse(args[3]);
                thresholdDarkPixelsPerFrameAsPercentage = int.Parse(args[4]);
                thresholdPixelScanPercentage = int.Parse(args[5]);
                thresholdSecondsSkip = float.Parse(args[6]);
                thresholdConsecutiveDarkFramesInSeconds = float.Parse(args[7]);
                //Logger.InitLogger("Odessa_TuningScanner_" + processIndex + ".log");

            #if TEST

                findDarkFramesHelper.SetCustomDetectionThreshold(
                    thresholdIndividualPixelBrightness,
                    thresholdDarkPixelsPerFrameAsPercentage,
                    thresholdPixelScanPercentage,
                    thresholdSecondsSkip,
                    thresholdConsecutiveDarkFramesInSeconds
                    );
            #else
                Console.WriteLine("THIS ONLY RUNS UNDER TEST CONFIG!!");
                Console.ReadLine();
            #endif

            }
            catch (Exception ex)
            {
                Logger.Error("Exception while loading arguments! Closing... " + ex);
                return;
            }

            Logger.Info("{0}, Pass Number: {1}", processIndex, currentPassNumber);
            Logger.Info("{0}, ThresholdIndividualPixelBrightness: {1}", processIndex, thresholdIndividualPixelBrightness);
            Logger.Info("{0}, ThresholdDarkPixelsPerFrameAsPercentage: {1}", processIndex, thresholdDarkPixelsPerFrameAsPercentage);
            Logger.Info("{0}, ThresholdPixelScanPercentage: {1}", processIndex, thresholdPixelScanPercentage);
            Logger.Info("{0}, ThresholdSecondsSkip: {1}", processIndex, thresholdSecondsSkip);
            Logger.Info("{0}, ThresholdConsecutiveDarkFramesInSeconds: {1}", processIndex, thresholdConsecutiveDarkFramesInSeconds);

            Logger.Info("{0}, Scanning {1}", processIndex, currentFileName);

            string filename = (new FileInfo(currentFileName)).Name;

            FindDarkFramesHelper.TestResult tr;
            try
            {
                tr = findDarkFramesHelper.FindDarkFramesTest(filename);
            }
            catch (Exception ex)
            {
                Logger.Error("{0}, Exception writing test results to output file: {1}", processIndex, ex);
                Environment.ExitCode = -1; // fail
                findDarkFramesHelper.Dispose();
                return;
            }

            Logger.Info("{0}, {1} score: {2} out of possible {3}", processIndex, filename, tr.ActualScore, tr.MaxScore);

            try
            {
                // save results where the host process can get it
                Logger.Info("{0}, Writing test results to output file", processIndex);
                Stream stream = File.Open(Path.Combine(Path.GetTempPath(), "Odessa_TestResult_" + processIndex + ".txt"), FileMode.Create);
                var bformatter = new BinaryFormatter();
                bformatter.Serialize(stream, tr);
                stream.Close();
            }
            catch (Exception ex)
            {
                Logger.Error("{0}, Exception writing test results to output file: {1}", processIndex, ex);
                Environment.ExitCode = -1; // fail
            }

            findDarkFramesHelper.Dispose();

            Logger.Info("{0}, Closing down", processIndex);

            Environment.ExitCode = 0; // success
        }
Esempio n. 6
0
        private void RunButton_Click(object sender, EventArgs e)
        {
            RunButton.Enabled = false;
            RunButton.Text = "Running...";
            CancelTestButton.Enabled = true;
            ProgressTimer.Enabled = true;
            ResetButton.Enabled = false;
            TuningResultsDirectoryTextBox.Enabled = false;
            LogDirectory = Directory.CreateDirectory(TuningResultsDirectoryTextBox.Text);
            TuningResultsDirectoryBrowseButton.Enabled = false;
            TrimButton.Enabled = false;
            AdjustConcurrentScanCount.Enabled = true;
            SetThresholdSetupComboBoxesEnableValue(false);
            Application.DoEvents();

            #region verify that all input files exist
            bool everyInputFileExists = true;

            var findDarkFramesHelper = new FindDarkFramesHelper();

            foreach (KeyValuePair<string, FileInfo> kvp in findDarkFramesHelper.AvailableFiles)
            {
                if (kvp.Value.Exists == false)
                {
                    everyInputFileExists = false;
                    MessageBox.Show("inputFile does not exist!" + Environment.NewLine + Environment.NewLine +
                        kvp.Value.FullName, "inputFile does not exist!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            findDarkFramesHelper.Dispose();

            if (findDarkFramesHelper.AvailableFiles.Count == 0)
            {
                MessageBox.Show("No files to scan!");
                ScanCancelled();
                return;
            }

            if (everyInputFileExists == false)
            {
                ScanCancelled();
                return;
            }
            #endregion

            #region Verify valid threshold parameters

            if (Convert.ToInt32(ThresholdIndividualPixelBrightnessSetupStart.SelectedItem) > Convert.ToInt32(ThresholdIndividualPixelBrightnessSetupEnd.SelectedItem) ||
                Convert.ToInt32(ThresholdDarkPixelsPerFrameAsPercentageSetupStart.SelectedItem) > Convert.ToInt32(ThresholdDarkPixelsPerFrameAsPercentageSetupEnd.SelectedItem) ||
                Convert.ToInt32(ThresholdPixelScanPercentageSetupStart.SelectedItem) > Convert.ToInt32(ThresholdPixelScanPercentageSetupEnd.SelectedItem) ||
                Convert.ToDecimal(ThresholdSecondsSkipSetupStart.SelectedItem) > Convert.ToDecimal(ThresholdSecondsSkipSetupEnd.SelectedItem) ||
                Convert.ToDecimal(ThresholdConsecutiveDarkFramesInSecondsStart.SelectedItem) > Convert.ToDecimal(ThresholdConsecutiveDarkFramesInSecondsEnd.SelectedItem))
            {
                MessageBox.Show("Invalid threshold parameters! Start values must be less than end values.");
                ScanCancelled();
                return;
            }

            #endregion

            #region Save threshold parameters

            Properties.Settings.Default.ThresholdIndividualPixelBrightnessStart = Convert.ToInt32(ThresholdIndividualPixelBrightnessSetupStart.SelectedItem);
            Properties.Settings.Default.ThresholdIndividualPixelBrightnessEnd = Convert.ToInt32(ThresholdIndividualPixelBrightnessSetupEnd.SelectedItem);
            Properties.Settings.Default.ThresholdIndividualPixelBrightnessIncrement = Convert.ToInt32(ThresholdIndividualPixelBrightnessSetupIncrement.SelectedItem);

            Properties.Settings.Default.ThresholdDarkPixelsPerFrameAsPercentageStart = Convert.ToInt32(ThresholdDarkPixelsPerFrameAsPercentageSetupStart.SelectedItem);
            Properties.Settings.Default.ThresholdDarkPixelsPerFrameAsPercentageEnd = Convert.ToInt32(ThresholdDarkPixelsPerFrameAsPercentageSetupEnd.SelectedItem);
            Properties.Settings.Default.ThresholdDarkPixelsPerFrameAsPercentageIncrement = Convert.ToInt32(ThresholdDarkPixelsPerFrameAsPercentageSetupIncrement.SelectedItem);

            Properties.Settings.Default.ThresholdPixelScanPercentageStart = Convert.ToInt32(ThresholdPixelScanPercentageSetupStart.SelectedItem);
            Properties.Settings.Default.ThresholdPixelScanPercentageEnd = Convert.ToInt32(ThresholdPixelScanPercentageSetupEnd.SelectedItem);
            Properties.Settings.Default.ThresholdPixelScanPercentageIncrement = Convert.ToInt32(ThresholdPixelScanPercentageSetupIncrement.SelectedItem);

            Properties.Settings.Default.ThresholdSecondsSkipStart = float.Parse(ThresholdSecondsSkipSetupStart.SelectedItem.ToString());
            Properties.Settings.Default.ThresholdSecondsSkipEnd = float.Parse(ThresholdSecondsSkipSetupEnd.SelectedItem.ToString());
            Properties.Settings.Default.ThresholdSecondsSkipIncrement = float.Parse(ThresholdSecondsSkipIncrement.SelectedItem.ToString());

            Properties.Settings.Default.ThresholdConsecutiveDarkFramesInSecondsStart = float.Parse(ThresholdConsecutiveDarkFramesInSecondsStart.SelectedItem.ToString());
            Properties.Settings.Default.ThresholdConsecutiveDarkFramesInSecondsEnd = float.Parse(ThresholdConsecutiveDarkFramesInSecondsEnd.SelectedItem.ToString());
            Properties.Settings.Default.ThresholdConsecutiveDarkFramesInSecondsIncrement = float.Parse(ThresholdConsecutiveDarkFramesInSecondsIncrement.SelectedItem.ToString());

            Properties.Settings.Default.Save();
            #endregion

            // verify we have write access to excel spreadsheet
            try
            {
                if (File.Exists(GetTuningPath().FullName))
                {
                    // the following line will cause exception if file is open
                    new StreamWriter(GetTuningPath().FullName, true);
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Test pass output file is open! Please close it before continuing.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            _startTime = DateTime.Now;

            AdjustConcurrentScanCount_Tick(sender, e); // refresh allowed concurrent scan count

            HostWorker.Initialize(this);
            var workerThread = new Thread(HostWorker.DoWork);

            // Start the worker thread.
            workerThread.Start();
            Logger.Info("main thread: Starting worker thread...");
        }