private void LocateStarsWithStarRecognition(IAstroImage astroImage) { EnsureComputedRefinedData(); if (m_MinLocateDistance > 8) { if (!LightCurveReductionContext.Instance.WindOrShaking) { //TODO: If the wind flag is not set, then use a 3 frame binned integration to locate the stars on } uint[,] pixels = astroImage.GetPixelsCopy(); List <PotentialStarStruct> peakPixels = new List <PotentialStarStruct>(); AutoDiscoveredStars.Clear(); AutoDiscoveredStars = StarFinder.GetStarsInArea( ref pixels, astroImage.BitPix, astroImage.MaxSignalValue, TangraConfig.PreProcessingFilter.NoFilter, peakPixels, null, (uint)Math.Round(TangraConfig.Settings.Special.LostTrackingMinSignalCoeff * m_MinLocateSignal), TangraConfig.Settings.Special.LostTrackingMinDistance, false, LightCurveReductionContext.Instance.OSDFrame, ReducePeakPixels); Stopwatch sw = new Stopwatch(); sw.Start(); if (m_LocateObjects.Count == 1 && AutoDiscoveredStars.Count == 1) { LocateSingleStarsWithStarRecognition(AutoDiscoveredStars, astroImage); } else if ( m_LocateObjects.Count == 2 && peakPixels.Count > 1) { LocateTwoStarsWithStarRecognition(peakPixels, astroImage, pixels); } else if ( m_LocateObjects.Count > 2 && peakPixels.Count > 1) { List <TrackedObject> goodTrackedObjects = TrackedObjects.Cast <TrackedObject>().ToList().FindAll(t => t.LastKnownGoodPosition != null); if (goodTrackedObjects.Count < 2) { // We don't have at least one good pair. Fail. } else if (goodTrackedObjects.Count >= 2) { goodTrackedObjects.Sort((a, b) => Math.Min(b.LastKnownGoodPosition.XDouble, b.LastKnownGoodPosition.YDouble).CompareTo( Math.Min(a.LastKnownGoodPosition.XDouble, a.LastKnownGoodPosition.YDouble))); Trace.WriteLine(string.Format("StarRecognitionDistanceBasedLocation: Using objects {0} and {1}", goodTrackedObjects[0].TargetNo, goodTrackedObjects[1].TargetNo)); // There is only 1 good pair so fallback to using 2 star recognition LocateTwoStarsWithStarRecognition(peakPixels, astroImage, pixels, goodTrackedObjects[0], goodTrackedObjects[1]); } } sw.Stop(); Trace.WriteLine(string.Format("StarRecognitionDistanceBasedLocation: {0} sec", sw.Elapsed.TotalSeconds.ToString("0.00"))); } }
private void LocateSingleStarsWithStarRecognition(List <PSFFit> stars, IAstroImage astroImage) { TrackedObject trackedObject = TrackedObjects.Cast <TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[0]); trackedObject.ThisFrameX = (float)stars[0].XCenter; trackedObject.ThisFrameY = (float)stars[0].YCenter; trackedObject.PSFFit = stars[0]; trackedObject.ThisFrameCertainty = (float)stars[0].Certainty; trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterStarRecognition); AutoDiscoveredStars.Clear(); if (TrackedObjects.Count > 1 && LocateFirstObjects.Contains(trackedObject)) { // If guiding star then run the locate second objects again ReLocateNonGuidingObjects(astroImage); } }
private void LocateTwoStarsWithStarRecognition( List <CandidatePair> candidates, IAstroImage astroImage, TrackedObject trackedObject1, TrackedObject trackedObject2) { try { if (candidates.Count > 0) { candidates.Sort((c1, c2) => c2.Weight.CompareTo(c1.Weight)); CandidatePair bestPair = candidates[0]; bestPair.Object1.PSFFit = bestPair.Star1; bestPair.Object1.ThisFrameX = (float)bestPair.Star1.XCenter; bestPair.Object1.ThisFrameY = (float)bestPair.Star1.YCenter; bestPair.Object1.ThisFrameCertainty = (float)bestPair.Star1.Certainty; bestPair.Object1.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterStarRecognition); bestPair.Object2.PSFFit = bestPair.Star2; bestPair.Object2.ThisFrameX = (float)bestPair.Star2.XCenter; bestPair.Object2.ThisFrameY = (float)bestPair.Star2.YCenter; bestPair.Object2.ThisFrameCertainty = (float)bestPair.Star2.Certainty; bestPair.Object2.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterStarRecognition); ReLocateNonGuidingObjects(astroImage); } else { trackedObject1.SetIsLocated(false, NotMeasuredReasons.FailedToLocateAfterStarRecognition); trackedObject2.SetIsLocated(false, NotMeasuredReasons.FailedToLocateAfterStarRecognition); } } finally { AutoDiscoveredStars.Clear(); } }
private List <CandidatePair> LocateStarPairsWithStarRecognition(TrackedObject trackedObject1, TrackedObject trackedObject2, List <PotentialStarStruct> stars, uint[,] pixels) { List <CandidatePair> candidates = new List <CandidatePair>(); double minFWHM = (1 - TangraConfig.Settings.Special.LostTrackingFWHMCoeff) * m_AverageFWHM; double maxFWHM = (1 + TangraConfig.Settings.Special.LostTrackingFWHMCoeff) * m_AverageFWHM; if (trackedObject1.TargetNo != trackedObject2.TargetNo && trackedObject1.LastKnownGoodPosition != null && trackedObject2.LastKnownGoodPosition != null) { double deltaX = trackedObject1.LastKnownGoodPosition.X - trackedObject2.LastKnownGoodPosition.X; double deltaY = trackedObject1.LastKnownGoodPosition.Y - trackedObject2.LastKnownGoodPosition.Y; // Looking for two stars with the same distance and similar brighness for (int i = 0; i < stars.Count; i++) { for (int j = 0; j < stars.Count; j++) { if (i == j) { continue; } double deltaXStars = stars[i].X - stars[j].X; double deltaYStars = stars[i].Y - stars[j].Y; if (Math.Abs(deltaX - deltaXStars) < TangraConfig.Settings.Special.LostTrackingPositionToleranceCoeff * PositionTolerance && Math.Abs(deltaY - deltaYStars) < TangraConfig.Settings.Special.LostTrackingPositionToleranceCoeff * PositionTolerance) { // Now compute PSFFits from the pixels PSFFit fit1 = AstroImage.GetPSFFitForPeakPixel(pixels, stars[i], m_MinLocateSignal, minFWHM, maxFWHM); PSFFit fit2 = AstroImage.GetPSFFitForPeakPixel(pixels, stars[j], m_MinLocateSignal, minFWHM, maxFWHM); if (fit1 != null && fit2 != null) { AutoDiscoveredStars.Add(fit1); AutoDiscoveredStars.Add(fit2); deltaXStars = fit1.XCenter - fit2.XCenter; deltaYStars = fit1.YCenter - fit2.YCenter; if (Math.Abs(deltaX - deltaXStars) < PositionTolerance && Math.Abs(deltaY - deltaYStars) < PositionTolerance) { // Compute a certainty and add to the candidates dictionary CandidatePair pair = new CandidatePair(); pair.Star1 = fit1; pair.Star2 = fit2; pair.Object1 = trackedObject1; pair.Object2 = trackedObject2; int[] BRIGTHNESS_MATCH_WEIGTH = new int[] { 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 }; int weight = (trackedObject1.IsGuidingStar ? 2 : 0) + (trackedObject2.IsGuidingStar ? 2 : 0); double d1 = pair.Star1.IMax - pair.Star1.I0; double d2 = pair.Star2.IMax - pair.Star2.I0; d1 = pair.Object1.RefinedOrLastSignalLevel / d1; if (d1 > 1) { d1 = 1 / d1; } int d1i = Math.Min(10, (int)Math.Round((1 - d1) * 10)); weight += BRIGTHNESS_MATCH_WEIGTH[d1i]; d2 = pair.Object2.RefinedOrLastSignalLevel / d2; if (d2 > 1) { d2 = 1 / d2; } int d2i = Math.Min(10, (int)Math.Round((1 - d2) * 10)); weight += BRIGTHNESS_MATCH_WEIGTH[d2i]; double distanceFromLastKnownGoodPosition = ImagePixel.ComputeDistance( pair.Star1.XCenter, pair.Object1.LastKnownGoodPosition.XDouble, pair.Star1.YCenter, pair.Object1.LastKnownGoodPosition.YDouble); int closeToPrevCoeff = LightCurveReductionContext.Instance.WindOrShaking ? 2 : 1; int closeToPrevPosWeighting = 0; if (distanceFromLastKnownGoodPosition < 4 * closeToPrevCoeff) { closeToPrevPosWeighting = 3; } else if (distanceFromLastKnownGoodPosition < 8 * closeToPrevCoeff) { closeToPrevPosWeighting = 2; } else if (distanceFromLastKnownGoodPosition < 16 * closeToPrevCoeff) { closeToPrevPosWeighting = 1; } else if (distanceFromLastKnownGoodPosition > 32 * closeToPrevCoeff) { closeToPrevPosWeighting = -1; } weight += closeToPrevPosWeighting; pair.Weight = weight; candidates.Add(pair); } else { Trace.WriteLine("Pair with close distances has been rejected."); } } } } } } return(candidates); }