public override void BeginMeasurements(IAstroImage astroImage) { base.BeginMeasurements(astroImage); // We consider the first frame of the measurements successfully tracked (after the refining is completed) m_IsTrackedSuccessfully = true; }
public bool InitializeNewTracking(IAstroImage astroImage) { RefinedAverageFWHM = float.NaN; MedianValue = uint.MinValue; m_PastMeasuredRelativeDistances.Clear(); m_PastAverageRelativeDistances.Clear(); for (int i = 0; i < m_TrackedObjects.Count; i++) { ((TrackedObjectLight)m_TrackedObjects[i]).InitializeNewTracking(); var averlist = new List <double>(); var meaList = new List <List <double> >(); for (int j = 0; j < m_TrackedObjects.Count; j++) { meaList.Add(new List <double>()); averlist.Add(double.NaN); } m_PastMeasuredRelativeDistances.Add(i, meaList); m_PastAverageRelativeDistances.Add(i, averlist); } // No preliminary refining used by the AdHockTracker RefiningPercentageWorkLeft = 0; return(true); }
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"))); } }
public void NextFrame(int frameNo, IAstroImage astroImage) { m_NativeTrackedObject.ForEach(x => x.NextFrame()); uint[] pixels = astroImage.GetPixelmapPixels(); IsTrackedSuccessfully = NativeTracking.TrackNextFrame(frameNo, pixels, m_NativeTrackedObject); }
private void LocateTwoStarsWithStarRecognition( List <PotentialStarStruct> stars, IAstroImage astroImage, uint[,] pixels, TrackedObject trackedObject1, TrackedObject trackedObject2) { List <CandidatePair> candidates = LocateStarPairsWithStarRecognition(trackedObject1, trackedObject2, stars, pixels); LocateTwoStarsWithStarRecognition(candidates, astroImage, trackedObject1, trackedObject2); }
public override void NextFrame(int frameNo, IAstroImage astroImage) { // All objects are 'fixed' so always return the same positions foreach (TrackedObject trackedObject in TrackedObjects) { trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully); trackedObject.ThisFrameX = trackedObject.OriginalObject.ApertureStartingX; trackedObject.ThisFrameY = trackedObject.OriginalObject.ApertureStartingY; trackedObject.ThisFrameCertainty = trackedObject.OriginalObject.Gaussian != null ? (float)trackedObject.OriginalObject.Gaussian.Certainty : 0; } }
public override bool InitializeNewTracking(IAstroImage astroImage) { if (base.InitializeNewTracking(astroImage)) { m_RefiningFramesLeft = TangraConfig.Settings.Tracking.RefiningFrames; return true; } else return false; }
public bool InitializeNewTracking(IAstroImage astroImage) { NativeTracking.InitialiseNewTracking(); RefinedAverageFWHM = float.NaN; MedianValue = uint.MinValue; m_NativeTrackedObject.ForEach(x => x.InitializeNewTracking()); return(true); }
public override bool InitializeNewTracking(IAstroImage astroImage) { if (base.InitializeNewTracking(astroImage)) { m_RefiningFramesLeft = TangraConfig.Settings.Tracking.RefiningFrames; return(true); } else { return(false); } }
public bool InitializeNewTracking(IAstroImage astroImage, TrackedAstrometricObjectConfig objectToTrack) { m_ObjectToTrack = objectToTrack; TrackedObject = new TrackedAstrometricObject() { LastKnownX = m_ObjectToTrack.StartingX, LastKnownY = m_ObjectToTrack.StartingY, RAHours = m_ObjectToTrack.RADeg / 15.0, DEDeg = m_ObjectToTrack.DEDeg }; return(true); }
public bool InitializeNewTracking(IAstroImage astroImage, TrackedAstrometricObjectConfig objectToTrack) { m_ObjectToTrack = objectToTrack; TrackedObject = new TrackedAstrometricObject() { LastKnownX = m_ObjectToTrack.StartingX, LastKnownY = m_ObjectToTrack.StartingY, RAHours = m_ObjectToTrack.RADeg / 15.0, DEDeg = m_ObjectToTrack.DEDeg }; return true; }
public void NextFrame(int frameNo, IAstroImage astroImage) { m_FrameNo = frameNo; TrackSingleStar(frameNo, astroImage); m_IsTrackedSuccessfully = TrackedStar.IsLocated; if (TrackedStar.IsLocated) { TrackedStar.LastKnownGoodPosition = new ImagePixel(TrackedStar.Center); TrackedStar.LastKnownGoodPsfCertainty = TrackedStar.PSFFit != null ? TrackedStar.PSFFit.Certainty : 0; } }
public bool InitializeNewTracking(IAstroImage astroImage, TrackedAstrometricObjectConfig objectToTrack) { m_ObjectToTrack = objectToTrack; TrackedObject = new TrackedAstrometricObject() { LastKnownX = m_ObjectToTrack.StartingX, LastKnownY = m_ObjectToTrack.StartingY, RAHours = m_ObjectToTrack.RADeg / 15.0, DEDeg = m_ObjectToTrack.DEDeg }; m_RepeatedIntergationPositions = m_MeasurementContext.IntegratedFramesCount / m_MeasurementContext.FrameInterval; if (m_RepeatedIntergationPositions == 0) m_RepeatedIntergationPositions = 1; return true; }
public void NextFrame(int frameNo, IAstroImage astroImage, IStarMap starMap, LeastSquareFittedAstrometry astrometricFit) { IsTrackedSuccessfully = false; ImagePixel centroid = AstrometryContext.Current.StarMap.GetCentroid( (int)TrackedObject.LastKnownX, (int)TrackedObject.LastKnownY, CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius); if (centroid != null) { PSFFit psfFit; AstrometryContext.Current.StarMap.GetPSFFit( centroid.X, centroid.Y, PSFFittingMethod.NonLinearFit, out psfFit); if (psfFit != null) { double ra, de; astrometricFit.GetRADEFromImageCoords(psfFit.XCenter, psfFit.YCenter, out ra, out de); double maxPosDiffArcSec = astrometricFit.GetDistanceInArcSec(astrometricFit.Image.CenterXImage, astrometricFit.Image.CenterYImage, astrometricFit.Image.CenterXImage + CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius, astrometricFit.Image.CenterYImage); if (!double.IsNaN(TrackedObject.RAHours)) { double posDif = 3600 * AngleUtility.Elongation(15 * TrackedObject.RAHours, TrackedObject.DEDeg, ra, de); if (posDif > maxPosDiffArcSec) { // NOTE: Not a valid measurement Trace.WriteLine(string.Format("The target position is too far from the last measured position", posDif)); return; } } TrackedObject.RAHours = ra / 15.0; TrackedObject.DEDeg = de; TrackedObject.LastKnownX = psfFit.XCenter; TrackedObject.LastKnownY = psfFit.YCenter; TrackedObject.PSFFit = psfFit; IsTrackedSuccessfully = true; } } }
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); } }
public bool InitializeNewTracking(IAstroImage astroImage, TrackedAstrometricObjectConfig objectToTrack) { m_ObjectToTrack = objectToTrack; TrackedObject = new TrackedAstrometricObject() { LastKnownX = m_ObjectToTrack.StartingX, LastKnownY = m_ObjectToTrack.StartingY, RAHours = m_ObjectToTrack.RADeg / 15.0, DEDeg = m_ObjectToTrack.DEDeg }; m_RepeatedIntergationPositions = m_MeasurementContext.IntegratedFramesCount / m_MeasurementContext.FrameInterval; if (m_RepeatedIntergationPositions == 0) { m_RepeatedIntergationPositions = 1; } m_LastMovementPixels = 0; return(true); }
private void TrackSingleStar(int frameNo, IAstroImage astroImage) { TrackedStar.NewFrame(); float expectedX; float expectedY; GetExpectedXY(out expectedX, out expectedY); uint[,] pixels = astroImage.GetPixelsArea((int)expectedX, (int)expectedY, FIT_AREA); // There is only one object in the area, just do a wide fit followed by a fit with the selected matrix size PSFFit gaussian = new PSFFit((int)expectedX, (int)expectedY); gaussian.Fit(pixels, FIT_AREA); IImagePixel firstCenter = new ImagePixel((int)gaussian.XCenter, (int)gaussian.YCenter); pixels = astroImage.GetPixelsArea(firstCenter.X, firstCenter.Y, FIT_AREA); gaussian = new PSFFit(firstCenter.X, firstCenter.Y); gaussian.Fit(pixels, TrackedStar.PsfFitMatrixSize); if (gaussian.IsSolved) { TrackedStar.PSFFit = gaussian; TrackedStar.ThisFrameX = (float)gaussian.XCenter; TrackedStar.ThisFrameY = (float)gaussian.YCenter; TrackedStar.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0); TrackedStar.ThisFrameCertainty = (float)gaussian.Certainty; TrackedStar.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully); } else { TrackedStar.ThisFrameX = expectedX; TrackedStar.ThisFrameY = expectedY; TrackedStar.ThisFrameCertainty = (float)gaussian.Certainty; Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve second PSF", m_FrameNo, TrackedStar.TargetNo)); TrackedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed); } }
public override void NextFrame(int frameNo, IAstroImage astroImage) { m_FrameNo = frameNo; if (m_Refining) { // For refining use the base class base.NextFrame(frameNo, astroImage); } else { // And for measuring use TrackSingleStar(frameNo, astroImage); } if (m_RefiningFramesLeft > 0) { if (OccultedStar.IsLocated) { m_RefiningFramesLeft--; } } else { m_IsTrackedSuccessfully = OccultedStar.IsLocated; } if (OccultedStar.IsLocated && !m_NotCertain) { AddPreviousPosition(); } if (OccultedStar.IsLocated) { OccultedStar.LastKnownGoodPosition = new ImagePixel(OccultedStar.Center); OccultedStar.LastKnownGoodPsfCertainty = OccultedStar.PSFFit != null ? OccultedStar.PSFFit.Certainty : 0; } }
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 void LocateSingleNonGuidingObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos) { LocateNonGuidingObject(astroImage, trackedObject, newStaringPos); }
public override void NextFrame(int frameNo, IAstroImage astroImage) { base.NextFrame(frameNo, astroImage); #region run the full star recognition recovery if enabled if (TangraConfig.Settings.Tracking.RecoverFromLostTracking && m_RefiningFramesLeft <= 0) { bool notAllStarsLocated = TrackedObjects.Exists(o => !o.IsLocated); bool notAllLocateFirstStarsLocated = LocateFirstObjects.Exists(o => !o.IsLocated); if (notAllLocateFirstStarsLocated && LocateFirstObjects.Count > 1) LocateStarsWithStarRecognition(astroImage); // TODO: Use the notAllStarsLocated to troubleshoot the pattern recognition alignment } #endregion bool allGuidingStarsLocated = true; foreach (TrackedObject trackedObject in LocateFirstObjects) { if (!trackedObject.IsLocated && !trackedObject.IsOffScreen) allGuidingStarsLocated = false; } if (m_RefiningFramesLeft > 0) { if (allGuidingStarsLocated) m_RefiningFramesLeft--; } else { m_IsTrackedSuccessfully = LocateFirstObjects.Count > 0 ? allGuidingStarsLocated : OccultedStar.IsLocated; } if (!m_Refining && (LocateFirstObjects.Count > 0 && allGuidingStarsLocated) && (LightCurveReductionContext.Instance.FieldRotation || LightCurveReductionContext.Instance.LightCurveReductionType == LightCurveReductionType.MutualEvent)) { for (int i = 0; i < TrackedObjects.Count; i++) { TrackedObject obj1 = TrackedObjects[i] as TrackedObject; for (int j = 0; j < TrackedObjects.Count; j++) { if (i == j) continue; TrackedObject obj2 = TrackedObjects[j] as TrackedObject; long pairId = (((long)obj1.TargetNo) << 32) + (long)obj2.TargetNo; double oldDistance = m_RefinedDistances[pairId]; double newDistance = ImagePixel.ComputeDistance( obj1.Center.XDouble, obj2.Center.XDouble, obj1.Center.YDouble, obj2.Center.YDouble); m_RefinedDistances[pairId] = (oldDistance + newDistance) / 2.0; LocationVector vector = obj1.OtherGuidingStarsLocationVectors[obj2.TargetNo]; vector.DeltaXToAdd = (vector.DeltaXToAdd + obj2.Center.XDouble - obj1.Center.XDouble) / 2; vector.DeltaYToAdd = (vector.DeltaYToAdd + obj2.Center.YDouble - obj1.Center.YDouble) / 2; } } } if (!m_IsTrackedSuccessfully) { // If the tracking has failed, then some objects may be offscreen and have NaN position // So inherit the IsOffScreen flag from the previous position foreach (TrackedObject obj in TrackedObjects) if (m_IsOffScreenPrev[obj.TargetNo] && double.IsNaN(obj.Center.XDouble)) obj.SetIsLocated(false, NotMeasuredReasons.ObjectExpectedPositionIsOffScreen); } else { foreach (TrackedObject obj in TrackedObjects) m_IsOffScreenPrev[obj.TargetNo] = obj.IsOffScreen; } }
public override void NextFrame(int frameNo, IAstroImage astroImage) { IsTrackedSuccessfully = false; // For each of the non manualy positioned Tracked objects do a PSF fit in the area of its previous location for (int i = 0; i < m_TrackedObjectGroups.Count; i++) { TrackedObjectGroup objectGroup = m_TrackedObjectGroups[i]; objectGroup.NextFrame(); if (objectGroup.TrackLater) { // Group position will be determined after the rest of the stars are found } else { if (objectGroup.IsSingleObject) { TrackedObjectLight trackedObject = (TrackedObjectLight)objectGroup.SingleObject; uint[,] pixels = astroImage.GetPixelsArea(objectGroup.SingleObjectLastCenter.X, objectGroup.SingleObjectLastCenter.Y, 17); var fit = new PSFFit(objectGroup.SingleObjectLastCenter.X, objectGroup.SingleObjectLastCenter.Y); fit.FittingMethod = PSFFittingMethod.NonLinearFit; fit.Fit(pixels); if (fit.IsSolved) { if (fit.Certainty < GUIDING_STAR_MIN_CERTAINTY) { trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall); } else if (fit.FWHM < STELLAR_OBJECT_MIN_FWHM || fit.FWHM > STELLAR_OBJECT_MAX_FWHM) { trackedObject.SetIsTracked(false, NotMeasuredReasons.FWHMOutOfRange); } else if (TangraConfig.Settings.Tracking.CheckElongation && fit.ElongationPercentage > STELLAR_OBJECT_MAX_ELONGATION) { trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectTooElongated); } else { trackedObject.SetTrackedObjectMatch(fit); trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully); } } } else { string dbg = ""; int areaCenterX = (objectGroup.LastCenterObject1.X + objectGroup.LastCenterObject2.X) / 2; int areaCenterY = (objectGroup.LastCenterObject1.Y + objectGroup.LastCenterObject2.Y) / 2; uint[,] pixels = astroImage.GetPixelsArea(areaCenterX, areaCenterY, 35); var doubleFit = new DoublePSFFit(areaCenterX, areaCenterY); int x1 = objectGroup.LastCenterObject1.X - areaCenterX + 17; int y1 = objectGroup.LastCenterObject1.Y - areaCenterY + 17; int x2 = objectGroup.LastCenterObject2.X - areaCenterX + 17; int y2 = objectGroup.LastCenterObject2.Y - areaCenterY + 17; if (TangraConfig.Settings.Photometry.PsfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel) { doubleFit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel; } doubleFit.Fit(pixels, x1, y1, x2, y2); if (doubleFit.IsSolved) { PSFFit fit1 = doubleFit.GetGaussian1(); PSFFit fit2 = doubleFit.GetGaussian2(); TrackedObjectLight trackedObject1; TrackedObjectLight trackedObject2; bool groupIdentified = objectGroup.IdentifyObjects(fit1, fit2, GUIDING_STAR_MIN_CERTAINTY, out trackedObject1, out trackedObject2); if (!groupIdentified) { dbg += "Ni-"; objectGroup.SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed); //Bitmap bmp = new Bitmap(100, 200); //using (Graphics g = Graphics.FromImage(bmp)) //{ // doubleFit.DrawInternalPoints(g, new Rectangle(0, 0, 100, 200), 5, 5, Brushes.Lime, Brushes.Yellow, 8); // g.Save(); //} //bmp.Save(@"D:\Hristo\mutual_double_fit.bmp"); m_FailedGroupFits++; } else { PSFFit[] fits = new PSFFit[] { fit1, fit2 }; TrackedObjectLight[] trackedObjects = new TrackedObjectLight[] { trackedObject1, trackedObject2 }; int tooSmallCertainties = 0; int errors = 0; for (int j = 0; j < 2; j++) { PSFFit fit = fits[j]; TrackedObjectLight trackedObject = trackedObjects[j]; if (fit.Certainty < GUIDING_STAR_MIN_CERTAINTY) { tooSmallCertainties++; trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully); dbg += "TsGs-"; } else if (fit.FWHM < STELLAR_OBJECT_MIN_FWHM || fit.FWHM > STELLAR_OBJECT_MAX_FWHM) { trackedObject.SetIsTracked(false, NotMeasuredReasons.FWHMOutOfRange); dbg += "Fw-"; errors++; } else if (TangraConfig.Settings.Tracking.CheckElongation && fit.ElongationPercentage > STELLAR_OBJECT_MAX_ELONGATION) { trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectTooElongated); dbg += "Elo-"; errors++; } else { trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully); dbg += "Ts-"; } } if (tooSmallCertainties == 2) { trackedObjects[0].SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall); trackedObjects[1].SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall); errors++; m_FailedGroupFits++; dbg += "Uncer-"; } if (errors == 0) { if (objectGroup.CheckIdentifiedObjects(fits[0].XCenter, fits[1].XCenter, fits[0].YCenter, fits[1].YCenter)) { trackedObjects[0].SetTrackedObjectMatch(fits[0]); trackedObjects[1].SetTrackedObjectMatch(fits[1]); m_FailedGroupFits = 0; dbg += "Id-"; double dist = ImagePixel.ComputeDistance(fits[0].XCenter, fits[1].XCenter, fits[0].YCenter, fits[1].YCenter); if (dist < 2) { Trace.WriteLine("TOO CLOSE"); } if (dist > 16) { Trace.WriteLine("TOO FAR"); } } else { dbg += "NoId-"; } } } } else { dbg += "NoSlv-"; } objectGroup.ValidatePosition(); Trace.WriteLine(dbg); } } } bool atLeastOneGroupLocated = false; for (int i = 0; i < m_TrackedObjectGroups.Count; i++) { TrackedObjectGroup trackedGroup = m_TrackedObjectGroups[i]; if (!trackedGroup.IsSingleObject && trackedGroup.LastCenterObject1 != null && trackedGroup.LastCenterObject2 != null) { Trace.WriteLine(string.Format("({0}, {1}, {2}) ({3},{4},{5}) [{6},{7}]", trackedGroup.LastCenterObject1.XDouble, trackedGroup.LastCenterObject1.YDouble, trackedGroup.LastCenterObject1.Brightness, trackedGroup.LastCenterObject2.XDouble, trackedGroup.LastCenterObject2.YDouble, trackedGroup.LastCenterObject2.Brightness, trackedGroup.LastCenterObject1.XDouble - trackedGroup.LastCenterObject2.XDouble, trackedGroup.LastCenterObject1.YDouble - trackedGroup.LastCenterObject2.YDouble)); } bool containsFullyDisappearingTarget = trackedGroup.ContainsOcultedStar && m_IsFullDisappearance; if (!containsFullyDisappearingTarget && trackedGroup.IsLocated) { atLeastOneGroupLocated = true; } if (!containsFullyDisappearingTarget) { continue; } int numReferences = 0; double x_double; double y_double; if (trackedGroup.IsSingleObject && m_IsFullDisappearance) { // This is the case for single fully disappearing targets double totalX = 0; double totalY = 0; numReferences = 0; for (int j = 0; j < m_TrackedObjectGroups.Count; j++) { TrackedObjectGroup referenceGroup = (TrackedObjectGroup)m_TrackedObjectGroups[j]; if (referenceGroup.IsLocated) { totalX += (trackedGroup.BrigherOriginalObject.ApertureStartingX - referenceGroup.BrigherOriginalObject.ApertureStartingX) + referenceGroup.BrigherObjectLastCenter.XDouble; totalY += (trackedGroup.BrigherOriginalObject.ApertureStartingY - referenceGroup.BrigherOriginalObject.ApertureStartingY) + referenceGroup.BrigherObjectLastCenter.YDouble; numReferences++; atLeastOneGroupLocated = true; } } x_double = totalX / numReferences; y_double = totalY / numReferences; } else { // The fully disappearing target is in a group. The other target would have been located. We use the last known position of the other targets numReferences = 1; x_double = trackedGroup.NonOccultedObjectLastCenter.XDouble; y_double = trackedGroup.NonOccultedObjectLastCenter.YDouble; } if (numReferences == 0) { trackedGroup.SetIsTracked(false, NotMeasuredReasons.FitSuspectAsNoGuidingStarsAreLocated); } else { int x = (int)(Math.Round(x_double)); int y = (int)(Math.Round(y_double)); uint[,] pixels = astroImage.GetPixelsArea(x, y, 35); if (trackedGroup.IsSingleObject) { PSFFit fit = new PSFFit(x, y); fit.Fit(pixels); if (fit.IsSolved && fit.Certainty > STELLAR_OBJECT_MIN_CERTAINTY) { trackedGroup.SingleObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully); trackedGroup.SingleObject.SetTrackedObjectMatch(fit); } else if (m_IsFullDisappearance) { trackedGroup.SingleObject.SetIsTracked(false, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound); } else { trackedGroup.SingleObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall); } } else { string dbg = ""; DoublePSFFit doubleFit = new DoublePSFFit(x, y); int x1 = trackedGroup.LastCenterObject1.X - x + 17; int y1 = trackedGroup.LastCenterObject1.Y - y + 17; int x2 = trackedGroup.LastCenterObject2.X - x + 17; int y2 = trackedGroup.LastCenterObject2.Y - y + 17; if (TangraConfig.Settings.Photometry.PsfFittingMethod == TangraConfig.PsfFittingMethod.LinearFitOfAveragedModel) { doubleFit.FittingMethod = PSFFittingMethod.LinearFitOfAveragedModel; } doubleFit.Fit(pixels, x1, y1, x2, y2); if (doubleFit.IsSolved) { PSFFit fit1 = doubleFit.GetGaussian1(); PSFFit fit2 = doubleFit.GetGaussian2(); IImagePixel center1 = null; IImagePixel center2 = null; TrackedObjectLight trackedObject1; TrackedObjectLight trackedObject2; bool resortToBrightness = false; bool groupIdentified = trackedGroup.IdentifyObjects(fit1, fit2, GUIDING_STAR_MIN_CERTAINTY, out trackedObject1, out trackedObject2); if (!groupIdentified && m_IsFullDisappearance) { dbg += "ReBr::"; groupIdentified = trackedGroup.IdentifyBrightObject(fit1, fit2, STELLAR_OBJECT_MIN_CERTAINTY, out trackedObject1, out trackedObject2, out center1, out center2); resortToBrightness = true; } if (!groupIdentified) { trackedGroup.SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed); dbg += "PsF::"; } else { PSFFit[] fits = new PSFFit[] { fit1, fit2 }; IImagePixel[] centers = new IImagePixel[] { center1, center2 }; TrackedObjectLight[] trackedObjects = new TrackedObjectLight[] { trackedObject1, trackedObject2 }; bool objectCheckSuccessful = resortToBrightness ? trackedGroup.CheckIdentifiedObjects(center1.XDouble, center2.XDouble, center1.YDouble, center2.YDouble) : trackedGroup.CheckIdentifiedObjects(fits[0].XCenter, fits[1].XCenter, fits[0].YCenter, fits[1].YCenter); if (objectCheckSuccessful) { dbg += "ChS::"; bool atLeastOneOK = (fit1.IsSolved && fit1.Certainty > GUIDING_STAR_MIN_CERTAINTY) || (fit2.IsSolved && fit2.Certainty > GUIDING_STAR_MIN_CERTAINTY); double dist = ImagePixel.ComputeDistance(fit1.XCenter, fit2.XCenter, fit1.YCenter, fit2.YCenter); if (!atLeastOneOK || ((dist < 2 || dist > 16) && !resortToBrightness)) { trackedGroup.SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed); } int cntOk = 0; for (int j = 0; j < 2; j++) { PSFFit fit = fits[j]; IImagePixel center = centers[j]; TrackedObjectLight trackedObject = trackedObjects[j]; if (fit.IsSolved && fit.Certainty > STELLAR_OBJECT_MIN_CERTAINTY) { if (resortToBrightness && trackedObject.IsOccultedStar) { trackedObject.SetIsTracked(true, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound, center, fit.Certainty); dbg += "OccDi::"; } else { trackedObject.SetTrackedObjectMatch(fit); trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully); dbg += "TrSuc::"; } cntOk++; } else if (m_IsFullDisappearance && trackedObject.IsOccultedStar) { trackedObject.SetIsTracked(false, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound, resortToBrightness ? center : null, 1); dbg += "BadCerSuc::"; } else { trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall, resortToBrightness ? center : null, resortToBrightness ? fit.Certainty : (double?)null); dbg += "BadCerNOSuc::"; } } if (cntOk == 2) { m_FailedGroupFits = 0; } } else { trackedObjects[0].SetIsTracked(false, NotMeasuredReasons.FailedToLocateAfterDistanceCheck); trackedObjects[1].SetIsTracked(false, NotMeasuredReasons.FailedToLocateAfterDistanceCheck); m_FailedGroupFits++; dbg += "ChU::"; } } } else { m_FailedGroupFits++; dbg += "NoFi::"; } trackedGroup.ValidatePosition(); Trace.WriteLine(dbg); } } } IsTrackedSuccessfully = atLeastOneGroupLocated; if (IsTrackedSuccessfully) { RefinedAverageFWHM = m_TrackedObjects.Cast <TrackedObjectLight>().Average(x => x.RefinedFWHM); } if (m_FailedGroupFits > 10) { Trace.WriteLine("ERR~10+"); } }
private void LocateNonGuidingObject(IAstroImage astroImage, TrackedObject trackedObject) { IImagePixel prevPos = trackedObject.HasRefinedPositions ? trackedObject.LastRefinedPosition : trackedObject.LastKnownGoodPosition != null ? trackedObject.LastKnownGoodPosition : trackedObject.OriginalObject.AsImagePixel; IImagePixel newStaringPos = m_AllGuidingStarsFailed ? prevPos : new ImagePixel(prevPos.Brightness, prevPos.XDouble + m_LastFrameDeltaX, prevPos.YDouble + m_LastFrameDeltaY); if (trackedObject.OriginalObject.IsWeakSignalObject) { LocateNonGuidingObject(astroImage, trackedObject, newStaringPos); } else if (trackedObject.OriginalObject.IsFixedAperture) { LocateFixedApertureObject(astroImage, trackedObject, newStaringPos); } else if ( trackedObject.OriginalObject.TrackingType == TrackingType.OccultedStar && LightCurveReductionContext.Instance.FullDisappearance && !trackedObject.OriginalObject.IsCloseToOtherStars) { LocateFullDisappearingObject(astroImage, trackedObject, newStaringPos); } else { LocateSingleNonGuidingObject(astroImage, trackedObject, newStaringPos); } }
private void LocateFixedApertureObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos) { double averageX = 0; double averageY = 0; GetAverageObjectPositionsFromGuidingStars(trackedObject, newStaringPos, out averageX, out averageY); trackedObject.SetIsLocated(true, NotMeasuredReasons.FixedObject); trackedObject.ThisFrameX = (float)averageX; trackedObject.ThisFrameY = (float)averageY; trackedObject.PSFFit = null; trackedObject.ThisSignalLevel = float.NaN; trackedObject.ThisFrameCertainty = float.NaN; }
protected void ReLocateNonGuidingObjects(IAstroImage astroImage) { CheckAndCorrectGuidingStarPositions(astroImage, false); ComputeFrameShift(); foreach (TrackedObject trackedObject in LocateSecondObjects) LocateNonGuidingObject(astroImage, trackedObject); }
public virtual void NextFrame(int frameNo, IAstroImage astroImage) { m_FrameNo = frameNo; if (!m_Refining) { int numLocatedGuidingStars = LocateFirstObjects.Sum(t => t.IsLocated ? 1 : 0); // TODO: Think of chaning this to rely on at least one guiding star being located // rather than all guiding stars being located successfully ! if (numLocatedGuidingStars == LocateFirstObjects.Count) { foreach (TrackedObject trackedObject in TrackedObjects) { trackedObject.LastKnownGoodFrameId = frameNo - 1; trackedObject.LastKnownGoodPosition = new ImagePixel((int)trackedObject.ThisSignalLevel, trackedObject.ThisFrameX, trackedObject.ThisFrameY); trackedObject.LastKnownGoodPsfCertainty = trackedObject.ThisFrameCertainty; } } } m_AllGuidingStarsFailed = false; foreach (TrackedObject trackedObject in TrackedObjects) trackedObject.NewFrame(); // Locate all guiding objects based on their previous positions foreach (TrackedObject trackedObject in LocateFirstObjects) LocateObjectAsGuidingStar(astroImage, trackedObject, false); if (m_Refining) { if (m_MedianValueStart == uint.MaxValue) m_MedianValueStart = astroImage.MedianNoise; UpdateReferencePosition(); } else { // Based on the refined distances, brightness and allowed tolerance // confirm the positions and fix some of them if needed CheckAndCorrectGuidingStarPositions(astroImage, true); ComputeFrameShift(); } foreach (TrackedObject trackedObject in LocateSecondObjects) LocateNonGuidingObject(astroImage, trackedObject); if (m_AllGuidingStarsFailed) LocateSecondObjects.ForEach((o) => o.SetIsLocated(false, NotMeasuredReasons.FitSuspectAsNoGuidingStarsAreLocated)); }
private void LocateObjectAsGuidingStar(IAstroImage astroImage, TrackedObject trackedObject, bool useLowPassFilter) { trackedObject.SetIsLocated(false, NotMeasuredReasons.UnknownReason); int bestMaxFixAreaSize = !float.IsNaN(trackedObject.OriginalObject.RefinedFWHM) ? (int)(6 * trackedObject.OriginalObject.RefinedFWHM) : 17; if (bestMaxFixAreaSize > 17) bestMaxFixAreaSize = 35; // We only support FSP Fitting of 17 or 35 square matrixes if (bestMaxFixAreaSize < 17) bestMaxFixAreaSize = 17; // Try all fits from 5 to 15. Find the one with the highest peak, then do a fit around this area with the configured psf matrix size uint[,] pixels; if (useLowPassFilter) { pixels = astroImage.GetPixelsArea((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, bestMaxFixAreaSize + 2); pixels = EnhanceByteAreaForSearch(pixels); } else { pixels = astroImage.GetPixelsArea((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, bestMaxFixAreaSize); } // There is only one object in the area, just do a wide fit followed by a fit with the selected matrix size PSFFit gaussian = new PSFFit((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY); gaussian.Fit(pixels, bestMaxFixAreaSize); if (gaussian.Certainty < TangraConfig.Settings.Special.MinGuidingStarCertainty && (trackedObject.LastKnownGoodPsfCertainty > TangraConfig.Settings.Special.GoodGuidingStarCertainty || LightCurveReductionContext.Instance.HighFlickeringOrLargeStars)) { // We have a problem. Try to find the star in the area using other means IImagePixel centroid = astroImage.GetCentroid((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, bestMaxFixAreaSize, m_MedianValue); if (centroid != null) { double maxAllowedDistance = !float.IsNaN(trackedObject.OriginalObject.RefinedFWHM) ? 2 * trackedObject.OriginalObject.RefinedFWHM : 3 * TangraConfig.Settings.Special.LostTrackingMinDistance; if (LightCurveReductionContext.Instance.WindOrShaking) maxAllowedDistance *= 1.5; if (centroid.DistanceTo(new ImagePixel((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY)) < maxAllowedDistance) { pixels = astroImage.GetPixelsArea(centroid.X, centroid.Y, bestMaxFixAreaSize); gaussian = new PSFFit(centroid.X, centroid.Y); gaussian.Fit(pixels, bestMaxFixAreaSize); } } } IImagePixel firstCenter = gaussian.IsSolved ? new ImagePixel(gaussian.Brightness, (int)gaussian.XCenter, (int)gaussian.YCenter) : astroImage.GetCentroid((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, bestMaxFixAreaSize, m_MedianValue); if (!gaussian.IsSolved || gaussian.Certainty < TangraConfig.Settings.Special.MinGuidingStarCertainty) firstCenter = null; if (firstCenter != null) { // Do a second fit pixels = astroImage.GetPixelsArea(firstCenter.X, firstCenter.Y, bestMaxFixAreaSize); int secondFitAreaSize = Math.Max(trackedObject.PsfFitMatrixSize, (int)Math.Round(gaussian.FWHM * 2.5)); if (secondFitAreaSize % 2 == 0) secondFitAreaSize++; secondFitAreaSize = Math.Min(17, secondFitAreaSize); gaussian = new PSFFit(firstCenter.X, firstCenter.Y); gaussian.Fit(pixels, secondFitAreaSize); if (gaussian.IsSolved) { double signal = gaussian.IMax - gaussian.I0; if (signal < 0) signal = 0; double brightnessFluctoation = signal > trackedObject.RefinedOrLastSignalLevel ? signal / trackedObject.RefinedOrLastSignalLevel : trackedObject.RefinedOrLastSignalLevel / signal; //double brightnessFluctoation = (trackedObject.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / trackedObject.RefinedOrLastSignalLevel; double fluckDiff = Math.Abs(brightnessFluctoation)/m_AllowedSignalFluctoation; //if (trackedObject.LastSignalLevel != 0 && // fluckDiff > 1 && // LightCurveReductionContext.Instance.WindOrShaking) //{ // // If the located object is not similar brightness as expected, then search for our object in a wider area // try // { // IImagePixel centroid = astroImage.GetCentroid((int)trackedObject.LastFrameX, (int)trackedObject.LastFrameY, 14, m_MedianValueStart); // pixels = astroImage.GetPixelsArea(centroid.X, centroid.Y, 17); // gaussian = new PSFFit(centroid.X, centroid.Y); // gaussian.Fit(pixels, trackedObject.PsfFitMatrixSize); // if (gaussian.IsSolved) // { // signal = gaussian.IMax - gaussian.I0; if (signal < 0) signal = 0; // brightnessFluctoation = signal > trackedObject.RefinedOrLastSignalLevel // ? signal / trackedObject.RefinedOrLastSignalLevel // : trackedObject.RefinedOrLastSignalLevel / signal; // //brightnessFluctoation = (trackedObject.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / trackedObject.RefinedOrLastSignalLevel; // fluckDiff = Math.Abs(brightnessFluctoation) / m_AllowedSignalFluctoation; // } // else // { // Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [Guiding.WindOrShaking]. Cannot solve third PSF", m_FrameNo, trackedObject.TargetNo)); // } // } // catch { } //} if (!trackedObject.HasRefinedPositions || fluckDiff < 1 || LightCurveReductionContext.Instance.HighFlickeringOrLargeStars) { trackedObject.PSFFit = gaussian; trackedObject.ThisFrameX = (float)gaussian.XCenter; trackedObject.ThisFrameY = (float)gaussian.YCenter; trackedObject.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0); trackedObject.ThisFrameCertainty = (float) gaussian.Certainty; trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully); if (m_Refining) { trackedObject.RegisterRefinedPosition(trackedObject.Center, trackedObject.ThisSignalLevel, gaussian.FWHM); } } else { if (useLowPassFilter) { // Only show the warning the second time around Trace.WriteLine( string.Format( "Frame {0}: Guiding target #{1} is suspect because the brightness fluctuation is too big: {2}", m_FrameNo, trackedObject.TargetNo, fluckDiff.ToString("0.00"))); trackedObject.SetIsLocated(false, NotMeasuredReasons.GuidingStarBrightnessFluctoationTooHigh); } } } else { Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [Guiding]. Cannot solve second PSF", m_FrameNo, trackedObject.TargetNo)); trackedObject.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed); } } else { Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [Guiding]. Cannot solve first PSF", m_FrameNo, trackedObject.TargetNo)); trackedObject.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed); } if (!trackedObject.IsLocated) { // Could not locate the object this time trackedObject.ThisSignalLevel = trackedObject.LastSignalLevel; if (m_Refining) { // Use the last known coordinates for refining frames trackedObject.ThisFrameX = trackedObject.LastFrameX; trackedObject.ThisFrameY = trackedObject.LastFrameY; trackedObject.ThisSignalLevel = trackedObject.LastSignalLevel; trackedObject.ThisFrameCertainty = (float)trackedObject.LastKnownGoodPsfCertainty; trackedObject.RegisterRefinedPosition(ImagePixel.Unspecified, float.NaN, double.NaN); } else { // Make the position invalid, which will cause the distance check for this object to fail // which will trigger another fitting later on. Eventually the previous position may be still used trackedObject.ThisFrameX = float.NaN; trackedObject.ThisFrameY = float.NaN; trackedObject.ThisFrameCertainty = float.NaN; } } }
protected virtual void TrackSingleStar(int frameNo, IAstroImage astroImage) { OccultedStar.NewFrame(); m_NotCertain = false; float expectedX; float expectedY; GetExpectedXY(out expectedX, out expectedY); uint[,] pixels = astroImage.GetPixelsArea((int)expectedX, (int)expectedY, 17); // There is only one object in the area, just do a wide fit followed by a fit with the selected matrix size PSFFit gaussian = new PSFFit((int)expectedX, (int)expectedY); gaussian.Fit(pixels, 17); IImagePixel firstCenter = gaussian.IsSolved ? new ImagePixel((int)gaussian.XCenter, (int)gaussian.YCenter) : astroImage.GetCentroid((int)expectedX, (int)expectedY, 17, m_MedianValue); if (firstCenter != null) { // Do a second fit pixels = astroImage.GetPixelsArea(firstCenter.X, firstCenter.Y, 17); gaussian = new PSFFit(firstCenter.X, firstCenter.Y); gaussian.Fit(pixels, OccultedStar.PsfFitMatrixSize); if (gaussian.IsSolved) { double signal = gaussian.IMax - gaussian.I0; if (signal < 0) { signal = 0; } double brightnessFluctoation = signal > OccultedStar.RefinedOrLastSignalLevel ? signal / OccultedStar.RefinedOrLastSignalLevel : OccultedStar.RefinedOrLastSignalLevel / signal; //double brightnessFluctoation = (trackedObject.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / trackedObject.RefinedOrLastSignalLevel; double fluckDiff = Math.Abs(brightnessFluctoation) / m_AllowedSignalFluctoation; if (fluckDiff < 1 || (LightCurveReductionContext.Instance.HighFlickeringOrLargeStars && !LightCurveReductionContext.Instance.FullDisappearance && !LightCurveReductionContext.Instance.IsDriftThrough)) { OccultedStar.PSFFit = gaussian; OccultedStar.ThisFrameX = (float)gaussian.XCenter; OccultedStar.ThisFrameY = (float)gaussian.YCenter; OccultedStar.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0); OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty; OccultedStar.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully); } else { m_NotCertain = true; // This is the Occulted Star, so no brightness fluctoations can be used as excuses! FitObjectInLimitedArea(OccultedStar, astroImage, expectedX, expectedY); OccultedStar.SetIsLocated( LightCurveReductionContext.Instance.FullDisappearance || OccultedStar.PSFFit != null, LightCurveReductionContext.Instance.FullDisappearance || OccultedStar.PSFFit != null ? NotMeasuredReasons.TrackedSuccessfully : NotMeasuredReasons.DistanceToleranceTooHighForNonFullDisappearingOccultedStar); m_NotCertain = !OccultedStar.IsLocated; if (m_PreviousPositions.Count > 1 && LightCurveReductionContext.Instance.FullDisappearance && LightCurveReductionContext.Instance.IsDriftThrough) { var prevSignals = m_PreviousPositions.Select(x => x.Brightness).ToList(); var prevSignalMedian = prevSignals.Median(); var prevSignalSigma = Math.Sqrt(prevSignals.Sum(x => (x - prevSignalMedian) * (x - prevSignalMedian)) / (m_PreviousPositions.Count - 1)); var bigBrightnessVariation = (Math.Abs(signal - prevSignalMedian) > prevSignalSigma); m_NotCertain = m_NotCertain || bigBrightnessVariation; } if (m_NotCertain) { OccultedStar.ThisFrameX = expectedX; OccultedStar.ThisFrameY = expectedY; OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty; } } } else { OccultedStar.ThisFrameX = expectedX; OccultedStar.ThisFrameY = expectedY; OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty; Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve second PSF", m_FrameNo, OccultedStar.TargetNo)); OccultedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed); } } else { OccultedStar.ThisFrameX = expectedX; OccultedStar.ThisFrameY = expectedY; OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty; Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve first PSF", m_FrameNo, OccultedStar.TargetNo)); OccultedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed); } }
public void NextFrame(int frameNo, IAstroImage astroImage, IStarMap starMap, LeastSquareFittedAstrometry astrometricFit) { IsTrackedSuccessfully = false; int searchRadius = (int)Math.Ceiling(Math.Max(m_LastMovementPixels, CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius)); PSFFit psfFit = null; int startingX = (int)TrackedObject.LastKnownX; int startingY = (int)TrackedObject.LastKnownY; if (m_RepeatedIntergationPositions * 4 < m_PastFrameNos.Count) { var expectedPos = GetExpectedPosition(frameNo); if (expectedPos != null) { startingX = expectedPos.X; startingY = expectedPos.Y; } } var nearbyFeatures = starMap.GetFeaturesInRadius(startingX, startingY, searchRadius).ToArray(); var nonStarNearbyFeature = new List <StarMapFeature>(); foreach (var feature in nearbyFeatures) { var center = feature.GetCenter(); var referenceStarFeatures = astrometricFit.FitInfo.AllStarPairs.Where(x => x.FitInfo.UsedInSolution).ToList(); var refStar = referenceStarFeatures.FirstOrDefault(s => Math.Sqrt((s.x - center.X) * (s.x - center.X) + (s.y - center.Y) * (s.y - center.Y)) < 2); double raf, def; astrometricFit.GetRADEFromImageCoords(center.XDouble, center.YDouble, out raf, out def); var pastKnownStar = m_LastFrameStars.FirstOrDefault(s => AngleUtility.Elongation(s.RADeg, s.DEDeg, raf, def) * 3600.0 < 2); if (refStar == null && pastKnownStar == null) { nonStarNearbyFeature.Add(feature); } } if (nonStarNearbyFeature.Count > 0) { StarMapFeature closestFeature = nonStarNearbyFeature[0]; var lastKnownCenter = new ImagePixel(TrackedObject.LastKnownX, TrackedObject.LastKnownY); var smallestDistance = lastKnownCenter.DistanceTo(closestFeature.GetCenter()); for (int i = 1; i < nonStarNearbyFeature.Count; i++) { var distance = lastKnownCenter.DistanceTo(nonStarNearbyFeature[i].GetCenter()); if (distance < smallestDistance) { smallestDistance = distance; closestFeature = nonStarNearbyFeature[i]; } } if (closestFeature != null) { var center = closestFeature.GetCenter(); AstrometryContext.Current.StarMap.GetPSFFit(center.X, center.Y, PSFFittingMethod.NonLinearFit, out psfFit); } } if (psfFit == null) { // The expected location cannot be matched with any brighter feature so it is likely a faint object // with no brighter objects around. Lets find the brightest (faint) object in the are and use it ImagePixel centroid = AstrometryContext.Current.StarMap.GetCentroid(startingX, startingY, searchRadius); if (centroid != null) { AstrometryContext.Current.StarMap.GetPSFFit(centroid.X, centroid.Y, PSFFittingMethod.NonLinearFit, out psfFit); } } if (psfFit != null) { double ra, de; astrometricFit.GetRADEFromImageCoords(psfFit.XCenter, psfFit.YCenter, out ra, out de); double maxPosDiffArcSec = astrometricFit.GetDistanceInArcSec(astrometricFit.Image.CenterXImage, astrometricFit.Image.CenterYImage, astrometricFit.Image.CenterXImage + Math.Max(m_LastMovementPixels, CoreAstrometrySettings.Default.MaxAllowedDefaultMotionInPixels), astrometricFit.Image.CenterYImage); if (!double.IsNaN(TrackedObject.RAHours)) { double posDif = 3600 * AngleUtility.Elongation(15 * TrackedObject.RAHours, TrackedObject.DEDeg, ra, de); if (posDif > maxPosDiffArcSec) { // NOTE: Not a valid measurement Trace.WriteLine(string.Format("The target position is too far from the last measured position", posDif)); return; } } TrackedObject.RAHours = ra / 15.0; TrackedObject.DEDeg = de; if (TrackedObject.PSFFit != null) { m_LastMovementPixels = 1.2 * ImagePixel.ComputeDistance(TrackedObject.LastKnownX, psfFit.XCenter, TrackedObject.LastKnownY, psfFit.YCenter); } TrackedObject.LastKnownX = psfFit.XCenter; TrackedObject.LastKnownY = psfFit.YCenter; TrackedObject.PSFFit = psfFit; var lastKnownCenter = new ImagePixel(TrackedObject.LastKnownX, TrackedObject.LastKnownY); var thisFrameStars = astrometricFit.FitInfo.AllStarPairs.Where(x => lastKnownCenter.DistanceTo(x.x, x.y) > 2 * psfFit.FWHM).ToList(); if (thisFrameStars.Count > 0) { m_LastFrameStars = thisFrameStars.Select(x => new Star(x.StarNo, x.RADeg, x.DEDeg, x.Mag) as IStar).ToList(); } IsTrackedSuccessfully = true; } if (psfFit != null && psfFit.XCenter > 0 && psfFit.YCenter > 0) { m_PastFramePosX.Add(psfFit.XCenter); m_PastFramePosY.Add(psfFit.YCenter); m_PastFrameNos.Add(frameNo); } }
public virtual void BeginMeasurements(IAstroImage astroImage) { m_Refining = false; m_MedianValue = (byte)Math.Min(254, ((astroImage.MedianNoise + m_MedianValueStart) / 2.0)); FinalizeRefining(); }
public virtual bool InitializeNewTracking(IAstroImage astroImage) { m_Refining = true; return true; }
protected override void TrackSingleStar(int frameNo, IAstroImage astroImage) { // TODO: Do some smarts for Lunar Occultations? base.TrackSingleStar(frameNo, astroImage); }
protected void FitObjectInLimitedArea(TrackedObject trackedObject, IAstroImage astroImage, float startingX, float startingY) { int smallestMatrixSize = (int)Math.Round(trackedObject.OriginalObject.ApertureInPixels * 2); if (smallestMatrixSize % 2 == 0) smallestMatrixSize++; // If this is not an aperture photometry we still derive a PSF uint[,] pixels = astroImage.GetPixelsArea((int)Math.Round(startingX), (int)Math.Round(startingY), 17); bool isFSPSolved = false; bool isTooFar = true; for (int i = Math.Max(trackedObject.PsfFitMatrixSize, smallestMatrixSize); i >= smallestMatrixSize; i -= 2) { int borderZeroes = (trackedObject.PsfFitMatrixSize - i) / 2; for (int x = 0; x < pixels.GetLength(0); x++) { for (int y = 0; y < borderZeroes; y++) { pixels[x, y] = 0; pixels[x, pixels.GetLength(1) - y - 1] = 0; } } for (int y = 0; y < pixels.GetLength(1); y++) { for (int x = 0; x < borderZeroes; x++) { pixels[x, y] = 0; pixels[pixels.GetLength(0) - x - 1, y] = 0; } } PSFFit gaussian = new PSFFit((int)Math.Round(startingX), (int)Math.Round(startingY)); gaussian.Fit(pixels, trackedObject.PsfFitMatrixSize); isFSPSolved = gaussian.IsSolved; isTooFar = true; if (gaussian.IsSolved) { trackedObject.ThisFrameCertainty = (float)gaussian.Certainty; double dist = ImagePixel.ComputeDistance((float)gaussian.XCenter, (float)startingX, (float)gaussian.YCenter, (float)startingY); if (dist <= PositionTolerance) { isTooFar = false; trackedObject.PSFFit = gaussian; trackedObject.ThisFrameX = (float)gaussian.XCenter; trackedObject.ThisFrameY = (float)gaussian.YCenter; trackedObject.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0); trackedObject.ThisFrameCertainty = (float)gaussian.Certainty; trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully); return; } } } trackedObject.PSFFit = null; trackedObject.ThisFrameX = startingX; trackedObject.ThisFrameY = startingY; trackedObject.SetIsLocated(false, !isFSPSolved ? NotMeasuredReasons.PSFFittingFailed : isTooFar ? NotMeasuredReasons.FoundObjectNotWithInExpectedPositionTolerance : NotMeasuredReasons.UnknownReason); }
public override void NextFrame(int frameNo, IAstroImage astroImage) { m_FrameNo = frameNo; if (m_Refining) { // For refining use the base class base.NextFrame(frameNo, astroImage); } else { // And for measuring use TrackSingleStar(frameNo, astroImage); } if (m_RefiningFramesLeft > 0) { if (OccultedStar.IsLocated) m_RefiningFramesLeft--; } else { m_IsTrackedSuccessfully = OccultedStar.IsLocated; } if (OccultedStar.IsLocated && !m_NotCertain) AddPreviousPosition(); if (OccultedStar.IsLocated) { OccultedStar.LastKnownGoodPosition = new ImagePixel(OccultedStar.Center); OccultedStar.LastKnownGoodPsfCertainty = OccultedStar.PSFFit != null ? OccultedStar.PSFFit.Certainty : 0; } }
private void CheckAndCorrectGuidingStarPositions(IAstroImage astroImage, bool retryWithLPFilterIfSuspectObjects) { List<int> goodObjects = new List<int>(); List<int> suspectObjects = new List<int>(); for (int k = 0; k < 2; k++) { goodObjects.Clear(); suspectObjects.Clear(); if (LocateFirstObjects.Count == 1) { if (!LocateFirstObjects[0].IsLocated || float.IsNaN(LocateFirstObjects[0].ThisFrameX) || float.IsNaN(LocateFirstObjects[0].ThisFrameY)) { suspectObjects.Add(LocateFirstObjects[0].TargetNo); } } else { // See how many of the distances are okay for (int i = 0; i < LocateFirstObjects.Count; i++) { TrackedObject obj1 = LocateFirstObjects[i]; for (int j = 0; j < LocateFirstObjects.Count; j++) { if (i == j) continue; TrackedObject obj2 = LocateFirstObjects[j]; long pairId = (((long) obj1.TargetNo) << 32) + (long) obj2.TargetNo; double expectedDistance = m_RefinedDistances[pairId]; double actualDistance = ImagePixel.ComputeDistance(obj1.ThisFrameX, obj2.ThisFrameX, obj1.ThisFrameY, obj2.ThisFrameY); if (Math.Abs(expectedDistance - actualDistance) <= PositionTolerance) { goodObjects.Add(obj1.TargetNo); goodObjects.Add(obj2.TargetNo); } else { suspectObjects.Add(obj1.TargetNo); suspectObjects.Add(obj2.TargetNo); } } } } if (k == 0 && suspectObjects.Count > 0 && retryWithLPFilterIfSuspectObjects) { // There are some suspect objects. Try to locate the guiding stars with a low pass filter foreach (TrackedObject trackedObject in LocateFirstObjects) LocateObjectAsGuidingStar(astroImage, trackedObject, true); } else break; } if (suspectObjects.Count > 0) { if (goodObjects.Distinct().Count() == LocateFirstObjectsTargetIds.Count) { // There is at least one good distance involving each of the locate first objects // This means the suspect distance it not too bad so we ignore and continue } else { if (goodObjects.Count == 0) { List<TrackedObject> okayObjects = LocateFirstObjects.FindAll(o => !o.IsOccultedStar && o.IsLocated); if (okayObjects.Count == 0) { // If one of the objects is the occulted star (found) and non of the other guiding stars are found // then make all objects not found and use the latest expected positions foreach(TrackedObject obj in LocateFirstObjects) { obj.PSFFit = null; obj.ThisFrameX = obj.LastFrameX; obj.ThisFrameY = obj.LastFrameY; obj.ThisFrameCertainty = (float)obj.LastKnownGoodPsfCertainty; obj.SetIsLocated(false, NotMeasuredReasons.FitSuspectAsNoGuidingStarsAreLocated); } m_AllGuidingStarsFailed = true; return; } // If no distances are okay consider the brightest located first object as the correctly identified one // and then find the positions of the other ones based on the expected distances (and do another PSF fit in a smaller area) okayObjects = LocateFirstObjects.FindAll(o => o.IsLocated); okayObjects.Sort((o1, o2) => o1.LastSignalLevel.CompareTo(o2.LastSignalLevel)); TrackedObject brightestObject = okayObjects[0]; foreach (TrackedObject obj in LocateFirstObjects) { if (obj.TargetNo == brightestObject.TargetNo) continue; LocationVector vec = brightestObject.OtherGuidingStarsLocationVectors[obj.TargetNo]; double expectedX = brightestObject.ThisFrameX + vec.DeltaXToAdd; double expectedY = brightestObject.ThisFrameY + vec.DeltaYToAdd; if (expectedX < RefinedAverageFWHM || expectedX > astroImage.Width - RefinedAverageFWHM || expectedY < RefinedAverageFWHM || expectedY > astroImage.Height - RefinedAverageFWHM) { // The expected position in Off Screen. obj.PSFFit = null; obj.ThisFrameX = float.NaN; obj.ThisFrameY = float.NaN; obj.ThisFrameCertainty = float.NaN; obj.SetIsLocated(false, NotMeasuredReasons.ObjectExpectedPositionIsOffScreen); continue; } uint[,] pixels = astroImage.GetPixelsArea((int)Math.Round(expectedX), (int)Math.Round(expectedY), 19); pixels = EnhanceByteAreaForSearch(pixels); PSFFit gaussian = new PSFFit((int)Math.Round(expectedX), (int)Math.Round(expectedY)); gaussian.Fit(pixels, obj.PsfFitMatrixSize); if (gaussian.IsSolved) { double distance = ImagePixel.ComputeDistance(gaussian.XCenter, expectedX, gaussian.YCenter, expectedY); if (distance <= 2 * PositionTolerance) { // Object successfully located obj.PSFFit = gaussian; obj.ThisFrameX = (float)gaussian.XCenter; obj.ThisFrameY = (float)gaussian.YCenter; obj.ThisFrameCertainty = (float)gaussian.Certainty; obj.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterDistanceCheck); Trace.WriteLine(string.Format("Frame {0}: Successfully located object #{1} after a close look up {2}px from the expected position.", m_FrameNo, obj.TargetNo, distance.ToString("0.00"))); } else { obj.PSFFit = null; obj.ThisFrameX = (float)expectedX; obj.ThisFrameY = (float)expectedY; obj.ThisFrameCertainty = 0; obj.SetIsLocated(false, NotMeasuredReasons.FailedToLocateAfterDistanceCheck); Trace.WriteLine(string.Format("Frame {0}: Cannot locate object #{1}. A close look up found it {2}px from the expected position.", m_FrameNo, obj.TargetNo, distance.ToString("0.00"))); } } } } else { // Some objects are okay and some are not okay. List<int> badObjectIds = suspectObjects.FindAll(o => goodObjects.IndexOf(o) == -1).Distinct().ToList(); List<int> goodObjectIds = goodObjects.Distinct().ToList(); foreach(int badObjectId in badObjectIds) { double expectedX = 0; double expectedY = 0; TrackedObject badObject = TrackedObjectsByTargetId[badObjectId]; foreach (int goodObjectId in goodObjectIds) { TrackedObject goodObject = TrackedObjectsByTargetId[goodObjectId]; LocationVector vec = goodObject.OtherGuidingStarsLocationVectors[badObjectId]; expectedX += (goodObject.ThisFrameX + vec.DeltaXToAdd); expectedY += (goodObject.ThisFrameY + vec.DeltaYToAdd); } expectedX /= goodObjectIds.Count; expectedY /= goodObjectIds.Count; uint[,] pixels = astroImage.GetPixelsArea((int)Math.Round(expectedX), (int)Math.Round(expectedY), 19); pixels = EnhanceByteAreaForSearch(pixels); PSFFit gaussian = new PSFFit((int)Math.Round(expectedX), (int)Math.Round(expectedY)); gaussian.Fit(pixels, badObject.PsfFitMatrixSize); if (gaussian.IsSolved) { double distance = ImagePixel.ComputeDistance(gaussian.XCenter, expectedX, gaussian.YCenter, expectedY); if (distance <= 2 * PositionTolerance) { // Object successfully located badObject.PSFFit = gaussian; badObject.ThisFrameX = (float)gaussian.XCenter; badObject.ThisFrameY = (float)gaussian.YCenter; badObject.ThisFrameCertainty = (float)gaussian.Certainty; badObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterDistanceCheck); Trace.WriteLine(string.Format("Frame {0}: Successfully located object #{1} after a close look up {2}px from the expected position.", m_FrameNo, badObjectId, distance.ToString("0.00"))); } else { badObject.PSFFit = null; badObject.ThisFrameX = (float)expectedX; badObject.ThisFrameY = (float)expectedY; badObject.ThisFrameCertainty = 0; badObject.SetIsLocated(false, NotMeasuredReasons.FailedToLocateAfterDistanceCheck); Trace.WriteLine(string.Format("Frame {0}: Cannot locate object #{1}. A close look up found it {2}px from the expected position.", m_FrameNo, badObjectId, distance.ToString("0.00"))); } } } } } } else if ( goodObjects.Count == 0 && LocateFirstObjects.Count == 1 && float.IsNaN(LocateFirstObjects[0].ThisFrameX)) { // Single 'lost' guiding star or single object (occulted star only) TrackedObject obj1 = LocateFirstObjects[0]; float bestFluctDiff = float.MaxValue; int coeff = LightCurveReductionContext.Instance.WindOrShaking ? 3 : 1; for (int i = 0; i < coeff * obj1.PsfFitMatrixSize; i++) { int searchRadius = obj1.PsfFitMatrixSize + i; IImagePixel centroid = astroImage.GetCentroid( (int) Math.Round(obj1.LastFrameX), (int) Math.Round(obj1.LastFrameY), searchRadius, m_MedianValue); if (centroid != null) { uint[,] pixels = astroImage.GetPixelsArea(centroid.X, centroid.Y, 19); PSFFit gaussian = new PSFFit(centroid.X, centroid.Y); gaussian.Fit(pixels, obj1.PsfFitMatrixSize); if (gaussian.IsSolved) { double brightnessFluctoation = (obj1.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / obj1.RefinedOrLastSignalLevel; double fluckDiff = Math.Abs(brightnessFluctoation) / m_AllowedSignalFluctoation; if (fluckDiff < 1 || LightCurveReductionContext.Instance.HighFlickeringOrLargeStars) { obj1.PSFFit = gaussian; obj1.ThisFrameX = (float) gaussian.XCenter; obj1.ThisFrameY = (float) gaussian.YCenter; obj1.ThisSignalLevel = (float) (gaussian.IMax - gaussian.I0); obj1.ThisFrameCertainty = (float)gaussian.Certainty; obj1.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfullyAfterWiderAreaSearch); Trace.WriteLine( string.Format( "Frame {0}: Successfully located object #{1} after a wider search in {2}px region.", m_FrameNo, obj1.TargetNo, searchRadius)); break; } else { if (bestFluctDiff > fluckDiff) bestFluctDiff = (float)fluckDiff; } } } } if (!obj1.IsLocated) { obj1.PSFFit = null; obj1.ThisFrameX = obj1.LastFrameX; obj1.ThisFrameY = obj1.LastFrameY; obj1.ThisSignalLevel = obj1.LastSignalLevel; obj1.ThisFrameCertainty = (float) obj1.LastKnownGoodPsfCertainty; obj1.SetIsLocated(false, NotMeasuredReasons.TrackedSuccessfullyAfterWiderAreaSearch); Trace.WriteLine(string.Format("Frame {0}: Cannot locate object #{1} after a wider search in {2}px region. Best fluct diff: {3}", m_FrameNo, obj1.TargetNo, obj1.PsfFitMatrixSize * 2, bestFluctDiff.ToString("0.00"))); } } }
private void LocateTwoStarsWithStarRecognition(List <PotentialStarStruct> stars, IAstroImage astroImage, uint[,] pixels) { TrackedObject trackedObject1 = TrackedObjects.Cast <TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[0]); TrackedObject trackedObject2 = TrackedObjects.Cast <TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[1]); LocateTwoStarsWithStarRecognition(stars, astroImage, pixels, trackedObject1, trackedObject2); }
private void LocateFullDisappearingObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos) { if (m_Refining) // Full disapearance is not expected during refining LocateNonGuidingObject(astroImage, trackedObject, newStaringPos); else { double averageX, averageY; GetAverageObjectPositionsFromGuidingStars(trackedObject, newStaringPos, out averageX, out averageY); trackedObject.ThisFrameX = (float)averageX + 0.5f; trackedObject.ThisFrameY = (float)averageY + 0.5f; trackedObject.PSFFit = null; trackedObject.ThisSignalLevel = float.NaN; trackedObject.ThisFrameCertainty = 1; int x0 = (int) Math.Round(averageX); int y0 = (int) Math.Round(averageY); trackedObject.SetIsLocated(false, NotMeasuredReasons.UnknownReason); PSFFit gaussian = null; int smallestMatrixSize = (int)Math.Round(trackedObject.OriginalObject.ApertureInPixels * 2); if (smallestMatrixSize % 2 == 0) smallestMatrixSize++; // If this is not an aperture photometry we still derive a PSF uint[,] pixels = astroImage.GetPixelsArea(x0, y0, 17); for (int i = trackedObject.PsfFitMatrixSize; i >= smallestMatrixSize; i -= 2) { int borderZeroes = (trackedObject.PsfFitMatrixSize - i) / 2; for (int x = 0; x < pixels.GetLength(0); x++) { for (int y = 0; y < borderZeroes; y++) { pixels[x, y] = 0; pixels[x, pixels.GetLength(1) - y - 1] = 0; } } for (int y = 0; y < pixels.GetLength(1); y++) { for (int x = 0; x < borderZeroes; x++) { pixels[x, y] = 0; pixels[pixels.GetLength(0) - x - 1, y] = 0; } } gaussian = new PSFFit(x0, y0); gaussian.Fit(pixels, trackedObject.PsfFitMatrixSize); if (gaussian.IsSolved) { double dist = ImagePixel.ComputeDistance((float)gaussian.XCenter, (float)averageX, (float)gaussian.YCenter, (float)averageY); if (dist <= PositionTolerance) { trackedObject.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully); break; } else trackedObject.SetIsLocated(false, NotMeasuredReasons.FoundObjectNotWithInExpectedPositionTolerance); } else trackedObject.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed); } if (gaussian != null) { if (!trackedObject.IsLocated) trackedObject.SetIsLocated(true, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound); trackedObject.PSFFit = gaussian; trackedObject.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0); trackedObject.ThisFrameX = (float)gaussian.XCenter; trackedObject.ThisFrameY = (float)gaussian.YCenter; trackedObject.ThisFrameCertainty = (float)gaussian.Certainty; } } }
public override void NextFrame(int frameNo, IAstroImage astroImage) { base.NextFrame(frameNo, astroImage); #region run the full star recognition recovery if enabled if (TangraConfig.Settings.Tracking.RecoverFromLostTracking && m_RefiningFramesLeft <= 0) { bool notAllStarsLocated = TrackedObjects.Exists(o => !o.IsLocated); bool notAllLocateFirstStarsLocated = LocateFirstObjects.Exists(o => !o.IsLocated); if (notAllLocateFirstStarsLocated && LocateFirstObjects.Count > 1) { LocateStarsWithStarRecognition(astroImage); } // TODO: Use the notAllStarsLocated to troubleshoot the pattern recognition alignment } #endregion bool allGuidingStarsLocated = true; foreach (TrackedObject trackedObject in LocateFirstObjects) { if (!trackedObject.IsLocated && !trackedObject.IsOffScreen) { allGuidingStarsLocated = false; } } if (m_RefiningFramesLeft > 0) { if (allGuidingStarsLocated) { m_RefiningFramesLeft--; } } else { m_IsTrackedSuccessfully = LocateFirstObjects.Count > 0 ? allGuidingStarsLocated : OccultedStar.IsLocated; } if (!m_Refining && (LocateFirstObjects.Count > 0 && allGuidingStarsLocated) && (LightCurveReductionContext.Instance.FieldRotation || LightCurveReductionContext.Instance.LightCurveReductionType == LightCurveReductionType.MutualEvent)) { for (int i = 0; i < TrackedObjects.Count; i++) { TrackedObject obj1 = TrackedObjects[i] as TrackedObject; for (int j = 0; j < TrackedObjects.Count; j++) { if (i == j) { continue; } TrackedObject obj2 = TrackedObjects[j] as TrackedObject; long pairId = (((long)obj1.TargetNo) << 32) + (long)obj2.TargetNo; double oldDistance = m_RefinedDistances[pairId]; double newDistance = ImagePixel.ComputeDistance( obj1.Center.XDouble, obj2.Center.XDouble, obj1.Center.YDouble, obj2.Center.YDouble); m_RefinedDistances[pairId] = (oldDistance + newDistance) / 2.0; LocationVector vector = obj1.OtherGuidingStarsLocationVectors[obj2.TargetNo]; vector.DeltaXToAdd = (vector.DeltaXToAdd + obj2.Center.XDouble - obj1.Center.XDouble) / 2; vector.DeltaYToAdd = (vector.DeltaYToAdd + obj2.Center.YDouble - obj1.Center.YDouble) / 2; } } } if (!m_IsTrackedSuccessfully) { // If the tracking has failed, then some objects may be offscreen and have NaN position // So inherit the IsOffScreen flag from the previous position foreach (TrackedObject obj in TrackedObjects) { if (m_IsOffScreenPrev[obj.TargetNo] && double.IsNaN(obj.Center.XDouble)) { obj.SetIsLocated(false, NotMeasuredReasons.ObjectExpectedPositionIsOffScreen); } } } else { foreach (TrackedObject obj in TrackedObjects) { m_IsOffScreenPrev[obj.TargetNo] = obj.IsOffScreen; } } }
private void LocateNonGuidingObject(IAstroImage astroImage, TrackedObject trackedObject, IImagePixel newStaringPos) { trackedObject.SetIsLocated(false, NotMeasuredReasons.UnknownReason); double averageX = 0; double averageY = 0; GetAverageObjectPositionsFromGuidingStars(trackedObject, newStaringPos, out averageX, out averageY); trackedObject.ThisFrameX = (float)averageX; trackedObject.ThisFrameY = (float)averageY; trackedObject.PSFFit = null; trackedObject.ThisSignalLevel = float.NaN; trackedObject.ThisFrameCertainty = float.NaN; List<TrackedObject> resolvedGuidingStars = LocateFirstObjects.FindAll(o => o.IsLocated); if (resolvedGuidingStars.Count == 0) { if (m_Refining) trackedObject.RegisterRefinedPosition(newStaringPos, float.NaN, double.NaN); } else { FitObjectInLimitedArea(trackedObject, astroImage, (float) averageX, (float) averageY); if (m_Refining) trackedObject.RegisterRefinedPosition( new ImagePixel((int)trackedObject.ThisSignalLevel, trackedObject.ThisFrameX, trackedObject.ThisFrameY), trackedObject.ThisSignalLevel, trackedObject.PSFFit != null ? trackedObject.PSFFit.FWHM : double.NaN); } }
public override void NextFrame(int frameNo, IAstroImage astroImage) { IsTrackedSuccessfully = false; // For each of the non manualy positioned Tracked objects do a PSF fit in the area of its previous location for (int i = 0; i < m_TrackedObjects.Count; i++) { TrackedObjectLight trackedObject = (TrackedObjectLight)m_TrackedObjects[i]; trackedObject.NextFrame(); if (trackedObject.OriginalObject.IsFixedAperture || (trackedObject.OriginalObject.IsOcultedStar() && m_IsFullDisappearance)) { // Star position will be determined after the rest of the stars are found } else { uint[,] pixels = astroImage.GetPixelsArea(trackedObject.Center.X, trackedObject.Center.Y, 17); var fit = new PSFFit(trackedObject.Center.X, trackedObject.Center.Y); fit.FittingMethod = TangraConfig.Settings.Tracking.CheckElongation ? PSFFittingMethod.NonLinearAsymetricFit : PSFFittingMethod.NonLinearFit; fit.Fit(pixels); if (fit.IsSolved) { if (fit.Certainty < GUIDING_STAR_MIN_CERTAINTY) { trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall); } else if (fit.FWHM < STELLAR_OBJECT_MIN_FWHM || fit.FWHM > STELLAR_OBJECT_MAX_FWHM) { trackedObject.SetIsTracked(false, NotMeasuredReasons.FWHMOutOfRange); } else if (TangraConfig.Settings.Tracking.CheckElongation && fit.ElongationPercentage > STELLAR_OBJECT_MAX_ELONGATION) { trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectTooElongated); } else { trackedObject.SetTrackedObjectMatch(fit); trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully); } } } } bool atLeastOneObjectLocated = false; for (int i = 0; i < m_TrackedObjects.Count; i++) { TrackedObjectLight trackedObject = (TrackedObjectLight)m_TrackedObjects[i]; bool needsRelativePositioning = trackedObject.OriginalObject.IsFixedAperture || (trackedObject.OriginalObject.IsOcultedStar() && m_IsFullDisappearance); if (!needsRelativePositioning && trackedObject.IsLocated) { atLeastOneObjectLocated = true; } if (!needsRelativePositioning) { continue; } double totalX = 0; double totalY = 0; int numReferences = 0; for (int j = 0; j < m_TrackedObjects.Count; j++) { TrackedObjectLight referenceObject = (TrackedObjectLight)m_TrackedObjects[j]; if (referenceObject.IsLocated) { totalX += (trackedObject.OriginalObject.ApertureStartingX - referenceObject.OriginalObject.ApertureStartingX) + referenceObject.Center.XDouble; totalY += (trackedObject.OriginalObject.ApertureStartingY - referenceObject.OriginalObject.ApertureStartingY) + referenceObject.Center.YDouble; numReferences++; atLeastOneObjectLocated = true; } } if (numReferences == 0) { trackedObject.SetIsTracked(false, NotMeasuredReasons.FitSuspectAsNoGuidingStarsAreLocated); } else { double x_double = totalX / numReferences; double y_double = totalY / numReferences; if (trackedObject.OriginalObject.IsFixedAperture) { trackedObject.SetIsTracked(true, NotMeasuredReasons.FixedObject, new ImagePixel(x_double, y_double), 1); } else if (trackedObject.OriginalObject.IsOcultedStar()) { int x = (int)(Math.Round(totalX / numReferences)); int y = (int)(Math.Round(totalY / numReferences)); int matrixSize = (int)(Math.Round(trackedObject.OriginalObject.ApertureInPixels * 1.5)); if (matrixSize % 2 == 0) { matrixSize++; } if (matrixSize > 17) { matrixSize = 17; } uint[,] pixels = astroImage.GetPixelsArea(x, y, matrixSize); PSFFit fit = new PSFFit(x, y); fit.Fit(pixels); if (fit.IsSolved && fit.Certainty > STELLAR_OBJECT_MIN_CERTAINTY) { trackedObject.SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully); trackedObject.SetTrackedObjectMatch(fit); } else if (m_IsFullDisappearance) { trackedObject.SetIsTracked(false, NotMeasuredReasons.FullyDisappearingStarMarkedTrackedWithoutBeingFound); } else { trackedObject.SetIsTracked(false, NotMeasuredReasons.ObjectCertaintyTooSmall); } } } } IsTrackedSuccessfully = atLeastOneObjectLocated; }
public void BeginMeasurements(IAstroImage astroImage) { }
public void NextFrame(int frameNo, IAstroImage astroImage, IStarMap starMap, LeastSquareFittedAstrometry astrometricFit) { IsTrackedSuccessfully = false; PSFFit psfFit = null; if (m_RepeatedIntergationPositions * 4 < m_PastFrameNos.Count) { var expectedPos = GetExpectedPosition(frameNo); if (expectedPos != null) AstrometryContext.Current.StarMap.GetPSFFit(expectedPos.X, expectedPos.Y, PSFFittingMethod.NonLinearFit, out psfFit); } if (psfFit == null) { var brightestFeature = starMap.GetFeatureInRadius((int)TrackedObject.LastKnownX, (int)TrackedObject.LastKnownY, CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius); if (brightestFeature != null) { var center = brightestFeature.GetCenter(); var referenceStarFeatures = astrometricFit.FitInfo.AllStarPairs.Where(x => x.FitInfo.UsedInSolution).ToList(); var refStar = referenceStarFeatures.FirstOrDefault(s => Math.Sqrt((s.x - center.X) * (s.x - center.X) + (s.y - center.Y) * (s.y - center.Y)) < 2); if (refStar == null) // The brightest feature is not a reference star, so we assume it is our object AstrometryContext.Current.StarMap.GetPSFFit(center.X, center.Y, PSFFittingMethod.NonLinearFit, out psfFit); } } if (psfFit == null) { ImagePixel centroid = AstrometryContext.Current.StarMap.GetCentroid( (int)TrackedObject.LastKnownX, (int)TrackedObject.LastKnownY, CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius); if (centroid != null) AstrometryContext.Current.StarMap.GetPSFFit(centroid.X, centroid.Y, PSFFittingMethod.NonLinearFit, out psfFit); } if (psfFit != null) { double ra, de; astrometricFit.GetRADEFromImageCoords(psfFit.XCenter, psfFit.YCenter, out ra, out de); double maxPosDiffArcSec = astrometricFit.GetDistanceInArcSec(astrometricFit.Image.CenterXImage, astrometricFit.Image.CenterYImage, astrometricFit.Image.CenterXImage + CoreAstrometrySettings.Default.PreMeasureSearchCentroidRadius, astrometricFit.Image.CenterYImage); if (!double.IsNaN(TrackedObject.RAHours)) { double posDif = 3600 * AngleUtility.Elongation(15 * TrackedObject.RAHours, TrackedObject.DEDeg, ra, de); if (posDif > maxPosDiffArcSec) { // NOTE: Not a valid measurement Trace.WriteLine(string.Format("The target position is too far from the last measured position", posDif)); return; } } TrackedObject.RAHours = ra / 15.0; TrackedObject.DEDeg = de; TrackedObject.LastKnownX = psfFit.XCenter; TrackedObject.LastKnownY = psfFit.YCenter; TrackedObject.PSFFit = psfFit; IsTrackedSuccessfully = true; } if (psfFit != null && psfFit.XCenter > 0 && psfFit.YCenter > 0) { m_PastFramePosX.Add(psfFit.XCenter); m_PastFramePosY.Add(psfFit.YCenter); m_PastFrameNos.Add(frameNo); } }
private void LocateTwoStarsWithStarRecognition(List<PotentialStarStruct> stars, IAstroImage astroImage, uint[,] pixels) { TrackedObject trackedObject1 = TrackedObjects.Cast<TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[0]); TrackedObject trackedObject2 = TrackedObjects.Cast<TrackedObject>().ToList().Find(o => o.TargetNo == m_LocateObjects[1]); LocateTwoStarsWithStarRecognition(stars, astroImage, pixels, trackedObject1, trackedObject2); }
private void LocateTwoStarsWithStarRecognition( List<PotentialStarStruct> stars, IAstroImage astroImage, uint[,] pixels, TrackedObject trackedObject1, TrackedObject trackedObject2) { List<CandidatePair> candidates = LocateStarPairsWithStarRecognition(trackedObject1, trackedObject2, stars, pixels); LocateTwoStarsWithStarRecognition(candidates, astroImage, trackedObject1, trackedObject2); }
protected virtual void TrackSingleStar(int frameNo, IAstroImage astroImage) { OccultedStar.NewFrame(); m_NotCertain = false; float expectedX; float expectedY; GetExpectedXY(out expectedX, out expectedY); uint[,] pixels = astroImage.GetPixelsArea((int)expectedX, (int)expectedY, 17); // There is only one object in the area, just do a wide fit followed by a fit with the selected matrix size PSFFit gaussian = new PSFFit((int)expectedX, (int)expectedY); gaussian.Fit(pixels, 17); IImagePixel firstCenter = gaussian.IsSolved ? new ImagePixel((int)gaussian.XCenter, (int)gaussian.YCenter) : astroImage.GetCentroid((int)expectedX, (int)expectedY, 17, m_MedianValue); if (firstCenter != null) { // Do a second fit pixels = astroImage.GetPixelsArea(firstCenter.X, firstCenter.Y, 17); gaussian = new PSFFit(firstCenter.X, firstCenter.Y); gaussian.Fit(pixels, OccultedStar.PsfFitMatrixSize); if (gaussian.IsSolved) { double signal = gaussian.IMax - gaussian.I0; if (signal < 0) signal = 0; double brightnessFluctoation = signal > OccultedStar.RefinedOrLastSignalLevel ? signal / OccultedStar.RefinedOrLastSignalLevel : OccultedStar.RefinedOrLastSignalLevel / signal; //double brightnessFluctoation = (trackedObject.RefinedOrLastSignalLevel - gaussian.IMax + gaussian.I0) / trackedObject.RefinedOrLastSignalLevel; double fluckDiff = Math.Abs(brightnessFluctoation) / m_AllowedSignalFluctoation; if (fluckDiff < 1 || LightCurveReductionContext.Instance.HighFlickeringOrLargeStars) { OccultedStar.PSFFit = gaussian; OccultedStar.ThisFrameX = (float)gaussian.XCenter; OccultedStar.ThisFrameY = (float)gaussian.YCenter; OccultedStar.ThisSignalLevel = (float)(gaussian.IMax - gaussian.I0); OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty; OccultedStar.SetIsLocated(true, NotMeasuredReasons.TrackedSuccessfully); } else { m_NotCertain = true; // This is the Occulted Star, so no brightness fluctoations can be used as excuses! FitObjectInLimitedArea(OccultedStar, astroImage, expectedX, expectedY); OccultedStar.SetIsLocated( LightCurveReductionContext.Instance.FullDisappearance || OccultedStar.PSFFit != null, LightCurveReductionContext.Instance.FullDisappearance || OccultedStar.PSFFit != null ? NotMeasuredReasons.TrackedSuccessfully : NotMeasuredReasons.DistanceToleranceTooHighForNonFullDisappearingOccultedStar); m_NotCertain = !OccultedStar.IsLocated; } } else { OccultedStar.ThisFrameX = expectedX; OccultedStar.ThisFrameY = expectedY; OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty; Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve second PSF", m_FrameNo, OccultedStar.TargetNo)); OccultedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed); } } else { OccultedStar.ThisFrameX = expectedX; OccultedStar.ThisFrameY = expectedY; OccultedStar.ThisFrameCertainty = (float)gaussian.Certainty; Trace.WriteLine(string.Format("Frame {0}: Cannot confirm target {1} [SingleStar]. Cannot solve first PSF", m_FrameNo, OccultedStar.TargetNo)); OccultedStar.SetIsLocated(false, NotMeasuredReasons.PSFFittingFailed); } }
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(); } }
public void NextFrame(int frameNo, IAstroImage astroImage) { m_IsTrackedSuccessfully = false; StarMap starMap = new StarMap(); starMap.FindBestMap( m_StarMapConfig, (AstroImage)astroImage, Rectangle.Empty, new Rectangle(0, 0, astroImage.Width, astroImage.Height), AstrometryContext.Current.LimitByInclusion); if (starMap.Features.Count >= 5) { starMap.Features.Sort((x, y) => y.PixelCount.CompareTo(x.PixelCount)); int featuresToConsider = Math.Min(10, starMap.Features.Count); var featureDistances = new List <List <double> >(); for (int i = 0; i < featuresToConsider; i++) { var dist = new List <double>(); for (int j = 0; j < featuresToConsider; j++) { dist.Add(double.NaN); } featureDistances.Add(dist); } var pivotDistances = new List <List <double> >(); for (int i = 0; i < featuresToConsider; i++) { pivotDistances.Add(new List <double>(UNINITIALIZED_DISTANCES)); } for (int i = 0; i < featuresToConsider; i++) { var feature_i = starMap.Features[i]; for (int j = i + 1; j < featuresToConsider; j++) { var feature_j = starMap.Features[j]; double distance = feature_j.GetCenter().DistanceTo(feature_i.GetCenter()); pivotDistances[i][j] = distance; pivotDistances[j][i] = distance; } } Dictionary <int, int> pivotMap = IdentifyPivots(pivotDistances); int identifiedObjects = 0; for (int i = 0; i < m_TrackedObjects.Count; i++) { ((TrackedObject)m_TrackedObjects[i]).NewFrame(); var xVals = new List <double>(); var yVals = new List <double>(); foreach (int key in pivotMap.Keys) { int mapsToSourceFeatureId = pivotMap[key]; xVals.Add(starMap.Features[key].GetCenter().XDouble + m_TrackedObjectsPivotDistancesX[i][mapsToSourceFeatureId]); yVals.Add(starMap.Features[key].GetCenter().YDouble + m_TrackedObjectsPivotDistancesY[i][mapsToSourceFeatureId]); } double x0 = xVals.Median(); double y0 = yVals.Median(); double sigmaX = Math.Sqrt(xVals.Select(x => (x - x0) * (x - x0)).Sum()) / (xVals.Count - 1); double sigmaY = Math.Sqrt(yVals.Select(y => (y - y0) * (y - y0)).Sum()) / (yVals.Count - 1); if (!double.IsNaN(x0) && !double.IsNaN(y0) && xVals.Count > 1 && (sigmaX > m_FWHMAverage || sigmaY > m_FWHMAverage)) { // Some of the pivots may have been misidentified. Remove all entries with too large residuals and try again xVals.RemoveAll(x => Math.Abs(x - x0) > sigmaX); yVals.RemoveAll(y => Math.Abs(y - y0) > sigmaY); if (xVals.Count > 1) { x0 = xVals.Median(); y0 = yVals.Median(); sigmaX = Math.Sqrt(xVals.Select(x => (x - x0) * (x - x0)).Sum()) / (xVals.Count - 1); sigmaY = Math.Sqrt(yVals.Select(y => (y - y0) * (y - y0)).Sum()) / (yVals.Count - 1); } } if (!double.IsNaN(x0) && !double.IsNaN(y0) && xVals.Count > 1 && (sigmaX > m_FWHMAverage || sigmaY > m_FWHMAverage)) { // There is something really wrong about this. Reject the position and fail the frame m_TrackedObjects[i].SetIsTracked(false, NotMeasuredReasons.FoundObjectNotWithInExpectedPositionTolerance, null, null); } else { PSFFit fit = new PSFFit((int)x0, (int)y0); uint[,] data = ((AstroImage)astroImage).GetMeasurableAreaPixels((int)x0, (int)y0); fit.Fit(data); if (fit.IsSolved) { m_TrackedObjects[i].SetIsTracked(true, NotMeasuredReasons.TrackedSuccessfully, new ImagePixel(fit.XCenter, fit.YCenter), fit.Certainty); ((TrackedObject)m_TrackedObjects[i]).ThisFrameX = (float)fit.XCenter; ((TrackedObject)m_TrackedObjects[i]).ThisFrameY = (float)fit.YCenter; ((TrackedObjectBase)m_TrackedObjects[i]).PSFFit = fit; identifiedObjects++; } else { m_TrackedObjects[i].SetIsTracked(false, NotMeasuredReasons.PSFFittingFailed, null, null); } } } m_IsTrackedSuccessfully = identifiedObjects == m_TrackedObjects.Count; if (m_IsTrackedSuccessfully) { UpdatePivotDistances(starMap, pivotMap); } } }
public virtual void NextFrame(int frameNo, IAstroImage astroImage) { IsTrackedSuccessfully = false; }
public bool InitializeNewTracking(IAstroImage astroImage) { m_StarMapConfig = new StarMapInternalConfig(StarMapInternalConfig.Default); m_StarMapConfig.CustomMaxSignalValue = astroImage.GetPixelmapPixels().Max(); m_StarMapConfig.CustomOptimumStarsValue = 25; m_StarMapConfig.IsFITSFile = true; StarMap starMap = new StarMap(); starMap.FindBestMap( m_StarMapConfig, (AstroImage)astroImage, Rectangle.Empty, new Rectangle(0, 0, astroImage.Width, astroImage.Height), AstrometryContext.Current.LimitByInclusion); if (starMap.Features.Count < 10) { MessageBox.Show("Cannot initialize object tracking as less than 10 stars can be identified in the field"); return(false); } // Build a signature of the largest 10 features (pivots) m_PivotDistances.Clear(); for (int i = 0; i < 10; i++) { m_PivotDistances.Add(new List <double>(UNINITIALIZED_DISTANCES)); } double fwhmSum = 0; int fwhmCount = 0; starMap.Features.Sort((x, y) => y.PixelCount.CompareTo(x.PixelCount)); for (int i = 0; i < 10; i++) { var feature_i = starMap.Features[i]; for (int j = i + 1; j < 10; j++) { var feature_j = starMap.Features[j]; double distance = feature_j.GetCenter().DistanceTo(feature_i.GetCenter()); m_PivotDistances[i][j] = distance; m_PivotDistances[j][i] = distance; } int x0 = feature_i.GetCenter().X; int y0 = feature_i.GetCenter().Y; PSFFit fit = new PSFFit((int)x0, (int)y0); uint[,] data = ((AstroImage)astroImage).GetMeasurableAreaPixels((int)x0, (int)y0); fit.Fit(data); if (fit.IsSolved) { fwhmSum += fit.FWHM; fwhmCount++; } } m_FWHMAverage = (float)(fwhmSum / fwhmCount); for (int i = 0; i < m_TrackedObjects.Count; i++) { m_TrackedObjectsPivotDistancesX[i] = new List <double>(); m_TrackedObjectsPivotDistancesY[i] = new List <double>(); for (int j = 0; j < 10; j++) { m_TrackedObjectsPivotDistancesX[i].Add(m_TrackedObjects[i].Center.XDouble - starMap.Features[j].GetCenter().XDouble); m_TrackedObjectsPivotDistancesY[i].Add(m_TrackedObjects[i].Center.YDouble - starMap.Features[j].GetCenter().YDouble); } int x0 = m_TrackedObjects[i].Center.X; int y0 = m_TrackedObjects[i].Center.Y; PSFFit fit = new PSFFit((int)x0, (int)y0); uint[,] data = ((AstroImage)astroImage).GetMeasurableAreaPixels((int)x0, (int)y0); fit.Fit(data); if (fit.IsSolved) { SetTargetFWHM(i, (float)fit.FWHM); } } m_TargetPivotDistancesListX.Clear(); m_TargetPivotDistancesListY.Clear(); return(true); }
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"))); } }