private void DisplayFoundIntegration(PotentialIntegrationFit foundIntegration) { m_FoundIntegration = foundIntegration; this.Invoke(new Action(() => { progressBar1.Value = progressBar1.Maximum; progressBar1.Style = ProgressBarStyle.Continuous; progressBar1.Refresh(); pnlResult.Visible = true; pnlResult.BringToFront(); if (foundIntegration != null) { lblIntegrationFrames.Text = string.Format("{0} frames", foundIntegration.Interval); lblStartingAt.Text = foundIntegration.StartingAtFrame.ToString(); lblCertainty.Text = foundIntegration.CertaintyText; btnAccept.Visible = true; btnReject.Text = "Reject"; } else { lblIntegrationFrames.Text = "Detection Failed"; lblStartingAt.Text = "N/A"; lblCertainty.Text = "N/A"; btnAccept.Visible = false; btnReject.Text = "Close"; } })); }
private void OnPotentialIntegration(PotentialIntegrationFit fit) { if (m_RecordPixelFile) { m_PixDetFile.WriteFooter(fit.Interval, fit.StartingAtFrame, fit.Certainty, fit.AboveSigmaRatio); m_PixDetFile.Dispose(); } if (m_ExpectedFit != null) { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(); Console.WriteLine("[Integration Detection] " + m_VideoFileName); Console.ForegroundColor = m_ExpectedFit.Interval == fit.Interval ? ConsoleColor.Green : ConsoleColor.Red; Console.WriteLine("[Detected Interval] Expected:{0} Actual:{1}", m_ExpectedFit.Interval, fit.Interval); Console.ForegroundColor = m_ExpectedFit.StartingAtFrame == fit.StartingAtFrame ? ConsoleColor.Green : ConsoleColor.Red; Console.WriteLine("[Starting At Frame] Expected:{0} Actual:{1}", m_ExpectedFit.StartingAtFrame, fit.StartingAtFrame); Console.ForegroundColor = Math.Abs(m_ExpectedFit.Certainty - fit.Certainty) < 0.1 ? ConsoleColor.Green : ConsoleColor.Red; Console.WriteLine("[Certainty] Expected:{0} Actual:{1}", m_ExpectedFit.Certainty, fit.Certainty); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(); } else { // TODO: Console.Write (green = detected; red = failed to detect) } m_RunFinished.Set(); }
private bool IsGuessWithSimilarSigmaAsOtherNonGuesses(PotentialIntegrationFit guess) { int frameToCheck = guess.StartingAtFrame - 1; int cnt = 0; double sigmaSum = 0; while (frameToCheck > 0 && frameToCheck < m_SigmaDict.Count) { sigmaSum += Math.Abs(m_SigmaDict[frameToCheck]); cnt++; frameToCheck += guess.Interval; } double averageSigmaForGuess = sigmaSum / cnt; Dictionary <int, double> sameOrHigherPoints = m_SigmaDict .Where(kvp => (kvp.Key - guess.StartingAtFrame + 1) % guess.Interval != 0 && kvp.Value >= averageSigmaForGuess) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); int numPointsNotInGuessWithSameOrHigherSigmas = sameOrHigherPoints.Count(); if (numPointsNotInGuessWithSameOrHigherSigmas > (1.0 * m_SigmaDict.Count / guess.Interval) - 1) { // Too many other points with similar sigma return(true); } return(false); }
private bool ProbeIntegration2Interval(List <PotentialIntegrationFit> guessesMinFrame, List <PotentialIntegrationFit> guessesMaxOffset) { var oddSigmas = m_SigmaDict.Where(kvp => kvp.Key % 2 == 1).Select(kvp => kvp.Value).ToList(); var evenSigmas = m_SigmaDict.Where(kvp => kvp.Key % 2 == 0).Select(kvp => kvp.Value).ToList(); var oddMedian = oddSigmas.Median(); var oddVariance = Math.Sqrt(oddSigmas.Sum(x => (x - oddMedian) * (x - oddMedian)) / (oddSigmas.Count - 1)); var evenMedian = evenSigmas.Median(); var evenVariance = Math.Sqrt(evenSigmas.Sum(x => (x - evenMedian) * (x - evenMedian)) / (evenSigmas.Count - 1)); if (oddMedian > evenMedian) { // Could this be a x2 integration starting from an odd frame? if (oddMedian - 3 * oddVariance > evenMedian + 3 * evenVariance) { // Yes! var potentialFit = new PotentialIntegrationFit() { Interval = 2, StartingAtFrame = m_SigmaDict.Where(kvp => kvp.Key % 2 == 1).Min(kvp => kvp.Key) + 1, AboveSigmaRatio = oddSigmas.Sum() / (oddMedian * oddSigmas.Count), Certainty = 3, CertaintyText = "Average" }; guessesMinFrame.Add(potentialFit); guessesMaxOffset.Add(potentialFit); return(true); } } else if (evenMedian > oddMedian) { // Could this be a x2 integration starting from an even frame? if (evenMedian - 3 * evenVariance > oddMedian + 3 * oddVariance) { // Yes! var potentialFit = new PotentialIntegrationFit() { Interval = 2, StartingAtFrame = m_SigmaDict.Where(kvp => kvp.Key % 2 == 0).Min(kvp => kvp.Key) + 1, AboveSigmaRatio = evenSigmas.Sum() / (evenMedian * evenSigmas.Count), Certainty = 3, CertaintyText = "Average" }; guessesMinFrame.Add(potentialFit); guessesMaxOffset.Add(potentialFit); return(true); } } return(false); }
private void DisplayFoundIntegration(PotentialIntegrationFit foundIntegration) { m_FoundIntegration = foundIntegration; if (foundIntegration != null) { lblIntegrationFrames.Text = string.Format("{0} frames", foundIntegration.Interval); lblStartingAt.Text = foundIntegration.StartingAtFrame.ToString(); lblCertainty.Text = foundIntegration.CertaintyText; btnAccept.Visible = true; btnReject.Text = "Reject"; } else { lblIntegrationFrames.Text = "Detection Failed"; lblStartingAt.Text = "N/A"; lblCertainty.Text = "N/A"; btnAccept.Visible = false; btnReject.Text = "Close"; } }
public void Run() { if (!m_Arguments.TryGetValue("f", out m_VideoFileName)) { Console.Error.WriteLine("-f must be specified"); return; } if (!File.Exists(m_VideoFileName)) { Console.Error.WriteLine(string.Format("File '{0}' cannot be found.", m_VideoFileName)); return; } if (".pixdet".Equals(Path.GetExtension(m_VideoFileName), StringComparison.InvariantCultureIgnoreCase)) { var pixdet = new PixDetFile(m_VideoFileName, FileAccess.Read); m_ExpectedFit = pixdet.GetStoredIntegrationFit(); m_PixelImageProvider = pixdet; } else { m_ExpectedFit = null; var videoPlayer = new AutomationVideoPlayer(); if (!videoPlayer.OpenVideo(m_VideoFileName)) { Console.Error.WriteLine(string.Format("Cannot open file '{0}'.", m_VideoFileName)); return; } m_PixelImageProvider = videoPlayer; } string sfStr; m_StartFrameNo = 0; if (!m_Arguments.TryGetValue("sf", out sfStr) || !int.TryParse(sfStr, out m_StartFrameNo)) { m_StartFrameNo = m_PixelImageProvider.FirstFrame; } string pixFile; m_RecordPixelFile = false; if (m_Arguments.TryGetValue("pix", out pixFile)) { if (!Path.IsPathRooted(pixFile)) { pixFile = Path.GetFullPath(@".\" + pixFile); } var dirName = Path.GetDirectoryName(pixFile); if (!Directory.Exists(dirName)) { Console.Error.WriteLine(string.Format("Recording directory '{0}' does not exist", dirName)); return; } m_RecordFileName = pixFile; m_RecordPixelFile = true; m_PixDetFile = new PixDetFile(m_RecordFileName, FileAccess.Write); m_PixDetFile.WriteHeader(m_VideoFileName, m_StartFrameNo); } m_Controller = new IntegrationDetectionController(m_PixelImageProvider, m_StartFrameNo); m_Controller.OnPotentialIntegration += OnPotentialIntegration; m_Controller.OnFramePixels += m_Controller_OnFramePixels; m_Controller.RunMeasurements(); m_RunFinished.WaitOne(); }
private PotentialIntegrationFit SearchSmallerFit(PotentialIntegrationFit largestFit) { int integration = largestFit.Interval / 2; List<PotentialIntegrationFit> smallerFitsToCheckFor = new List<PotentialIntegrationFit>(); while (integration > 2) { int potentialStartingFrame = largestFit.StartingAtFrame; while (potentialStartingFrame > m_StartFrameId + integration - 1) potentialStartingFrame -= integration; while (potentialStartingFrame < minX) potentialStartingFrame += integration; smallerFitsToCheckFor.Insert(0, new PotentialIntegrationFit() { Interval = integration, StartingAtFrame = potentialStartingFrame, AboveSigmaRatio = largestFit.AboveSigmaRatio}); integration /= 2; } foreach(PotentialIntegrationFit fit in smallerFitsToCheckFor) { int k = 0; int aboveTwoSigma = 0; double fitVal = 0; do { int frameId = minX + fit.StartingAtFrame - 1 + k*fit.Interval; if (frameId >= 0 && frameId < m_SigmaDict.Count) { double deviation = Math.Abs(m_SigmaDict[frameId] - m_Median); fitVal += deviation; if (deviation > m_Variance * 2) aboveTwoSigma++; } k++; } while (fit.StartingAtFrame + k * fit.Interval < m_SigmaDict.Count); if (k == aboveTwoSigma && k > 2) { fit.CertaintyText = "Average"; fit.Certainty = 3; return fit; } if (k == aboveTwoSigma + 1 && k > 4) { fit.CertaintyText = "Average"; fit.Certainty = 3; return fit; } if (k == aboveTwoSigma + 2 && k > 8) { fit.CertaintyText = "Below Average"; fit.Certainty = 2; return fit; } if (k == aboveTwoSigma + 3 && k > 16) { fit.CertaintyText = "Below Average"; fit.Certainty = 2; return fit; } } largestFit.CertaintyText = largestFit.AboveSigmaRatio > 3.5 ? "Good" : "Average"; largestFit.Certainty = 4; return largestFit; }
private bool IsGuessWithSimilarSigmaAsOtherNonGuesses(PotentialIntegrationFit guess) { int frameToCheck = guess.StartingAtFrame - 1; int cnt = 0; double sigmaSum = 0; while (frameToCheck > 0 && frameToCheck < m_SigmaDict.Count) { sigmaSum += Math.Abs(m_SigmaDict[frameToCheck]); cnt++; frameToCheck += guess.Interval; } double averageSigmaForGuess = sigmaSum / cnt; Dictionary<int, double> sameOrHigherPoints = m_SigmaDict .Where(kvp => (kvp.Key - guess.StartingAtFrame + 1) % guess.Interval != 0 && kvp.Value >= averageSigmaForGuess) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); int numPointsNotInGuessWithSameOrHigherSigmas = sameOrHigherPoints.Count(); if (numPointsNotInGuessWithSameOrHigherSigmas > (1.0 * m_SigmaDict.Count / guess.Interval) - 1) { // Too many other points with similar sigma return true; } return false; }
private void DoMeasurements() { m_SigmaDict = new Dictionary <int, double>(); Rectangle testRect = new Rectangle( (m_ImageProvider.Width / 2) - 16, (m_ImageProvider.Height / 2) - 16, 32, 32); int framesToMeasure = 65; int firstFrame = m_StartFrameId; int lastFrame = Math.Min(m_ImageProvider.LastFrame, m_StartFrameId + framesToMeasure); progressBar1.Minimum = firstFrame; progressBar1.Maximum = lastFrame - 1; progressBar1.Style = ProgressBarStyle.Marquee; int[,] pixels1 = null; int[,] pixels2 = null; for (int i = firstFrame; i < lastFrame - 1; i++) { m_SigmaDict.Add(i, double.NaN); } PotentialIntegrationFit foundIntegration = null; for (int k = 0; k < 4; k++) { for (int i = firstFrame; i < lastFrame - 1; i++) { progressBar1.Value = i; progressBar1.Refresh(); List <AverageCalculator> calcList = new List <AverageCalculator>(); for (int x = 0; x < 32; x++) { for (int y = 0; y < 32; y++) { calcList.Add(new AverageCalculator()); } } if (pixels1 == null) { pixels1 = m_ImageProvider.GetPixelArray(i, testRect); } else { for (int x = 0; x < 32; x++) { for (int y = 0; y < 32; y++) { pixels1[x, y] = pixels2[x, y]; } } } pixels2 = m_ImageProvider.GetPixelArray(i + 1, testRect); double sigmaSum = 0; for (int x = 0; x < 32; x++) { for (int y = 0; y < 32; y++) { int value = pixels1[x, y]; int value2 = pixels2[x, y]; calcList[32 * y + x].AddDataPoint(value); calcList[32 * y + x].AddDataPoint(value2); sigmaSum += Math.Abs(value - value2) / 2.0; } } calcList.ForEach(c => c.Compute()); m_SigmaDict[i] = sigmaSum / 1024; Plot(calcList); PlotSigmas(m_SigmaDict); Refresh(); m_AverageCalculatorsPerFrame.Add(calcList); } foundIntegration = ComputeIntegration(); if (foundIntegration != null) { if (k == 0) { if (foundIntegration.Interval < 32 && foundIntegration.Certainty > 1) { break; } } else if (k == 1) { if (foundIntegration.Interval < 64 && foundIntegration.Certainty > 1) { break; } } else if (k == 2) { if (foundIntegration.Interval < 128 && foundIntegration.Certainty > 1) { break; } } } if (k < 3) { if (k < 2) { framesToMeasure += 65; } else { framesToMeasure += 129; } firstFrame = lastFrame - 1; lastFrame = Math.Min(m_ImageProvider.LastFrame, m_StartFrameId + framesToMeasure); progressBar1.Maximum = lastFrame - 1; int currSize = m_SigmaDict.Count; for (int i = currSize + m_StartFrameId; i < lastFrame - 1; i++) { m_SigmaDict.Add(i, double.NaN); } } } progressBar1.Value = progressBar1.Maximum; progressBar1.Style = ProgressBarStyle.Continuous; progressBar1.Refresh(); pnlResult.Visible = true; pnlResult.BringToFront(); DisplayFoundIntegration(foundIntegration); }
private PotentialIntegrationFit SearchSmallerFit(PotentialIntegrationFit largestFit) { int integration = largestFit.Interval / 2; List <PotentialIntegrationFit> smallerFitsToCheckFor = new List <PotentialIntegrationFit>(); while (integration > 2) { int potentialStartingFrame = largestFit.StartingAtFrame; while (potentialStartingFrame > m_StartFrameId + integration - 1) { potentialStartingFrame -= integration; } while (potentialStartingFrame < minX) { potentialStartingFrame += integration; } smallerFitsToCheckFor.Insert(0, new PotentialIntegrationFit() { Interval = integration, StartingAtFrame = potentialStartingFrame, AboveSigmaRatio = largestFit.AboveSigmaRatio }); integration /= 2; } foreach (PotentialIntegrationFit fit in smallerFitsToCheckFor) { int k = 0; int aboveTwoSigma = 0; double fitVal = 0; do { int frameId = minX + fit.StartingAtFrame - 1 + k * fit.Interval; if (frameId >= 0 && frameId < m_SigmaDict.Count) { double deviation = Math.Abs(m_SigmaDict[frameId] - m_Median); fitVal += deviation; if (deviation > m_Variance * 2) { aboveTwoSigma++; } } k++; }while (fit.StartingAtFrame + k * fit.Interval < m_SigmaDict.Count); if (k == aboveTwoSigma && k > 2) { fit.CertaintyText = "Average"; fit.Certainty = 3; return(fit); } if (k == aboveTwoSigma + 1 && k > 4) { fit.CertaintyText = "Average"; fit.Certainty = 3; return(fit); } if (k == aboveTwoSigma + 2 && k > 8) { fit.CertaintyText = "Below Average"; fit.Certainty = 2; return(fit); } if (k == aboveTwoSigma + 3 && k > 16) { fit.CertaintyText = "Below Average"; fit.Certainty = 2; return(fit); } } largestFit.CertaintyText = largestFit.AboveSigmaRatio > 3.5 ? "Good" : "Average"; largestFit.Certainty = 4; return(largestFit); }
private PotentialIntegrationFit ComputeIntegration(List <int> probeIntervals) { List <PotentialIntegrationFit> guessesMinFrame = new List <PotentialIntegrationFit>(); List <PotentialIntegrationFit> guessesMaxOffset = new List <PotentialIntegrationFit>(); foreach (int interval in probeIntervals) { if (interval == 2) { if (ProbeIntegration2Interval(guessesMinFrame, guessesMaxOffset)) { break; } } else { ProbeIntegrationInterval(interval, guessesMinFrame, guessesMaxOffset); } } List <List <PotentialIntegrationFit> > guessesList = new List <List <PotentialIntegrationFit> >(); guessesList.Add(guessesMaxOffset); guessesList.Add(guessesMinFrame); foreach (List <PotentialIntegrationFit> guesses in guessesList) { if (guesses.Count > 0) { // Sort by increasing interval to check for resonances guesses.Sort((g, h) => g.Interval.CompareTo(h.Interval)); bool isResonance = true; do { int prevInterval = guesses[0].Interval; int firstInterval = guesses[0].Interval; int firstFrame = guesses[0].StartingAtFrame; for (int i = 1; i < guesses.Count; i++) { if (guesses[i].Interval != 2 * prevInterval || Math.Abs(firstFrame - guesses[i].StartingAtFrame) % firstInterval != 0) { isResonance = false; break; } prevInterval = guesses[i].Interval; } if (!isResonance && guesses.Count > 1) { guesses.RemoveAt(0); isResonance = true; } else { break; } }while (true); if (isResonance) { if (IsGuessWithSimilarSigmaAsOtherNonGuesses(guesses[0])) { continue; } // found 2, 4, 8, 16 and 32 OR // found 4, 8, 16 and 32 OR // found 8, 16 and 32 OR // found 16 and 32 PotentialIntegrationFit smallerOrSameFit = SearchSmallerFit(guesses[0]); return(smallerOrSameFit); } else { if (IsGuessWithSimilarSigmaAsOtherNonGuesses(guesses[guesses.Count - 1])) { continue; } guesses.Sort((g, h) => - 1 * g.Certainty.CompareTo(h.Certainty)); guesses[guesses.Count - 1].CertaintyText = "Possible"; guesses[guesses.Count - 1].Certainty = 1; return(guesses[guesses.Count - 1]); } } } return(null); }